diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 6522e98aac9..a5bde90d527 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -19,13 +19,14 @@ This dev container includes configuration for a development container for workin > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. 4. Due to the size of the repository we strongly recommend cloning it on a Linux filesystem for better bind mount performance. On macOS we recommend using a Docker volume (press F1 and select **Dev Containers: Clone Repository in Container Volume...**) and on Windows we recommend using a WSL folder: + - Make sure you are running a recent WSL version to get X11 and Wayland support. - Use the WSL extension for VS Code to open the cloned folder in WSL. - Press F1 and select **Dev Containers: Reopen in Container**. Next: **[Try it out!](#try-it)** -## Try it! +## Try it To start working with Code - OSS, follow these steps: @@ -50,6 +51,6 @@ Next, let's try debugging. Enjoy! -# Notes +## Notes The container comes with VS Code Insiders installed. To run it from an Integrated Terminal use `VSCODE_IPC_HOOK_CLI= /usr/bin/code-insiders .`. diff --git a/.devcontainer/prebuilt/README.md b/.devcontainer/prebuilt/README.md index 82e731230c0..2ca4619ce13 100644 --- a/.devcontainer/prebuilt/README.md +++ b/.devcontainer/prebuilt/README.md @@ -14,21 +14,21 @@ If you already have VS Code and Docker installed, you can click the badge above 2. **Important**: Docker needs at least **4 Cores and 8 GB of RAM** to run a full build with **9 GB of RAM** being recommended. If you are on macOS, or are using the old Hyper-V engine for Windows, update these values for Docker Desktop by right-clicking on the Docker status bar item and going to **Preferences/Settings > Resources > Advanced**. - > **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar. + > **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar. 3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Dev Containers](https://aka.ms/vscode-remote/download/containers) extension. - ![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/dev-containers-extn.png) + ![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/dev-containers-extn.png) - > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. + > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. 4. Press Ctrl/Cmd + Shift + P or F1 and select **Dev Containers: Clone Repository in Container Volume...**. - > **Tip:** While you can use your local source tree instead, operations like `yarn install` can be slow on macOS or when using the Hyper-V engine on Windows. We recommend the "clone repository in container" approach instead since it uses "named volume" rather than the local filesystem. + > **Tip:** While you can use your local source tree instead, operations like `yarn install` can be slow on macOS or when using the Hyper-V engine on Windows. We recommend the "clone repository in container" approach instead since it uses "named volume" rather than the local filesystem. 5. Type `https://github.com/microsoft/vscode` (or a branch or PR URL) in the input box and press Enter. -6. After the container is running, open a web browser and go to [http://localhost:6080](http://localhost:6080), or use a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) to connect to `localhost:5901` and enter `vscode` as the password. +6. After the container is running, open a web browser and go to [http://localhost:6080](http://localhost:6080), or use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password. Anything you start in VS Code, or the integrated terminal, will appear here. @@ -54,41 +54,42 @@ Next: **[Try it out!](#try-it)** ### Using VS Code with GitHub Codespaces -You may see improved VNC responsiveness when accessing a codespace from VS Code client since you can use a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/). Here's how to do it. +You may see improved VNC responsiveness when accessing a codespace from VS Code client since you can use a [VNC Viewer][def]. Here's how to do it. -1. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the the [GitHub Codespaces extension](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces). +1. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the the [GitHub Codespaces extension](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces). - > **Note:** The GitHub Codespaces extension requires the Visual Studio Code distribution of Code - OSS. + > **Note:** The GitHub Codespaces extension requires the Visual Studio Code distribution of Code - OSS. 2. After the VS Code is up and running, press Ctrl/Cmd + Shift + P or F1, choose **Codespaces: Create New Codespace**, and use the following settings: - - `microsoft/vscode` for the repository. - - Select any branch (e.g. **main**) - you can select a different one later. - - Choose **Standard** (4-core, 8GB) as the size. -4. After you have connected to the codespace, you can use a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) to connect to `localhost:5901` and enter `vscode` as the password. +- `microsoft/vscode` for the repository. +- Select any branch (e.g. **main**) - you can select a different one later. +- Choose **Standard** (4-core, 8GB) as the size. + +3. After you have connected to the codespace, you can use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password. > **Tip:** You may also need change your VNC client's **Picture Quality** setting to **High** to get a full color desktop. -5. Anything you start in VS Code, or the integrated terminal, will appear here. +4. Anything you start in VS Code, or the integrated terminal, will appear here. Next: **[Try it out!](#try-it)** -## Try it! +## Try it This container uses the [Fluxbox](http://fluxbox.org/) window manager to keep things lean. **Right-click on the desktop** to see menu options. It works with GNOME and GTK applications, so other tools can be installed if needed. -> **Note:** You can also set the resolution from the command line by typing `set-resolution`. + > **Note:** You can also set the resolution from the command line by typing `set-resolution`. To start working with Code - OSS, follow these steps: 1. In your local VS Code client, open a terminal (Ctrl/Cmd + Shift + \`) and type the following commands: - ```bash - yarn install - bash scripts/code.sh - ``` + ```bash + yarn install + bash scripts/code.sh + ``` -2. After the build is complete, open a web browser or a [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) to connect to the desktop environment as described in the quick start and enter `vscode` as the password. +2. After the build is complete, open a web browser or a [VNC Viewer][def] to connect to the desktop environment as described in the quick start and enter `vscode` as the password. 3. You should now see Code - OSS! @@ -98,8 +99,10 @@ Next, let's try debugging. 2. Go to your local VS Code client, and use the **Run / Debug** view to launch the **VS Code** configuration. (Typically the default, so you can likely just press F5). - > **Note:** If launching times out, you can increase the value of `timeout` in the "VS Code", "Attach Main Process", "Attach Extension Host", and "Attach to Shared Process" configurations in [launch.json](../../.vscode/launch.json). However, running `scripts/code.sh` first will set up Electron which will usually solve timeout issues. + > **Note:** If launching times out, you can increase the value of `timeout` in the "VS Code", "Attach Main Process", "Attach Extension Host", and "Attach to Shared Process" configurations in [launch.json](../../.vscode/launch.json). However, running `scripts/code.sh` first will set up Electron which will usually solve timeout issues. 3. After a bit, Code - OSS will appear with the debugger attached! Enjoy! + +[def]: https://www.realvnc.com/en/connect/download/viewer/ diff --git a/.vscode/shared.code-snippets b/.vscode/shared.code-snippets index fb3df23dd42..f473425b76f 100644 --- a/.vscode/shared.code-snippets +++ b/.vscode/shared.code-snippets @@ -6,7 +6,7 @@ // Placeholders with the same ids are connected. // Example: "MSFT Copyright Header": { - "scope": "javascript,typescript,css", + "scope": "javascript,typescript,css,rust", "prefix": [ "header", "stub", diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b96e077aa67..f17fa843645 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -104,6 +104,6 @@ If you believe the bot got something wrong, please open a new issue and let us k If you are interested in writing code to fix issues, please see [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) in the wiki. -# Thank You! +## Thank You Your contributions to open source, large or small, make great projects like this possible. Thank you for taking the time to contribute. diff --git a/README.md b/README.md index 0c7c6236c42..61df8fc6bb4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Visual Studio Code - Open Source ("Code - OSS") + [![Feature Requests](https://img.shields.io/github/issues/microsoft/vscode/feature-request.svg)](https://github.com/microsoft/vscode/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc) [![Bugs](https://img.shields.io/github/issues/microsoft/vscode/bug.svg)](https://github.com/microsoft/vscode/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3Abug) [![Gitter](https://img.shields.io/badge/chat-on%20gitter-yellow.svg)](https://gitter.im/Microsoft/vscode) @@ -60,9 +61,10 @@ VS Code includes a set of built-in extensions located in the [extensions](extens This repository includes a Visual Studio Code Dev Containers / GitHub Codespaces development container. -- For [Dev Containers](https://aka.ms/vscode-remote/download/containers), use the **Dev Containers: Clone Repository in Container Volume...** command which creates a Docker volume for better disk I/O on macOS and Windows. - - If you already have VS Code and Docker installed, you can also click [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. This will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use. -- For Codespaces, install the [GitHub Codespaces](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces) extension in VS Code, and use the **Codespaces: Create New Codespace** command. +* For [Dev Containers](https://aka.ms/vscode-remote/download/containers), use the **Dev Containers: Clone Repository in Container Volume...** command which creates a Docker volume for better disk I/O on macOS and Windows. + * If you already have VS Code and Docker installed, you can also click [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. This will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use. + +* For Codespaces, install the [GitHub Codespaces](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces) extension in VS Code, and use the **Codespaces: Create New Codespace** command. Docker / the Codespace should have at least **4 Cores and 6 GB of RAM (8 GB recommended)** to run full build. See the [development container README](.devcontainer/README.md) for more information. diff --git a/SECURITY.md b/SECURITY.md index a050f362c15..4fa5946a867 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -18,13 +18,13 @@ You should receive a response within 24 hours. If for some reason you do not, pl Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue +* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) +* Full paths of source file(s) related to the manifestation of the issue +* The location of the affected source code (tag/branch/commit or direct URL) +* Any special configuration required to reproduce the issue +* Step-by-step instructions to reproduce the issue +* Proof-of-concept or exploit code (if possible) +* Impact of the issue, including how an attacker might exploit the issue This information will help us triage your report more quickly. diff --git a/build/azure-pipelines/common/sign.js b/build/azure-pipelines/common/sign.js index fc522d4ef60..993711adfbf 100644 --- a/build/azure-pipelines/common/sign.js +++ b/build/azure-pipelines/common/sign.js @@ -34,7 +34,7 @@ function getParams(type) { return '[{"keyCode":"CP-230012","operationSetCode":"SigntoolSign","parameters":[{"parameterName":"OpusName","parameterValue":"VS Code"},{"parameterName":"OpusInfo","parameterValue":"https://code.visualstudio.com/"},{"parameterName":"Append","parameterValue":"/as"},{"parameterName":"FileDigest","parameterValue":"/fd \\"SHA256\\""},{"parameterName":"PageHash","parameterValue":"/NPH"},{"parameterName":"TimeStamp","parameterValue":"/tr \\"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\\" /td sha256"}],"toolName":"sign","toolVersion":"1.0"},{"keyCode":"CP-230012","operationSetCode":"SigntoolVerify","parameters":[{"parameterName":"VerifyAll","parameterValue":"/all"}],"toolName":"sign","toolVersion":"1.0"}]'; case 'windows-appx': return '[{"keyCode":"CP-229979","operationSetCode":"SigntoolSign","parameters":[{"parameterName":"OpusName","parameterValue":"VS Code"},{"parameterName":"OpusInfo","parameterValue":"https://code.visualstudio.com/"},{"parameterName":"FileDigest","parameterValue":"/fd \\"SHA256\\""},{"parameterName":"PageHash","parameterValue":"/NPH"},{"parameterName":"TimeStamp","parameterValue":"/tr \\"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\\" /td sha256"}],"toolName":"sign","toolVersion":"1.0"},{"keyCode":"CP-229979","operationSetCode":"SigntoolVerify","parameters":[],"toolName":"sign","toolVersion":"1.0"}]'; - case 'rpm': + case 'pgp': return '[{ "keyCode": "CP-450779-Pgp", "operationSetCode": "LinuxSign", "parameters": [], "toolName": "sign", "toolVersion": "1.0" }]'; case 'darwin-sign': return '[{"keyCode":"CP-401337-Apple","operationSetCode":"MacAppDeveloperSign","parameters":[{"parameterName":"Hardening","parameterValue":"--options=runtime"}],"toolName":"sign","toolVersion":"1.0"}]'; diff --git a/build/azure-pipelines/common/sign.ts b/build/azure-pipelines/common/sign.ts index 955c9389c02..494e89b3e12 100644 --- a/build/azure-pipelines/common/sign.ts +++ b/build/azure-pipelines/common/sign.ts @@ -35,7 +35,7 @@ function getParams(type: string): string { return '[{"keyCode":"CP-230012","operationSetCode":"SigntoolSign","parameters":[{"parameterName":"OpusName","parameterValue":"VS Code"},{"parameterName":"OpusInfo","parameterValue":"https://code.visualstudio.com/"},{"parameterName":"Append","parameterValue":"/as"},{"parameterName":"FileDigest","parameterValue":"/fd \\"SHA256\\""},{"parameterName":"PageHash","parameterValue":"/NPH"},{"parameterName":"TimeStamp","parameterValue":"/tr \\"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\\" /td sha256"}],"toolName":"sign","toolVersion":"1.0"},{"keyCode":"CP-230012","operationSetCode":"SigntoolVerify","parameters":[{"parameterName":"VerifyAll","parameterValue":"/all"}],"toolName":"sign","toolVersion":"1.0"}]'; case 'windows-appx': return '[{"keyCode":"CP-229979","operationSetCode":"SigntoolSign","parameters":[{"parameterName":"OpusName","parameterValue":"VS Code"},{"parameterName":"OpusInfo","parameterValue":"https://code.visualstudio.com/"},{"parameterName":"FileDigest","parameterValue":"/fd \\"SHA256\\""},{"parameterName":"PageHash","parameterValue":"/NPH"},{"parameterName":"TimeStamp","parameterValue":"/tr \\"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\\" /td sha256"}],"toolName":"sign","toolVersion":"1.0"},{"keyCode":"CP-229979","operationSetCode":"SigntoolVerify","parameters":[],"toolName":"sign","toolVersion":"1.0"}]'; - case 'rpm': + case 'pgp': return '[{ "keyCode": "CP-450779-Pgp", "operationSetCode": "LinuxSign", "parameters": [], "toolName": "sign", "toolVersion": "1.0" }]'; case 'darwin-sign': return '[{"keyCode":"CP-401337-Apple","operationSetCode":"MacAppDeveloperSign","parameters":[{"parameterName":"Hardening","parameterValue":"--options=runtime"}],"toolName":"sign","toolVersion":"1.0"}]'; diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 2145e588b1c..919d48eac37 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -312,7 +312,10 @@ steps: continueOnError: true displayName: Download ESRPClient - - script: node build/azure-pipelines/common/sign $(Agent.ToolsDirectory)/esrpclient/*/*/net6.0/esrpcli.dll rpm $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) .build/linux/rpm '*.rpm' + - script: node build/azure-pipelines/common/sign $(Agent.ToolsDirectory)/esrpclient/*/*/net6.0/esrpcli.dll pgp $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) .build/linux/deb '*.deb' + displayName: Codesign deb + + - script: node build/azure-pipelines/common/sign $(Agent.ToolsDirectory)/esrpclient/*/*/net6.0/esrpcli.dll pgp $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) .build/linux/rpm '*.rpm' displayName: Codesign rpm - script: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index a235f55c79e..592157f8d76 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -62,10 +62,6 @@ const serverResources = [ // Performance 'out-build/vs/base/common/performance.js', - // Watcher - 'out-build/vs/platform/files/**/*.exe', - 'out-build/vs/platform/files/**/*.md', - // Process monitor 'out-build/vs/base/node/cpuUsage.sh', 'out-build/vs/base/node/ps.sh', diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 9505e8fe5ca..5f7f5ce4470 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -72,10 +72,9 @@ const vscodeResources = [ 'out-build/vs/workbench/contrib/terminal/browser/media/*.sh', 'out-build/vs/workbench/contrib/terminal/browser/media/*.zsh', 'out-build/vs/workbench/contrib/webview/browser/pre/*.js', + 'out-build/vs/workbench/services/voiceRecognition/electron-sandbox/voiceTranscriptionWorklet.js', 'out-build/vs/**/markdown.css', 'out-build/vs/workbench/contrib/tasks/**/*.json', - 'out-build/vs/platform/files/**/*.exe', - 'out-build/vs/platform/files/**/*.md', '!**/test/**' ]; diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index f83225cc974..303ac03be1e 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -58,6 +58,10 @@ "name": "vs/workbench/contrib/commands", "project": "vscode-workbench" }, + { + "name": "vs/workbench/contrib/mappedEdits", + "project": "vscode-workbench" + }, { "name": "vs/workbench/contrib/comments", "project": "vscode-workbench" @@ -78,6 +82,10 @@ "name": "vs/workbench/services/assignment", "project": "vscode-workbench" }, + { + "name": "vs/workbench/services/voiceRecognition", + "project": "vscode-workbench" + }, { "name": "vs/workbench/contrib/extensions", "project": "vscode-workbench" diff --git a/build/lib/stylelint/vscode-known-variables.json b/build/lib/stylelint/vscode-known-variables.json index 6133fe142b4..a7d22a17b85 100644 --- a/build/lib/stylelint/vscode-known-variables.json +++ b/build/lib/stylelint/vscode-known-variables.json @@ -99,6 +99,7 @@ "--vscode-diffEditor-insertedTextBackground", "--vscode-diffEditor-insertedTextBorder", "--vscode-diffEditor-move-border", + "--vscode-diffEditor-moveActive-border", "--vscode-diffEditor-removedLineBackground", "--vscode-diffEditor-removedTextBackground", "--vscode-diffEditor-removedTextBorder", @@ -545,12 +546,16 @@ "--vscode-statusBar-noFolderBackground", "--vscode-statusBar-noFolderBorder", "--vscode-statusBar-noFolderForeground", - "--vscode-statusBar-offlineBackground", - "--vscode-statusBar-offlineForeground", + "--vscode-statusBarItem-offlineBackground", + "--vscode-statusBarItem-offlineForeground", + "--vscode-statusBarItem-offlineHoverBackground", + "--vscode-statusBarItem-offlineHoverForeground", "--vscode-statusBarItem-activeBackground", "--vscode-statusBarItem-compactHoverBackground", "--vscode-statusBarItem-errorBackground", "--vscode-statusBarItem-errorForeground", + "--vscode-statusBarItem-errorHoverBackground", + "--vscode-statusBarItem-errorHoverForeground", "--vscode-statusBarItem-focusBorder", "--vscode-statusBarItem-hoverBackground", "--vscode-statusBarItem-hoverForeground", @@ -560,8 +565,12 @@ "--vscode-statusBarItem-prominentHoverForeground", "--vscode-statusBarItem-remoteBackground", "--vscode-statusBarItem-remoteForeground", + "--vscode-statusBarItem-remoteHoverBackground", + "--vscode-statusBarItem-remoteHoverForeground", "--vscode-statusBarItem-warningBackground", "--vscode-statusBarItem-warningForeground", + "--vscode-statusBarItem-warningHoverBackground", + "--vscode-statusBarItem-warningHoverForeground", "--vscode-symbolIcon-arrayForeground", "--vscode-symbolIcon-booleanForeground", "--vscode-symbolIcon-classForeground", diff --git a/build/monaco/README-npm.md b/build/monaco/README-npm.md index ca5592e0fe1..ec8eb5a4037 100644 --- a/build/monaco/README-npm.md +++ b/build/monaco/README-npm.md @@ -10,4 +10,5 @@ The Monaco Editor is the code editor that powers [VS Code](https://github.com/mi This npm module contains the core editor functionality, as it comes from the [vscode repository](https://github.com/microsoft/vscode). ## License + [MIT](https://github.com/microsoft/vscode/blob/main/LICENSE.txt) diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index ff4febe8ce6..89c884f18a0 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -107,7 +107,7 @@ export interface ICommandHandler { #include(vs/editor/common/core/editOperation): ISingleEditOperation #include(vs/editor/common/core/wordHelper): IWordAtPosition #includeAll(vs/editor/common/model): IScrollEvent -#include(vs/editor/common/diff/smartLinesDiffComputer): IChange, ICharChange, ILineChange +#include(vs/editor/common/diff/legacyLinesDiffComputer): IChange, ICharChange, ILineChange #include(vs/editor/common/diff/documentDiffProvider): IDocumentDiffProvider, IDocumentDiffProviderOptions, IDocumentDiff #include(vs/editor/common/core/lineRange): LineRange #include(vs/editor/common/diff/linesDiffComputer): LineRangeMapping, RangeMapping, MovedText, SimpleLineRangeMapping diff --git a/cli/Cargo.lock b/cli/Cargo.lock index f7c60045c12..34627da135b 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -983,9 +983,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -2471,7 +2471,7 @@ dependencies = [ [[package]] name = "tunnels" version = "0.1.0" -source = "git+https://github.com/microsoft/dev-tunnels?rev=2621784a9ad72aa39500372391332a14bad581a3#2621784a9ad72aa39500372391332a14bad581a3" +source = "git+https://github.com/microsoft/dev-tunnels?rev=3141ad7be00e18c4231f7c4fb6c11f9219ac49af#3141ad7be00e18c4231f7c4fb6c11f9219ac49af" dependencies = [ "async-trait", "chrono", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index a25bee1f2ce..50fad68a8a4 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -34,10 +34,10 @@ serde_bytes = "0.11.9" chrono = { version = "0.4.26", features = ["serde", "std", "clock"], default-features = false } gethostname = "0.4.3" libc = "0.2.144" -tunnels = { git = "https://github.com/microsoft/dev-tunnels", rev = "2621784a9ad72aa39500372391332a14bad581a3", default-features = false, features = ["connections"] } +tunnels = { git = "https://github.com/microsoft/dev-tunnels", rev = "3141ad7be00e18c4231f7c4fb6c11f9219ac49af", default-features = false, features = ["connections"] } keyring = { version = "2.0.3", default-features = false, features = ["linux-secret-service-rt-tokio-crypto-openssl"] } dialoguer = "0.10.4" -hyper = "0.14.26" +hyper = { version = "0.14.26", features = ["server", "http1", "runtime"] } indicatif = "0.17.4" tempfile = "3.5.0" clap_lex = "0.5.0" diff --git a/cli/src/async_pipe.rs b/cli/src/async_pipe.rs index 6c7c918967a..e9b710c1d68 100644 --- a/cli/src/async_pipe.rs +++ b/cli/src/async_pipe.rs @@ -6,6 +6,8 @@ use crate::{constants::APPLICATION_NAME, util::errors::CodeError}; use async_trait::async_trait; use std::path::{Path, PathBuf}; +use std::pin::Pin; +use std::task::{Context, Poll}; use tokio::io::{AsyncRead, AsyncWrite}; use tokio::net::TcpListener; use uuid::Uuid; @@ -44,7 +46,7 @@ cfg_if::cfg_if! { } else { use tokio::{time::sleep, io::ReadBuf}; use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions, NamedPipeClient, NamedPipeServer}; - use std::{time::Duration, pin::Pin, task::{Context, Poll}, io}; + use std::{time::Duration, io}; use pin_project::pin_project; #[pin_project(project = AsyncPipeProj)] @@ -174,6 +176,57 @@ cfg_if::cfg_if! { } } +impl AsyncPipeListener { + pub fn into_pollable(self) -> PollableAsyncListener { + PollableAsyncListener { + listener: Some(self), + write_fut: tokio_util::sync::ReusableBoxFuture::new(make_accept_fut(None)), + } + } +} + +pub struct PollableAsyncListener { + listener: Option, + write_fut: tokio_util::sync::ReusableBoxFuture< + 'static, + (AsyncPipeListener, Result), + >, +} + +async fn make_accept_fut( + data: Option, +) -> (AsyncPipeListener, Result) { + match data { + Some(mut l) => { + let c = l.accept().await; + (l, c) + } + None => unreachable!("this future should not be pollable in this state"), + } +} + +impl hyper::server::accept::Accept for PollableAsyncListener { + type Conn = AsyncPipe; + type Error = CodeError; + + fn poll_accept( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>> { + if let Some(l) = self.listener.take() { + self.write_fut.set(make_accept_fut(Some(l))) + } + + match self.write_fut.poll(cx) { + Poll::Ready((l, cnx)) => { + self.listener = Some(l); + Poll::Ready(Some(cnx)) + } + Poll::Pending => Poll::Pending, + } + } +} + /// Gets a random name for a pipe/socket on the paltform pub fn get_socket_name() -> PathBuf { cfg_if::cfg_if! { diff --git a/cli/src/bin/code/main.rs b/cli/src/bin/code/main.rs index 8c32ee14d89..b104976b9ab 100644 --- a/cli/src/bin/code/main.rs +++ b/cli/src/bin/code/main.rs @@ -8,7 +8,7 @@ use std::process::Command; use clap::Parser; use cli::{ - commands::{args, tunnels, update, version, CommandContext}, + commands::{args, serve_web, tunnels, update, version, CommandContext}, constants::get_default_user_agent, desktop, log, state::LauncherPaths, @@ -99,6 +99,10 @@ async fn main() -> Result<(), std::convert::Infallible> { tunnels::command_shell(context!(), cs_args).await } + Some(args::Commands::ServeWeb(sw_args)) => { + serve_web::serve_web(context!(), sw_args).await + } + Some(args::Commands::Tunnel(tunnel_args)) => match tunnel_args.subcommand { Some(args::TunnelSubcommand::Prune) => tunnels::prune(context!()).await, Some(args::TunnelSubcommand::Unregister) => tunnels::unregister(context!()).await, diff --git a/cli/src/commands.rs b/cli/src/commands.rs index 754729f2c04..d10a52ad774 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -9,4 +9,5 @@ pub mod args; pub mod tunnels; pub mod update; pub mod version; +pub mod serve_web; pub use context::CommandContext; diff --git a/cli/src/commands/args.rs b/cli/src/commands/args.rs index 9caee09ed64..bfa1c6f2da4 100644 --- a/cli/src/commands/args.rs +++ b/cli/src/commands/args.rs @@ -172,11 +172,45 @@ pub enum Commands { /// Changes the version of the editor you're using. Version(VersionArgs), + /// Runs a local web version of VS Code. + ServeWeb(ServeWebArgs), + /// Runs the control server on process stdin/stdout #[clap(hide = true)] CommandShell(CommandShellArgs), } +#[derive(Args, Debug, Clone)] +pub struct ServeWebArgs { + /// Host to listen on, defaults to 'localhost' + #[clap(long)] + pub host: Option, + // The path to a socket file for the server to listen to. + #[clap(long)] + pub socket_path: Option, + /// Port to listen on. If 0 is passed a random free port is picked. + #[clap(long, default_value_t = 8000)] + pub port: u16, + /// A secret that must be included with all requests. + #[clap(long)] + pub connection_token: Option, + /// Run without a connection token. Only use this if the connection is secured by other means. + #[clap(long)] + pub without_connection_token: bool, + /// If set, the user accepts the server license terms and the server will be started without a user prompt. + #[clap(long)] + pub accept_server_license_terms: bool, + /// Specifies the directory that server data is kept in. + #[clap(long)] + pub server_data_dir: Option, + /// Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code. + #[clap(long)] + pub user_data_dir: Option, + /// Set the root path for extensions. + #[clap(long)] + pub extensions_dir: Option, +} + #[derive(Args, Debug, Clone)] pub struct CommandShellArgs { /// Listen on a socket instead of stdin/stdout. diff --git a/cli/src/commands/serve_web.rs b/cli/src/commands/serve_web.rs new file mode 100644 index 00000000000..4a3af432444 --- /dev/null +++ b/cli/src/commands/serve_web.rs @@ -0,0 +1,629 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +use std::collections::HashMap; +use std::convert::Infallible; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::path::PathBuf; +use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; + +use hyper::service::{make_service_fn, service_fn}; +use hyper::{Body, Request, Response, Server}; +use tokio::io::{AsyncBufReadExt, BufReader}; +use tokio::pin; +use tokio::process::Command; + +use crate::async_pipe::{ + get_socket_name, get_socket_rw_stream, listen_socket_rw_stream, AsyncPipe, +}; +use crate::constants::VSCODE_CLI_QUALITY; +use crate::download_cache::DownloadCache; +use crate::log; +use crate::options::Quality; +use crate::update_service::{ + unzip_downloaded_release, Platform, Release, TargetKind, UpdateService, +}; +use crate::util::errors::AnyError; +use crate::util::http::{self, ReqwestSimpleHttp}; +use crate::util::io::SilentCopyProgress; +use crate::util::sync::{new_barrier, Barrier, BarrierOpener}; +use crate::{ + tunnels::legal, + util::{errors::CodeError, prereqs::PreReqChecker}, +}; + +use super::{args::ServeWebArgs, CommandContext}; + +/// Length of a commit hash, for validation +const COMMIT_HASH_LEN: usize = 40; +/// Number of seconds where, if there's no connections to a VS Code server, +/// the server is shut down. +const SERVER_IDLE_TIMEOUT_SECS: u64 = 60 * 60; +/// Number of seconds in which the server times out when there is a connection +/// (should be large enough to basically never happen) +const SERVER_ACTIVE_TIMEOUT_SECS: u64 = SERVER_IDLE_TIMEOUT_SECS * 24 * 30 * 12; +/// How long to cache the "latest" version we get from the update service. +const RELEASE_CACHE_SECS: u64 = 60 * 60; + +/// Implements the vscode "server of servers". Clients who go to the URI get +/// served the latest version of the VS Code server whenever they load the +/// page. The VS Code server prefixes all assets and connections it loads with +/// its version string, so existing clients can continue to get served even +/// while new clients get new VS Code Server versions. +pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result { + legal::require_consent(&ctx.paths, args.accept_server_license_terms)?; + + let platform: crate::update_service::Platform = PreReqChecker::new().verify().await?; + + if !args.without_connection_token { + // Ensure there's a defined connection token, since if multiple server versions + // are excuted, they will need to have a single shared token. + args.connection_token = Some( + args.connection_token + .clone() + .unwrap_or_else(|| uuid::Uuid::new_v4().to_string()), + ); + } + + let cm = ConnectionManager::new(&ctx, platform, args.clone()); + let make_svc = move || { + let cm = cm.clone(); + let log = cm.log.clone(); + let service = service_fn(move |req| handle(cm.clone(), log.clone(), req)); + async move { Ok::<_, Infallible>(service) } + }; + + let r = if let Some(s) = args.socket_path { + let socket = listen_socket_rw_stream(&PathBuf::from(&s)).await?; + ctx.log.result(format!("Web UI available on {}", s)); + Server::builder(socket.into_pollable()) + .serve(make_service_fn(|_| make_svc())) + .await + } else { + let addr: SocketAddr = match &args.host { + Some(h) => { + SocketAddr::new(h.parse().map_err(CodeError::InvalidHostAddress)?, args.port) + } + None => SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), args.port), + }; + + let mut listening = format!("Web UI available at http://{}", addr); + if let Some(ct) = args.connection_token { + listening.push_str(&format!("?tkn={}", ct)); + } + ctx.log.result(listening); + + Server::bind(&addr) + .serve(make_service_fn(|_| make_svc())) + .await + }; + + r.map_err(CodeError::CouldNotListenOnInterface)?; + + Ok(0) +} + +/// Handler function for an inbound request +async fn handle( + cm: Arc, + log: log::Logger, + req: Request, +) -> Result, Infallible> { + let release = if let Some((r, _)) = get_release_from_path(req.uri().path(), cm.platform) { + r + } else { + match cm.get_latest_release().await { + Ok(r) => r, + Err(e) => { + error!(log, "error getting latest version: {}", e); + return Ok(response::code_err(e)); + } + } + }; + + Ok(match cm.get_connection(release).await { + Ok(rw) => { + if req.headers().contains_key(hyper::header::UPGRADE) { + forward_ws_req_to_server(cm.log.clone(), rw, req).await + } else { + forward_http_req_to_server(rw, req).await + } + } + Err(CodeError::ServerNotYetDownloaded) => response::wait_for_download(), + Err(e) => response::code_err(e), + }) +} + +/// Gets the release info from the VS Code path prefix, which is in the +/// format `/-/...` +fn get_release_from_path(path: &str, platform: Platform) -> Option<(Release, String)> { + if !path.starts_with('/') { + return None; // paths must start with '/' + } + + let path = &path[1..]; + let i = path.find('/').unwrap_or(path.len()); + let quality_commit_sep = path.get(..i).and_then(|p| p.find('-'))?; + + let (quality_commit, remaining) = path.split_at(i); + let (quality, commit) = quality_commit.split_at(quality_commit_sep); + + if !is_commit_hash(commit) { + return None; + } + + Some(( + Release { + // remember to trim off the leading '/' which is now part of th quality + quality: Quality::try_from(quality).ok()?, + commit: commit.to_string(), + platform, + target: TargetKind::Web, + name: "".to_string(), + }, + remaining.to_string(), + )) +} + +/// Proxies the standard HTTP request to the async pipe, returning the piped response +async fn forward_http_req_to_server( + (rw, handle): (AsyncPipe, ConnectionHandle), + req: Request, +) -> Response { + let (mut request_sender, connection) = + match hyper::client::conn::Builder::new().handshake(rw).await { + Ok(r) => r, + Err(e) => return response::connection_err(e), + }; + + tokio::spawn(connection); + + let res = request_sender + .send_request(req) + .await + .unwrap_or_else(response::connection_err); + + // technically, we should buffer the body into memory since it may not be + // read at this point, but because the keepalive time is very large + // there's not going to be responses that take hours to send and x + // cause us to kill the server before the response is sent + drop(handle); + + res +} + +/// Proxies the websocket request to the async pipe +async fn forward_ws_req_to_server( + log: log::Logger, + (rw, handle): (AsyncPipe, ConnectionHandle), + mut req: Request, +) -> Response { + // splicing of client and servers inspired by https://github.com/hyperium/hyper/blob/fece9f7f50431cf9533cfe7106b53a77b48db699/examples/upgrades.rs + let (mut request_sender, connection) = + match hyper::client::conn::Builder::new().handshake(rw).await { + Ok(r) => r, + Err(e) => return response::connection_err(e), + }; + + tokio::spawn(connection); + + let mut proxied_req = Request::builder().uri(req.uri()); + for (k, v) in req.headers() { + proxied_req = proxied_req.header(k, v); + } + + let mut res = request_sender + .send_request(proxied_req.body(Body::empty()).unwrap()) + .await + .unwrap_or_else(response::connection_err); + + let mut proxied_res = Response::new(Body::empty()); + *proxied_res.status_mut() = res.status(); + for (k, v) in res.headers() { + proxied_res.headers_mut().insert(k, v.clone()); + } + + // only start upgrade at this point in case the server decides to deny socket + if res.status() == hyper::StatusCode::SWITCHING_PROTOCOLS { + tokio::spawn(async move { + let (s_req, s_res) = + tokio::join!(hyper::upgrade::on(&mut req), hyper::upgrade::on(&mut res)); + + match (s_req, s_res) { + (Err(e1), Err(e2)) => debug!( + log, + "client ({}) and server ({}) websocket upgrade failed", e1, e2 + ), + (Err(e1), _) => debug!(log, "client ({}) websocket upgrade failed", e1), + (_, Err(e2)) => debug!(log, "server ({}) websocket upgrade failed", e2), + (Ok(mut s_req), Ok(mut s_res)) => { + trace!(log, "websocket upgrade succeeded"); + let r = tokio::io::copy_bidirectional(&mut s_req, &mut s_res).await; + trace!(log, "websocket closed (error: {:?})", r.err()); + } + } + + drop(handle); + }); + } + + proxied_res +} + +/// Returns whether the string looks like a commit hash. +fn is_commit_hash(s: &str) -> bool { + s.len() == COMMIT_HASH_LEN && s.chars().all(|c| c.is_ascii_hexdigit()) +} + +/// Module holding original responses the CLI's server makes. +mod response { + use const_format::concatcp; + + use crate::constants::QUALITYLESS_SERVER_NAME; + + use super::*; + + pub fn connection_err(err: hyper::Error) -> Response { + Response::builder() + .status(503) + .body(Body::from(format!("Error connecting to server: {:?}", err))) + .unwrap() + } + + pub fn code_err(err: CodeError) -> Response { + Response::builder() + .status(500) + .body(Body::from(format!("Error serving request: {}", err))) + .unwrap() + } + + pub fn wait_for_download() -> Response { + Response::builder() + .status(202) + .header("Content-Type", "text/html") // todo: get latest + .body(Body::from(concatcp!("The latest version of the ", QUALITYLESS_SERVER_NAME, " is downloading, please wait a moment...", ))) + .unwrap() + } +} + +/// Handle returned when getting a stream to the server, used to refcount +/// connections to a server so it can be disposed when there are no more clients. +struct ConnectionHandle { + client_counter: Arc>, +} + +impl ConnectionHandle { + pub fn new(client_counter: Arc>) -> Self { + client_counter.send_modify(|v| { + *v += 1; + }); + Self { client_counter } + } +} + +impl Drop for ConnectionHandle { + fn drop(&mut self) { + self.client_counter.send_modify(|v| { + *v -= 1; + }); + } +} + +type StartData = (PathBuf, Arc>); + +/// State stored in the ConnectionManager for each server version. +struct VersionState { + downloaded: bool, + socket_path: Barrier>, +} + +type ConnectionStateMap = Arc>>; + +/// Manages the connections to running web UI instances. Multiple web servers +/// can run concurrently, with routing based on the URL path. +struct ConnectionManager { + pub platform: Platform, + pub log: log::Logger, + args: ServeWebArgs, + /// Cache where servers are stored + cache: DownloadCache, + /// Mapping of (Quality, Commit) to the state each server is in + state: ConnectionStateMap, + /// Update service instance + update_service: UpdateService, + /// Cache of the latest released version, storing the time we checked as well + latest_version: tokio::sync::Mutex>, +} + +fn key_for_release(release: &Release) -> (Quality, String) { + (release.quality, release.commit.clone()) +} + +impl ConnectionManager { + pub fn new(ctx: &CommandContext, platform: Platform, args: ServeWebArgs) -> Arc { + Arc::new(Self { + platform, + args, + log: ctx.log.clone(), + cache: DownloadCache::new(ctx.paths.web_server_storage()), + update_service: UpdateService::new( + ctx.log.clone(), + Arc::new(ReqwestSimpleHttp::with_client(ctx.http.clone())), + ), + state: ConnectionStateMap::default(), + latest_version: tokio::sync::Mutex::default(), + }) + } + + /// Gets a connection to a server version + pub async fn get_connection( + &self, + release: Release, + ) -> Result<(AsyncPipe, ConnectionHandle), CodeError> { + // todo@connor4312: there is likely some performance benefit to + // implementing a 'keepalive' for these connections. + let (path, counter) = self.get_version_data(release).await?; + let handle = ConnectionHandle::new(counter); + let rw = get_socket_rw_stream(&path).await?; + Ok((rw, handle)) + } + + /// Gets the latest release for the CLI quality, caching its result for some + /// time to allow for fast loads. + pub async fn get_latest_release(&self) -> Result { + let mut latest = self.latest_version.lock().await; + let now = Instant::now(); + if let Some((checked_at, release)) = &*latest { + if checked_at.elapsed() < Duration::from_secs(RELEASE_CACHE_SECS) { + return Ok(release.clone()); + } + } + + let quality = VSCODE_CLI_QUALITY + .ok_or_else(|| CodeError::UpdatesNotConfigured("no configured quality")) + .and_then(|q| { + Quality::try_from(q).map_err(|_| CodeError::UpdatesNotConfigured("unknown quality")) + })?; + + let release = self + .update_service + .get_latest_commit(self.platform, TargetKind::Web, quality) + .await + .map_err(|e| CodeError::UpdateCheckFailed(e.to_string())); + + // If the update service is unavailable and we have stale data, use that + if let (Err(e), Some((_, previous))) = (&release, &*latest) { + warning!(self.log, "error getting latest release, using stale: {}", e); + return Ok(previous.clone()); + } + + let release = release?; + debug!(self.log, "refreshed latest release: {}", release); + *latest = Some((now, release.clone())); + + Ok(release) + } + + /// Gets the StartData for the a version of the VS Code server, triggering + /// download/start if necessary. It returns `CodeError::ServerNotYetDownloaded` + /// while the server is downloading, which is used to have a refresh loop on the page. + async fn get_version_data(&self, release: Release) -> Result { + self.get_version_data_inner(release)? + .wait() + .await + .unwrap() + .map_err(CodeError::ServerDownloadError) + } + + fn get_version_data_inner( + &self, + release: Release, + ) -> Result>, CodeError> { + let mut state = self.state.lock().unwrap(); + let key = key_for_release(&release); + if let Some(s) = state.get_mut(&key) { + if !s.downloaded { + if s.socket_path.is_open() { + s.downloaded = true; + } else { + return Err(CodeError::ServerNotYetDownloaded); + } + } + + return Ok(s.socket_path.clone()); + } + + let (socket_path, opener) = new_barrier(); + let state_map_dup = self.state.clone(); + let args = StartArgs { + args: self.args.clone(), + log: self.log.clone(), + opener, + release, + }; + + if let Some(p) = self.cache.exists(&args.release.commit) { + state.insert( + key.clone(), + VersionState { + socket_path: socket_path.clone(), + downloaded: true, + }, + ); + + tokio::spawn(async move { + Self::start_version(args, p).await; + state_map_dup.lock().unwrap().remove(&key); + }); + Ok(socket_path) + } else { + state.insert( + key.clone(), + VersionState { + socket_path, + downloaded: false, + }, + ); + let update_service = self.update_service.clone(); + let cache = self.cache.clone(); + tokio::spawn(async move { + Self::download_version(args, update_service.clone(), cache.clone()).await; + state_map_dup.lock().unwrap().remove(&key); + }); + Err(CodeError::ServerNotYetDownloaded) + } + } + + /// Downloads a server version into the cache and starts it. + async fn download_version( + args: StartArgs, + update_service: UpdateService, + cache: DownloadCache, + ) { + let release_for_fut = args.release.clone(); + let log_for_fut = args.log.clone(); + let dir_fut = cache.create(&args.release.commit, |target_dir| async move { + info!(log_for_fut, "Downloading server {}", release_for_fut.commit); + let tmpdir = tempfile::tempdir().unwrap(); + let response = update_service.get_download_stream(&release_for_fut).await?; + + let name = response.url_path_basename().unwrap(); + let archive_path = tmpdir.path().join(name); + http::download_into_file( + &archive_path, + log_for_fut.get_download_logger("Downloading server:"), + response, + ) + .await?; + unzip_downloaded_release(&archive_path, &target_dir, SilentCopyProgress())?; + Ok(()) + }); + + match dir_fut.await { + Err(e) => args.opener.open(Err(e.to_string())), + Ok(dir) => Self::start_version(args, dir).await, + } + } + + /// Starts a downloaded server that can be found in the given `path`. + async fn start_version(args: StartArgs, path: PathBuf) { + info!(args.log, "Starting server {}", args.release.commit); + + let executable = path + .join("bin") + .join(args.release.quality.server_entrypoint()); + let socket_path = get_socket_name(); + + #[cfg(not(windows))] + let mut cmd = Command::new(&executable); + #[cfg(windows)] + let mut cmd = { + let mut cmd = Command::new("cmd"); + cmd.arg("/Q"); + cmd.arg("/C"); + cmd.arg(&executable); + cmd + }; + + cmd.stdin(std::process::Stdio::null()); + cmd.stderr(std::process::Stdio::piped()); + cmd.stdout(std::process::Stdio::piped()); + cmd.arg("--socket-path"); + cmd.arg(&socket_path); + + // License agreement already checked by the `server_web` function. + cmd.args(["--accept-server-license-terms"]); + + if let Some(a) = &args.args.server_data_dir { + cmd.arg("--server-data-dir"); + cmd.arg(a); + } + if let Some(a) = &args.args.user_data_dir { + cmd.arg("--user-data-dir"); + cmd.arg(a); + } + if let Some(a) = &args.args.extensions_dir { + cmd.arg("--extensions-dir"); + cmd.arg(a); + } + if args.args.without_connection_token { + cmd.arg("--without-connection-token"); + } + if let Some(ct) = &args.args.connection_token { + cmd.arg("--connection-token"); + cmd.arg(ct); + } + + // removed, otherwise the workbench will not be usable when running the CLI from sources. + cmd.env_remove("VSCODE_DEV"); + + let mut child = match cmd.spawn() { + Ok(c) => c, + Err(e) => { + args.opener.open(Err(e.to_string())); + return; + } + }; + + let (mut stdout, mut stderr) = ( + BufReader::new(child.stdout.take().unwrap()).lines(), + BufReader::new(child.stderr.take().unwrap()).lines(), + ); + + // wrapped option to prove that we only use this once in the loop + let (counter_tx, mut counter_rx) = tokio::sync::watch::channel(0); + let mut opener = Some((args.opener, socket_path, Arc::new(counter_tx))); + let commit_prefix = &args.release.commit[..7]; + let kill_timer = tokio::time::sleep(Duration::from_secs(SERVER_IDLE_TIMEOUT_SECS)); + pin!(kill_timer); + + loop { + tokio::select! { + Ok(Some(l)) = stdout.next_line() => { + info!(args.log, "[{} stdout]: {}", commit_prefix, l); + + if l.contains("Server bound to") { + if let Some((opener, path, counter_tx)) = opener.take() { + opener.open(Ok((path, counter_tx))); + } + } + } + Ok(Some(l)) = stderr.next_line() => { + info!(args.log, "[{} stderr]: {}", commit_prefix, l); + }, + n = counter_rx.changed() => { + kill_timer.as_mut().reset(match n { + // err means that the record was dropped + Err(_) => tokio::time::Instant::now(), + Ok(_) => { + if *counter_rx.borrow() == 0 { + tokio::time::Instant::now() + Duration::from_secs(SERVER_IDLE_TIMEOUT_SECS) + } else { + tokio::time::Instant::now() + Duration::from_secs(SERVER_ACTIVE_TIMEOUT_SECS) + } + } + }); + } + _ = &mut kill_timer => { + info!(args.log, "[{} process]: idle timeout reached, ending", commit_prefix); + let _ = child.kill().await; + break; + } + e = child.wait() => { + info!(args.log, "[{} process]: exited: {:?}", commit_prefix, e); + break; + } + } + } + } +} + +struct StartArgs { + log: log::Logger, + args: ServeWebArgs, + release: Release, + opener: BarrierOpener>, +} diff --git a/cli/src/self_update.rs b/cli/src/self_update.rs index 2e95719a3b9..4a878dc5447 100644 --- a/cli/src/self_update.rs +++ b/cli/src/self_update.rs @@ -11,7 +11,7 @@ use crate::{ options::Quality, update_service::{unzip_downloaded_release, Platform, Release, TargetKind, UpdateService}, util::{ - errors::{wrap, AnyError, CorruptDownload, UpdatesNotConfigured}, + errors::{wrap, AnyError, CodeError, CorruptDownload}, http, io::{ReportCopyProgress, SilentCopyProgress}, }, @@ -27,14 +27,16 @@ pub struct SelfUpdate<'a> { impl<'a> SelfUpdate<'a> { pub fn new(update_service: &'a UpdateService) -> Result { let commit = VSCODE_CLI_COMMIT - .ok_or_else(|| UpdatesNotConfigured("unknown build commit".to_string()))?; + .ok_or_else(|| CodeError::UpdatesNotConfigured("unknown build commit"))?; let quality = VSCODE_CLI_QUALITY - .ok_or_else(|| UpdatesNotConfigured("no configured quality".to_string())) - .and_then(|q| Quality::try_from(q).map_err(UpdatesNotConfigured))?; + .ok_or_else(|| CodeError::UpdatesNotConfigured("no configured quality")) + .and_then(|q| { + Quality::try_from(q).map_err(|_| CodeError::UpdatesNotConfigured("unknown quality")) + })?; let platform = Platform::env_default().ok_or_else(|| { - UpdatesNotConfigured("Unknown platform, please report this error".to_string()) + CodeError::UpdatesNotConfigured("Unknown platform, please report this error") })?; Ok(Self { diff --git a/cli/src/state.rs b/cli/src/state.rs index 1b1ff343da5..8815e2df40c 100644 --- a/cli/src/state.rs +++ b/cli/src/state.rs @@ -212,4 +212,10 @@ impl LauncherPaths { ) }) } + + /// Suggested path for web server storage + pub fn web_server_storage(&self) -> PathBuf { + self.root.join("serve-web") + } + } diff --git a/cli/src/tunnels/legal.rs b/cli/src/tunnels/legal.rs index 676ccb7da55..35316af4fde 100644 --- a/cli/src/tunnels/legal.rs +++ b/cli/src/tunnels/legal.rs @@ -2,9 +2,9 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -use crate::constants::{IS_INTERACTIVE_CLI, PRODUCT_NAME_LONG}; +use crate::constants::IS_INTERACTIVE_CLI; use crate::state::{LauncherPaths, PersistedState}; -use crate::util::errors::{AnyError, MissingLegalConsent}; +use crate::util::errors::{AnyError, CodeError}; use crate::util::input::prompt_yn; use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; @@ -46,23 +46,14 @@ pub fn require_consent( if accept_server_license_terms { load.consented = Some(true); } else if !*IS_INTERACTIVE_CLI { - return Err(MissingLegalConsent( - "Run this command again with --accept-server-license-terms to indicate your agreement." - .to_string(), - ) - .into()); + return Err(CodeError::NeedsInteractiveLegalConsent.into()); } else { match prompt_yn(prompt) { Ok(true) => { load.consented = Some(true); } - Ok(false) => { - return Err(AnyError::from(MissingLegalConsent(format!( - "Sorry you cannot use {} CLI without accepting the terms.", - PRODUCT_NAME_LONG - )))) - } - Err(e) => return Err(AnyError::from(MissingLegalConsent(e.to_string()))), + Ok(false) => return Err(CodeError::DeniedLegalConset.into()), + Err(_) => return Err(CodeError::NeedsInteractiveLegalConsent.into()), } } diff --git a/cli/src/update_service.rs b/cli/src/update_service.rs index b03d8ea5963..d218e4a1333 100644 --- a/cli/src/update_service.rs +++ b/cli/src/update_service.rs @@ -11,7 +11,7 @@ use crate::{ constants::VSCODE_CLI_UPDATE_ENDPOINT, debug, log, options, spanf, util::{ - errors::{AnyError, CodeError, UpdatesNotConfigured, WrappedError}, + errors::{AnyError, CodeError, WrappedError}, http::{BoxedHttp, SimpleResponse}, io::ReportCopyProgress, tar, zipper, @@ -19,6 +19,7 @@ use crate::{ }; /// Implementation of the VS Code Update service for use in the CLI. +#[derive(Clone)] pub struct UpdateService { client: BoxedHttp, log: log::Logger, @@ -54,6 +55,10 @@ fn quality_download_segment(quality: options::Quality) -> &'static str { } } +fn get_update_endpoint() -> Result<&'static str, CodeError> { + VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(|| CodeError::UpdatesNotConfigured("no service url")) +} + impl UpdateService { pub fn new(log: log::Logger, http: BoxedHttp) -> Self { UpdateService { client: http, log } @@ -66,8 +71,7 @@ impl UpdateService { quality: options::Quality, version: &str, ) -> Result { - let update_endpoint = - VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(UpdatesNotConfigured::no_url)?; + let update_endpoint = get_update_endpoint()?; let download_segment = target .download_segment(platform) .ok_or_else(|| CodeError::UnsupportedPlatform(platform.to_string()))?; @@ -108,8 +112,7 @@ impl UpdateService { target: TargetKind, quality: options::Quality, ) -> Result { - let update_endpoint = - VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(UpdatesNotConfigured::no_url)?; + let update_endpoint = get_update_endpoint()?; let download_segment = target .download_segment(platform) .ok_or_else(|| CodeError::UnsupportedPlatform(platform.to_string()))?; @@ -144,8 +147,7 @@ impl UpdateService { /// Gets the download stream for the release. pub async fn get_download_stream(&self, release: &Release) -> Result { - let update_endpoint = - VSCODE_CLI_UPDATE_ENDPOINT.ok_or_else(UpdatesNotConfigured::no_url)?; + let update_endpoint = get_update_endpoint()?; let download_segment = release .target .download_segment(release.platform) diff --git a/cli/src/util/errors.rs b/cli/src/util/errors.rs index c82e14acc8b..38d9b36f54b 100644 --- a/cli/src/util/errors.rs +++ b/cli/src/util/errors.rs @@ -108,16 +108,6 @@ impl StatusError { } } -// When the user has not consented to the licensing terms in using the Launcher -#[derive(Debug)] -pub struct MissingLegalConsent(pub String); - -impl std::fmt::Display for MissingLegalConsent { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - // When the provided connection token doesn't match the one used to set up the original VS Code Server // This is most likely due to a new user joining. #[derive(Debug)] @@ -313,20 +303,6 @@ impl std::fmt::Display for ServerHasClosed { } } -#[derive(Debug)] -pub struct UpdatesNotConfigured(pub String); - -impl UpdatesNotConfigured { - pub fn no_url() -> Self { - UpdatesNotConfigured("no service url".to_owned()) - } -} - -impl std::fmt::Display for UpdatesNotConfigured { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "Update service is not configured: {}", self.0) - } -} #[derive(Debug)] pub struct ServiceAlreadyRegistered(); @@ -517,10 +493,28 @@ pub enum CodeError { KeyringTimeout, #[error("no host is connected to the tunnel relay")] NoTunnelEndpoint, + #[error("could not parse `host`: {0}")] + InvalidHostAddress(std::net::AddrParseError), + #[error("could not start server on the given host/port: {0}")] + CouldNotListenOnInterface(hyper::Error), + #[error( + "Run this command again with --accept-server-license-terms to indicate your agreement." + )] + NeedsInteractiveLegalConsent, + #[error("Sorry, you cannot use this CLI without accepting the terms.")] + DeniedLegalConset, + #[error("The server is not yet downloaded, try again shortly.")] + ServerNotYetDownloaded, + #[error("An error was encountered downloading the server, please retry: {0}")] + ServerDownloadError(String), + #[error("Updates are are not available: {0}")] + UpdatesNotConfigured(&'static str), + // todo: can be specialized when update service is moved to CodeErrors + #[error("Could not check for update: {0}")] + UpdateCheckFailed(String), } makeAnyError!( - MissingLegalConsent, MismatchConnectionToken, DevTunnelError, StatusError, @@ -543,7 +537,6 @@ makeAnyError!( ServerHasClosed, ServiceAlreadyRegistered, WindowsNeedsElevation, - UpdatesNotConfigured, CorruptDownload, MissingHomeDirectory, OAuthError, diff --git a/cli/src/util/sync.rs b/cli/src/util/sync.rs index 8b653cd2d53..67c777b75ed 100644 --- a/cli/src/util/sync.rs +++ b/cli/src/util/sync.rs @@ -63,7 +63,7 @@ impl BarrierOpener { /// and is thereafter permanently closed. It can contain a value. pub fn new_barrier() -> (Barrier, BarrierOpener) where - T: Copy, + T: Clone, { let (closed_tx, closed_rx) = watch::channel(None); (Barrier(closed_rx), BarrierOpener(Arc::new(closed_tx))) diff --git a/extensions/git-base/README.md b/extensions/git-base/README.md index ff5bcc321c7..d6f0b7c128b 100644 --- a/extensions/git-base/README.md +++ b/extensions/git-base/README.md @@ -14,7 +14,8 @@ The Git extension exposes an API, reachable by any other extension. 2. Include `git-base.d.ts` in your extension's compilation. 3. Get a hold of the API with the following snippet: - ```ts - const gitBaseExtension = vscode.extensions.getExtension('vscode.git-base').exports; - const git = gitBaseExtension.getAPI(1); - ``` + ```ts + const gitBaseExtension = vscode.extensions.getExtension('vscode.git-base').exports; + const git = gitBaseExtension.getAPI(1); + + ``` diff --git a/extensions/git/README.md b/extensions/git/README.md index a20f3207534..2a6678de933 100644 --- a/extensions/git/README.md +++ b/extensions/git/README.md @@ -14,7 +14,7 @@ The Git extension exposes an API, reachable by any other extension. 2. Include `git.d.ts` in your extension's compilation. 3. Get a hold of the API with the following snippet: - ```ts - const gitExtension = vscode.extensions.getExtension('vscode.git').exports; - const git = gitExtension.getAPI(1); - ``` \ No newline at end of file + ```ts + const gitExtension = vscode.extensions.getExtension('vscode.git').exports; + const git = gitExtension.getAPI(1); + ``` diff --git a/extensions/git/package.json b/extensions/git/package.json index d7d241e0aab..105491916ca 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -3005,7 +3005,7 @@ }, "dependencies": { "@joaomoreno/unique-names-generator": "^5.1.0", - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "@vscode/iconv-lite-umd": "0.7.0", "byline": "^5.0.0", "file-type": "16.5.4", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index af40853e27e..704a4fa47fd 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1783,12 +1783,17 @@ export class CommandCenter { const message = documents.length === 1 ? l10n.t('The following file has unsaved changes which won\'t be included in the commit if you proceed: {0}.\n\nWould you like to save it before committing?', path.basename(documents[0].uri.fsPath)) : l10n.t('There are {0} unsaved files.\n\nWould you like to save them before committing?', documents.length); - const saveAndCommit = l10n.t('Save All & Commit'); - const commit = l10n.t('Commit Staged Changes'); + const saveAndCommit = l10n.t('Save All & Commit Changes'); + const commit = l10n.t('Commit Changes'); const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit); if (pick === saveAndCommit) { await Promise.all(documents.map(d => d.save())); + + // After saving the dirty documents, if there are any documents that are part of the + // index group we have to add them back in order for the saved changes to be committed + documents = documents + .filter(d => repository.indexGroup.resourceStates.some(s => pathEquals(s.resourceUri.fsPath, d.uri.fsPath))); await repository.add(documents.map(d => d.uri)); noStagedChanges = repository.indexGroup.resourceStates.length === 0; diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index 6be6a6b4e43..bb3a09d947c 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,71 +80,105 @@ dependencies: tslib "^2.2.0" +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== + dependencies: + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + "@joaomoreno/unique-names-generator@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@joaomoreno/unique-names-generator/-/unique-names-generator-5.1.0.tgz#d577d425aed794c44c0e8863cddd5dea349f74f3" integrity sha512-KEVThTpUIKPb7dBKJ9mJ3WYnD1mJZZsEinCSp9CVEPlWbDagurFv1RKRjvvujrLfJzsGc0HkBHS9W8Bughao4A== -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -131,39 +190,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tokenizer/token@^0.3.0": version "0.3.0" @@ -202,26 +296,41 @@ resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003" integrity sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + "@types/which@3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/which/-/which-3.0.0.tgz#849afdd9fdcb0b67339b9cfc80fa6ea4e0253fc5" integrity sha512-ASCxdbsrwNfSMXALlC3Decif9rwDMu+80KGp5zI2RLRotfMsTv7fHL8W8VDp24wymzDyIFudhUeSCugrgRFfHQ== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" "@vscode/iconv-lite-umd@0.7.0": version "0.7.0" resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48" integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg== +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -229,22 +338,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -271,6 +382,11 @@ byline@^5.0.0: resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -295,7 +411,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -307,17 +423,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -344,6 +460,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -366,11 +494,28 @@ ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + inherits@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -381,6 +526,13 @@ jschardet@3.0.0: resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -393,11 +545,21 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + peek-readable@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" @@ -424,6 +586,24 @@ readable-web-to-node-stream@^3.0.0: dependencies: readable-stream "^3.6.0" +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -434,7 +614,14 @@ semver@^5.3.0, semver@^5.4.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -459,6 +646,11 @@ strtok3@^6.2.4: "@tokenizer/token" "^0.3.0" peek-readable "^4.1.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + token-types@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.0.tgz#b66bc3d67420c6873222a424eee64a744f4c2f13" @@ -493,3 +685,8 @@ which@3.0.1: integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== dependencies: isexe "^2.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/github-authentication/package.json b/extensions/github-authentication/package.json index f5e3c95e6dd..4855716e08e 100644 --- a/extensions/github-authentication/package.json +++ b/extensions/github-authentication/package.json @@ -60,7 +60,7 @@ }, "dependencies": { "node-fetch": "2.6.7", - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "vscode-tas-client": "^0.1.47" }, "devDependencies": { diff --git a/extensions/github-authentication/yarn.lock b/extensions/github-authentication/yarn.lock index 858f60ddaff..da5f5631576 100644 --- a/extensions/github-authentication/yarn.lock +++ b/extensions/github-authentication/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,39 +185,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" @@ -183,15 +277,30 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -200,22 +309,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -244,6 +355,11 @@ axios@^0.26.1: dependencies: follow-redirects "^1.14.8" +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -268,7 +384,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -280,17 +396,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -322,6 +438,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -339,6 +467,30 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" @@ -351,6 +503,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.44.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -363,12 +520,42 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -378,6 +565,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tas-client@0.1.45: version "0.1.45" resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.45.tgz#83bbf73f8458a0f527f9a389f7e1c37f63a64a76" @@ -419,3 +611,8 @@ whatwg-url@^5.0.0: dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/github/package.json b/extensions/github/package.json index ec02df2ec85..afbb7253f7f 100644 --- a/extensions/github/package.json +++ b/extensions/github/package.json @@ -183,7 +183,7 @@ "@octokit/graphql-schema": "14.4.0", "@octokit/rest": "19.0.4", "tunnel": "^0.0.6", - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "devDependencies": { "@types/node": "18.x" diff --git a/extensions/github/yarn.lock b/extensions/github/yarn.lock index f562d36c972..ab4275a38b9 100644 --- a/extensions/github/yarn.lock +++ b/extensions/github/yarn.lock @@ -17,32 +17,50 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.11.0.tgz#fc0e8f56caac08a9d4ac91c07a6c5a360ea31c82" - integrity sha512-nB4KXl6qAyJmBVLWA7SakT4tzpYZTCk4pvRBeI+Ye0WYSOrlTqlMhc4MSS/8atD3ufeYWdkN380LLoXlUUzThw== +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" + integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== dependencies: "@azure/abort-controller" "^1.0.0" "@azure/core-auth" "^1.4.0" "@azure/core-tracing" "^1.0.1" - "@azure/core-util" "^1.3.0" + "@azure/core-util" "^1.0.0" "@azure/logger" "^1.0.0" form-data "^4.0.0" http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0" tslib "^2.2.0" + uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" -"@azure/core-util@^1.3.0": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.3.2.tgz#3f8cfda1e87fac0ce84f8c1a42fcd6d2a986632d" - integrity sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ== +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + +"@azure/core-util@^1.0.0", "@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== dependencies: "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" @@ -54,66 +72,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.12", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.12" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.12.tgz#f5f56626bd0385a357fae6f730eea347be02ce64" - integrity sha512-cHpxZZ+pbtOyqFMFB/c1COpaOE3VPFU6phYVHVvOA9DvoeMZfI/Xrxaj7B/vfq4MmkiE7nOAPhv5ZRn+i6OogA== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.14" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.12" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.12.tgz#60f6ff48ba48c88880c1bceb376711cdd34f87ea" - integrity sha512-vhIVYg4FzBfwtM8tBqDUq3xU+cFu6SQ7biuJHtQpd5PVjDgvAovVOMRF1khsZE/k2rttRRBpmBgNEqG3Ptoysw== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.12" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.14": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.14.tgz#daabd8a418d9b70a318c0126518e000dd6f67fa0" - integrity sha512-z1AG6lqV3ACtdUXnT0Ubj48BAZ8K01sFsYdWgroSXpw2lYUlXAzdx3tK8zpaqEXSEhok8CWTZki7aunHzkZHSw== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== + dependencies: + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== + dependencies: + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" + +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: - "@microsoft/applicationinsights-common" "2.8.14" - "@microsoft/applicationinsights-core-js" "2.8.14" "@microsoft/applicationinsights-shims" "2.0.2" "@microsoft/dynamicproto-js" "^1.1.9" -"@microsoft/applicationinsights-common@2.8.14": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.14.tgz#7d082295f862a189c80aa98b3f4aaec926546051" - integrity sha512-1xjJvyyRN7tb5ahOTkEGGsvw8zvqmS714y3+1m7ooKHFfxO0wX+eYOU/kke74BCY0nJ/pocB/6hjWZOgwvbHig== +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.14" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.9" - -"@microsoft/applicationinsights-core-js@2.8.14": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.14.tgz#80e3d9d42102e741494726d78ac923098bad7132" - integrity sha512-XacWUHdjSHMUwdngMZBp0oiCBifD56CQK2Egu2PiBiF4xu2AO2yNCtWSXsQX2g5OkEhVwaEjfa/aH3WbpYxB1g== - dependencies: - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.9" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.14" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.14.tgz#8c43bcad2e12f25eb00a9aaad0182371507b21b9" - integrity sha512-R2mzg5NmCtLloq3lPQFmnlvjrPIqm3mWNYVy5ELJuOPZ7S6j9y7s4yHOzfXynmOziiQd+0q1j9pTth9aP9vo0g== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.14" - "@microsoft/applicationinsights-common" "2.8.14" - "@microsoft/applicationinsights-core-js" "2.8.14" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.9" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -125,6 +177,25 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== + dependencies: + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== + dependencies: + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" + +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + "@octokit/auth-token@^3.0.0": version "3.0.1" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.1.tgz#88bc2baf5d706cb258474e722a720a8365dff2ec" @@ -255,39 +326,50 @@ dependencies: "@octokit/openapi-types" "^17.1.0" -"@opentelemetry/api@^1.0.4": +"@opentelemetry/api@^1.4.1": version "1.4.1" resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== -"@opentelemetry/core@1.14.0", "@opentelemetry/core@^1.0.1": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.14.0.tgz#64e876b29cb736c984d54164cd47433f513eafd3" - integrity sha512-MnMZ+sxsnlzloeuXL2nm5QcNczt/iO82UOeQQDHhV83F2fP3sgntW2evvtoxJki0MBLxEsh5ADD7PR/Hn5uzjw== +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/semantic-conventions" "1.14.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/resources@1.14.0": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.14.0.tgz#d6b0a4e71c2706d33c8c6ec7a7b8fea6ad27ddea" - integrity sha512-qRfWIgBxxl3z47E036Aey0Lj2ZjlFb27Q7Xnj1y1z/P293RXJZGLtcfn/w8JF7v1Q2hs3SDGxz7Wb9Dko1YUQA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== dependencies: - "@opentelemetry/core" "1.14.0" - "@opentelemetry/semantic-conventions" "1.14.0" + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.14.0.tgz#831af08f002228a11e577ff860eb6059c8b80fb7" - integrity sha512-NzRGt3PS+HPKfQYMb6Iy8YYc5OKA73qDwci/6ujOIvyW9vcqBJSWbjZ8FeLEAmuatUB5WrRhEKu9b0sIiIYTrQ== +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== dependencies: - "@opentelemetry/core" "1.14.0" - "@opentelemetry/resources" "1.14.0" - "@opentelemetry/semantic-conventions" "1.14.0" + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.14.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.14.0.tgz#6a729b7f372ce30f77a3f217c09bc216f863fccb" - integrity sha512-rJfCY8rCWz3cb4KI6pEofnytvMPuj3YLQwoscCCYZ5DkdiPjo15IQ0US7+mjcWy9H3fcZIzf2pbJZ7ck/h4tug== +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" @@ -299,15 +381,30 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -316,22 +413,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -358,6 +457,11 @@ before-after-hook@^2.2.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -382,7 +486,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -399,17 +503,17 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -427,6 +531,11 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + graphql-tag@^2.10.3: version "2.12.6" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" @@ -439,6 +548,13 @@ graphql@^16.0.0: resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -456,11 +572,35 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + is-plain-object@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -473,6 +613,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -492,12 +637,42 @@ once@^1.4.0: dependencies: wrappy "1" +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -507,6 +682,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -532,6 +712,11 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -549,3 +734,8 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/html-language-features/.vscode/settings.json b/extensions/html-language-features/.vscode/settings.json index 569ac10cf8f..17b02728e8c 100644 --- a/extensions/html-language-features/.vscode/settings.json +++ b/extensions/html-language-features/.vscode/settings.json @@ -1,6 +1,6 @@ { "editor.insertSpaces": false, "prettier.semi": true, - "prettier.singleQuote": true, - "prettier.printWidth": 120, -} \ No newline at end of file + "prettier.singleQuote": true, + "prettier.printWidth": 120 +} diff --git a/extensions/javascript/syntaxes/Readme.md b/extensions/javascript/syntaxes/Readme.md index bc29199fd73..b7db3a6a4c9 100644 --- a/extensions/javascript/syntaxes/Readme.md +++ b/extensions/javascript/syntaxes/Readme.md @@ -1,10 +1,12 @@ The file `JavaScript.tmLanguage.json` is derived from [TypeScriptReact.tmLanguage](https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScriptReact.tmLanguage). To update to the latest version: + - `cd extensions/typescript` and run `npm run update-grammars` - don't forget to run the integration tests at `./scripts/test-integration.sh` The script does the following changes: + - fileTypes .tsx -> .js & .jsx - scopeName scope.tsx -> scope.js - update all rule names .tsx -> .js diff --git a/extensions/json-language-features/README.md b/extensions/json-language-features/README.md index 2ff5e6e57d3..3de3d11081a 100644 --- a/extensions/json-language-features/README.md +++ b/extensions/json-language-features/README.md @@ -4,4 +4,4 @@ ## Features -See [JSON in Visual Studio Code](https://code.visualstudio.com/docs/languages/json) to learn about the features of this extension. \ No newline at end of file +See [JSON in Visual Studio Code](https://code.visualstudio.com/docs/languages/json) to learn about the features of this extension. diff --git a/extensions/json-language-features/server/README.md b/extensions/json-language-features/server/README.md index e9875ba5977..10956439e32 100644 --- a/extensions/json-language-features/server/README.md +++ b/extensions/json-language-features/server/README.md @@ -11,6 +11,7 @@ The JSON Language server provides language-specific smarts for editing, validati ### Server capabilities The JSON language server supports requests on documents of language id `json` and `jsonc`. + - `json` documents are parsed and validated following the [JSON specification](https://tools.ietf.org/html/rfc7159). - `jsonc` documents additionally accept single line (`//`) and multi-line comments (`/* ... */`). JSONC is a VSCode specific file format, intended for VSCode configuration files, without any aspirations to define a new common file format. @@ -25,12 +26,12 @@ The server implements the following capabilities of the language server protocol - Semantic Selection for semantic selection for one or multiple cursor positions. - [Goto Definition](https://microsoft.github.io/language-server-protocol/specification#textDocument_definition) for $ref references in JSON schemas - [Diagnostics (Validation)](https://microsoft.github.io/language-server-protocol/specification#textDocument_publishDiagnostics) are pushed for all open documents - - syntax errors - - structural validation based on the document's [JSON schema](http://json-schema.org/). + - syntax errors + - structural validation based on the document's [JSON schema](http://json-schema.org/). In order to load JSON schemas, the JSON server uses NodeJS `http` and `fs` modules. For all other features, the JSON server only relies on the documents and settings provided by the client through the LSP. -### Client requirements: +### Client requirements The JSON language server expects the client to only send requests and notifications for documents of language id `json` and `jsonc`. @@ -56,8 +57,8 @@ Clients may send a `workspace/didChangeConfiguration` notification to notify the The server supports the following settings: - http - - `proxy`: The URL of the proxy server to use when fetching schema. When undefined or empty, no proxy is used. - - `proxyStrictSSL`: Whether the proxy server certificate should be verified against the list of supplied CAs. + - `proxy`: The URL of the proxy server to use when fetching schema. When undefined or empty, no proxy is used. + - `proxyStrictSSL`: Whether the proxy server certificate should be verified against the list of supplied CAs. - json - `format` @@ -72,6 +73,7 @@ The server supports the following settings: - `resultLimit`: The max number of color decorators and outline symbols to be computed (for performance reasons) - `jsonFoldingLimit`: The max number of folding ranges to be computed for json documents (for performance reasons) - `jsoncFoldingLimit`: The max number of folding ranges to be computed for jsonc documents (for performance reasons) + ```json { "http": { @@ -103,6 +105,7 @@ The server supports the following settings: [JSON schemas](http://json-schema.org/) are essential for code assist, hovers, color decorators to work and are required for structural validation. To find the schema for a given JSON document, the server uses the following mechanisms: + - JSON documents can define the schema URL using a `$schema` property - The settings define a schema association based on the documents URL. Settings can either associate a schema URL to a file or path pattern, and they can directly provide a schema. - Additionally, schema associations can also be provided by a custom 'schemaAssociations' configuration call. @@ -115,9 +118,9 @@ The `initializationOptions.handledSchemaProtocols` initialization option defines ```ts let clientOptions: LanguageClientOptions = { - initializationOptions: { - handledSchemaProtocols: ['file'] // language server should only try to load file URLs - } + initializationOptions: { + handledSchemaProtocols: ['file'] // language server should only try to load file URLs + } ... } ``` @@ -132,6 +135,7 @@ If `handledSchemaProtocols` is not set, the JSON language server will load the f Requests for schemas with URLs not handled by the server are forwarded to the client through an LSP request. This request is a JSON language server-specific, non-standardized, extension to the LSP. Request: + - method: 'vscode/content' - params: `string` - The schema URL to request. - response: `string` - The content of the schema with the given URL @@ -146,6 +150,7 @@ The server will, as a response, clear the schema content from the cache and relo In addition to the settings, schemas associations can also be provided through a notification from the client to the server. This notification is a JSON language server-specific, non-standardized, extension to the LSP. Notification: + - method: 'json/schemaAssociations' - params: `ISchemaAssociations` or `ISchemaAssociation[]` defined as follows @@ -183,11 +188,14 @@ interface ISchemaAssociation { } ``` + `ISchemaAssociations` - - keys: a file names or file path (separated by `/`). `*` can be used as a wildcard. - - values: An array of schema URLs + +- keys: a file names or file path (separated by `/`). `*` can be used as a wildcard. +- values: An array of schema URLs Notification: + - method: 'json/schemaContent' - params: `string` the URL of the schema that has changed. @@ -226,6 +234,7 @@ The source code of the JSON language server can be found in the [VSCode reposito File issues and pull requests in the [VSCode GitHub Issues](https://github.com/microsoft/vscode/issues). See the document [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) on how to build and run from source. Most of the functionality of the server is located in libraries: + - [jsonc-parser](https://github.com/microsoft/node-jsonc-parser) contains the JSON parser and scanner. - [vscode-json-languageservice](https://github.com/microsoft/vscode-json-languageservice) contains the implementation of all features as a re-usable library. - [vscode-languageserver-node](https://github.com/microsoft/vscode-languageserver-node) contains the implementation of language server for NodeJS. diff --git a/extensions/markdown-language-features/README.md b/extensions/markdown-language-features/README.md index e80e9e886bb..2052521da84 100644 --- a/extensions/markdown-language-features/README.md +++ b/extensions/markdown-language-features/README.md @@ -4,4 +4,4 @@ ## Features -See [Markdown in Visual Studio Code](https://code.visualstudio.com/docs/languages/markdown) to learn about the features of this extension. \ No newline at end of file +See [Markdown in Visual Studio Code](https://code.visualstudio.com/docs/languages/markdown) to learn about the features of this extension. diff --git a/extensions/markdown-language-features/media/markdown.css b/extensions/markdown-language-features/media/markdown.css index 939eafc442b..dba6176ffda 100644 --- a/extensions/markdown-language-features/media/markdown.css +++ b/extensions/markdown-language-features/media/markdown.css @@ -106,10 +106,10 @@ sup { line-height: 0; } -ul ul, -ul ol, -ol ul, -ol ol { +ul ul:first-child, +ul ol:first-child, +ol ul:first-child, +ol ol:first-child { margin-bottom: 0; } @@ -138,6 +138,10 @@ p { margin-bottom: 16px; } +li p { + margin-bottom: 0.7em; +} + ul, ol { margin-bottom: 0.7em; diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 60e80b169d3..9743845b8d9 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -123,7 +123,8 @@ "commands": [ { "command": "_markdown.copyImage", - "title": "%markdown.copyImage.title%" + "title": "%markdown.copyImage.title%", + "category": "Markdown" }, { "command": "markdown.showPreview", @@ -244,6 +245,10 @@ } ], "commandPalette": [ + { + "command": "_markdown.copyImage", + "when": "false" + }, { "command": "markdown.showPreview", "when": "editorLangId == markdown && !notebookEditorFocused", @@ -721,7 +726,7 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "dompurify": "^3.0.5", "highlight.js": "^11.8.0", "markdown-it": "^12.3.2", diff --git a/extensions/markdown-language-features/server/README.md b/extensions/markdown-language-features/server/README.md index 1fd38302195..4114d2698bf 100644 --- a/extensions/markdown-language-features/server/README.md +++ b/extensions/markdown-language-features/server/README.md @@ -6,7 +6,6 @@ The Markdown language server powers VS Code's built-in markdown support, providi This server uses the [Markdown Language Service](https://github.com/microsoft/vscode-markdown-languageservice) to implement almost all of the language features. You can use that library if you need a library for working with Markdown instead of a full language server. - ## Server capabilities - [Completions](https://microsoft.github.io/language-server-protocol/specification#textDocument_completion) for Markdown links. @@ -31,14 +30,13 @@ This server uses the [Markdown Language Service](https://github.com/microsoft/vs - [Code Actions](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_codeAction) - - Organize link definitions source action. - - Extract link to definition refactoring. + - Organize link definitions source action. + - Extract link to definition refactoring. - Updating links when a file is moved / renamed. Uses a custom `markdown/getEditForFileRenames` message. - [Pull diagnostics (validation)](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_pullDiagnostics) for links. - ## Client requirements ### Initialization options @@ -53,27 +51,27 @@ Clients may send a `workspace/didChangeConfiguration` notification to notify the The server supports the following settings: - `markdown` - - `suggest` - - `paths` - - `enabled` — Enable/disable path suggestions. + - `suggest` + - `paths` + - `enabled` — Enable/disable path suggestions. - - `occurrencesHighlight` - - `enabled` — Enable/disable highlighting of link occurrences. + - `occurrencesHighlight` + - `enabled` — Enable/disable highlighting of link occurrences. - - `validate` - - `enabled` — Enable/disable all validation. - - `referenceLinks` - - `enabled` — Enable/disable validation of reference links: `[text][ref]` - - `fragmentLinks` - - `enabled` — Enable/disable validation of links to fragments in the current files: `[text](#head)` - - `fileLinks` - - `enabled` — Enable/disable validation of links to file in the workspace. - - `markdownFragmentLinks` — Enable/disable validation of links to headers in other Markdown files. Use `inherit` to inherit the `fragmentLinks` setting. - - `ignoredLinks` — Array of glob patterns for files that should not be validated. - - `unusedLinkDefinitions` - - `enabled` — Enable/disable validation of unused link definitions. - - `duplicateLinkDefinitions` - - `enabled` — Enable/disable validation of duplicated link definitions. + - `validate` + - `enabled` — Enable/disable all validation. + - `referenceLinks` + - `enabled` — Enable/disable validation of reference links: `[text][ref]` + - `fragmentLinks` + - `enabled` — Enable/disable validation of links to fragments in the current files: `[text](#head)` + - `fileLinks` + - `enabled` — Enable/disable validation of links to file in the workspace. + - `markdownFragmentLinks` — Enable/disable validation of links to headers in other Markdown files. Use `inherit` to inherit the `fragmentLinks` setting. + - `ignoredLinks` — Array of glob patterns for files that should not be validated. + - `unusedLinkDefinitions` + - `enabled` — Enable/disable validation of unused link definitions. + - `duplicateLinkDefinitions` + - `enabled` — Enable/disable validation of duplicated link definitions. ### Custom requests @@ -109,7 +107,6 @@ Delete a previously created file watcher. Get a list of all markdown files in the workspace. - ## Contribute The source code of the Markdown language server can be found in the [VSCode repository](https://github.com/microsoft/vscode) at [extensions/markdown-language-features/server](https://github.com/microsoft/vscode/tree/master/extensions/markdown-language-features/server). @@ -132,4 +129,3 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the [MIT](https://github.com/microsoft/vscode/blob/master/LICENSE.txt) License. - diff --git a/extensions/markdown-language-features/yarn.lock b/extensions/markdown-language-features/yarn.lock index 8a47f870e93..36b5aebfed8 100644 --- a/extensions/markdown-language-features/yarn.lock +++ b/extensions/markdown-language-features/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,39 +185,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" @@ -207,6 +301,11 @@ resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003" integrity sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + "@types/trusted-types@*": version "2.0.2" resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" @@ -222,21 +321,31 @@ resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.0.tgz#bad5194d45ae8d03afc1c0f67f71ff5e7a243bbf" integrity sha512-x3Cb/SMa1IwRHfSvKaZDZOTh4cNoG505c3NjTqGlMC082m++x/ETUmtYniDsw6SSmYzZXO8KBNhYxR0+VqymqA== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" "@vscode/l10n@^0.0.10": version "0.0.10" resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.10.tgz#9c513107c690c0dd16e3ec61e453743de15ebdb0" integrity sha512-E1OCmDcDWa0Ya7vtSjp/XfHFGqYJfh+YPC1RkATU71fTac+j1JjCcB3qwSzmlKAighx2WxhLlfhS0RwAN++PFQ== +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -244,22 +353,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" argparse@^2.0.1: version "2.0.1" @@ -299,6 +410,11 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -328,7 +444,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -340,17 +456,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" dompurify@^3.0.5: version "3.0.5" @@ -378,6 +494,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + highlight.js@^11.8.0: version "11.8.0" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.8.0.tgz#966518ea83257bae2e7c9a48596231856555bb65" @@ -400,6 +528,23 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + linkify-it@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" @@ -459,6 +604,11 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + morphdom@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/morphdom/-/morphdom-2.6.1.tgz#e868e24f989fa3183004b159aed643e628b4306e" @@ -469,24 +619,47 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^7.3.5: +semver@^7.3.5, semver@^7.5.1, semver@^7.5.3: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -shimmer@^1.1.0, shimmer@^1.2.0: +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -496,6 +669,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" diff --git a/extensions/media-preview/README.md b/extensions/media-preview/README.md index 48428a684bf..8163e017143 100644 --- a/extensions/media-preview/README.md +++ b/extensions/media-preview/README.md @@ -16,7 +16,6 @@ This extension provides basic preview for images, audio and video files. - `.webp` - `.avif` - ### Supported audio formats - `.mp3` diff --git a/extensions/media-preview/package.json b/extensions/media-preview/package.json index 3107d9d60bf..6c1b46220b9 100644 --- a/extensions/media-preview/package.json +++ b/extensions/media-preview/package.json @@ -126,7 +126,7 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "vscode-uri": "^3.0.6" }, "repository": { diff --git a/extensions/media-preview/yarn.lock b/extensions/media-preview/yarn.lock index 971c4c2c50a..36b652d7d7b 100644 --- a/extensions/media-preview/yarn.lock +++ b/extensions/media-preview/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,54 +185,104 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -182,22 +291,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -219,6 +330,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -243,7 +359,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -255,17 +371,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -283,6 +399,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -300,6 +428,30 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -312,17 +464,52 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -332,6 +519,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" @@ -346,3 +538,8 @@ vscode-uri@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.6.tgz#5e6e2e1a4170543af30151b561a41f71db1d6f91" integrity sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/merge-conflict/package.json b/extensions/merge-conflict/package.json index 00a7136cff2..751e85c3da2 100644 --- a/extensions/merge-conflict/package.json +++ b/extensions/merge-conflict/package.json @@ -166,7 +166,7 @@ } }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "devDependencies": { "@types/node": "18.x" diff --git a/extensions/merge-conflict/yarn.lock b/extensions/merge-conflict/yarn.lock index f07c9a13701..d214c5e4447 100644 --- a/extensions/merge-conflict/yarn.lock +++ b/extensions/merge-conflict/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,39 +185,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.3.0.tgz#27c6f776ac3c1c616651e506a89f438a0ed6a055" - integrity sha512-YveTnGNsFFixTKJz09Oi4zYkiLT5af3WpZDu4aIUM7xX+2bHAkOJayFTVQd6zB8kkWPpbua4Ha6Ql00grdLlJQ== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.8.0", "@opentelemetry/core@^1.0.1": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.8.0.tgz#cca18594dd48ded6dc0d08c7e789c79af0315934" - integrity sha512-6SDjwBML4Am0AQmy7z1j6HGrWDgeK8awBRUvl1PGw6HayViMk4QpnUXvv4HTHisecgVBy43NE/cstWprm8tIfw== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.8.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.8.0.tgz#260be9742cf7bceccc0db928d8ca8d64391acfe3" - integrity sha512-KSyMH6Jvss/PFDy16z5qkCK0ERlpyqixb1xwb73wLMvVq+j7i89lobDjw3JkpCcd1Ws0J6jAI4fw28Zufj2ssg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.8.0" - "@opentelemetry/semantic-conventions" "1.8.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.8.0.tgz#70713aab90978a16dea188c8335209f857be7384" - integrity sha512-iH41m0UTddnCKJzZx3M85vlhKzRcmT48pUeBbnzsGrq4nIay1oWVHKM5nhB5r8qRDGvd/n7f/YLCXClxwM0tvA== +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.8.0" - "@opentelemetry/resources" "1.8.0" - "@opentelemetry/semantic-conventions" "1.8.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.8.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.8.0.tgz#fe2aa90e6df050a11cd57f5c0f47b0641fd2cad3" - integrity sha512-TYh1MRcm4JnvpqtqOwT9WYaBYY4KERHdToxs/suDTLviGRsQkIjS5yYROTYTSJQUnYLOn/TuOh5GoMwfLSU+Ew== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" @@ -170,15 +264,30 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -187,22 +296,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -224,6 +335,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -248,7 +364,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -260,17 +376,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -288,6 +404,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -305,6 +433,30 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -317,17 +469,52 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -337,6 +524,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" @@ -346,3 +538,8 @@ uuid@^8.3.0: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/microsoft-authentication/package.json b/extensions/microsoft-authentication/package.json index c0ed977db77..8747c4a1df8 100644 --- a/extensions/microsoft-authentication/package.json +++ b/extensions/microsoft-authentication/package.json @@ -118,7 +118,7 @@ "dependencies": { "node-fetch": "2.6.7", "@azure/ms-rest-azure-env": "^2.0.0", - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "repository": { "type": "git", diff --git a/extensions/microsoft-authentication/yarn.lock b/extensions/microsoft-authentication/yarn.lock index 13322694966..68b4aa00b84 100644 --- a/extensions/microsoft-authentication/yarn.lock +++ b/extensions/microsoft-authentication/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -60,66 +85,100 @@ resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-env/-/ms-rest-azure-env-2.0.0.tgz#45809f89763a480924e21d3c620cd40866771625" integrity sha512-dG76W7ElfLi+fbTjnZVGj+M9e0BIEJmRxU6fHaUQ12bZBe8EJKYb2GV50YWNaP2uJiVQ5+7nXEVj1VN1UQtaEw== -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -131,39 +190,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" @@ -202,20 +296,35 @@ dependencies: "@types/node" "*" +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + "@types/uuid@8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0" integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -224,22 +333,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -261,6 +372,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -285,7 +401,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -297,17 +413,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -334,6 +450,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -351,6 +479,30 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" @@ -363,6 +515,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.44.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -375,12 +532,42 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -390,6 +577,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -417,3 +609,8 @@ whatwg-url@^5.0.0: dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/npm/README.md b/extensions/npm/README.md index 82730c7e82a..296bf03f73e 100644 --- a/extensions/npm/README.md +++ b/extensions/npm/README.md @@ -28,7 +28,7 @@ The extension supports running a script as a task from a folder in the Explorer. ### Others -The extension fetches data from https://registry.npmjs.org and https://registry.bower.io to provide auto-completion and information on hover features on npm dependencies. +The extension fetches data from and to provide auto-completion and information on hover features on npm dependencies. ## Settings @@ -40,5 +40,3 @@ The extension fetches data from https://registry.npmjs.org and https://registry. - `npm.scriptExplorerAction` - The default click action: `open` or `run`, the default is `open`. - `npm.enableRunFromFolder` - Enable running npm scripts from the context menu of folders in Explorer, the default is `false`. - `npm.scriptCodeLens.enable` - Enable/disable the code lenses to run a script, the default is `false`. - - diff --git a/extensions/package.json b/extensions/package.json index 02a1f822e7d..2b68f668d5b 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -4,7 +4,7 @@ "license": "MIT", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "^5.2.1-rc" + "typescript": "^5.2.2" }, "scripts": { "postinstall": "node ./postinstall.mjs" diff --git a/extensions/php-language-features/README.md b/extensions/php-language-features/README.md index c00be6a964e..e0d28f5254f 100644 --- a/extensions/php-language-features/README.md +++ b/extensions/php-language-features/README.md @@ -4,4 +4,4 @@ ## Features -See [PHP in Visual Studio Code](https://code.visualstudio.com/docs/languages/php) to learn about the features of this extension. \ No newline at end of file +See [PHP in Visual Studio Code](https://code.visualstudio.com/docs/languages/php) to learn about the features of this extension. diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index 5a9ccd93d30..cd9aef49677 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -60,6 +60,7 @@ function withNodeDefaults(/**@type WebpackConfig & { context: string }*/extConfi externals: { 'vscode': 'commonjs vscode', // ignored because it doesn't exist, 'applicationinsights-native-metrics': 'commonjs applicationinsights-native-metrics', // ignored because we don't ship native module + '@azure/functions-core': 'commonjs azure/functions-core', // optioinal dependency of appinsights that we don't use '@opentelemetry/tracing': 'commonjs @opentelemetry/tracing', // ignored because we don't ship this module '@opentelemetry/instrumentation': 'commonjs @opentelemetry/instrumentation', // ignored because we don't ship this module '@azure/opentelemetry-instrumentation-azure-sdk': 'commonjs @azure/opentelemetry-instrumentation-azure-sdk', // ignored because we don't ship this module @@ -143,6 +144,7 @@ function withBrowserDefaults(/**@type WebpackConfig & { context: string }*/extCo externals: { 'vscode': 'commonjs vscode', // ignored because it doesn't exist, 'applicationinsights-native-metrics': 'commonjs applicationinsights-native-metrics', // ignored because we don't ship native module + '@azure/functions-core': 'commonjs azure/functions-core', // optioinal dependency of appinsights that we don't use '@opentelemetry/tracing': 'commonjs @opentelemetry/tracing', // ignored because we don't ship this module '@opentelemetry/instrumentation': 'commonjs @opentelemetry/instrumentation', // ignored because we don't ship this module '@azure/opentelemetry-instrumentation-azure-sdk': 'commonjs @azure/opentelemetry-instrumentation-azure-sdk', // ignored because we don't ship this module diff --git a/extensions/simple-browser/README.md b/extensions/simple-browser/README.md index b4ecf7a4ad6..5121dc86e89 100644 --- a/extensions/simple-browser/README.md +++ b/extensions/simple-browser/README.md @@ -2,5 +2,4 @@ **Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled. -Provides a very basic browser preview using an iframe embedded in a [webview](). This extension is primarily meant to be used by other extensions for showing simple web content. - +Provides a very basic browser preview using an iframe embedded in a [webviewW](). This extension is primarily meant to be used by other extensions for showing simple web content. diff --git a/extensions/simple-browser/package.json b/extensions/simple-browser/package.json index 79abe8e57cd..e86b8de070b 100644 --- a/extensions/simple-browser/package.json +++ b/extensions/simple-browser/package.json @@ -66,7 +66,7 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.7.5" + "@vscode/extension-telemetry": "^0.8.4" }, "devDependencies": { "@types/vscode-webview": "^1.57.0", diff --git a/extensions/simple-browser/yarn.lock b/extensions/simple-browser/yarn.lock index e57ce16ff44..d6ce34c9e21 100644 --- a/extensions/simple-browser/yarn.lock +++ b/extensions/simple-browser/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,59 +185,109 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + "@types/vscode-webview@^1.57.0": version "1.57.0" resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.0.tgz#bad5194d45ae8d03afc1c0f67f71ff5e7a243bbf" integrity sha512-x3Cb/SMa1IwRHfSvKaZDZOTh4cNoG505c3NjTqGlMC082m++x/ETUmtYniDsw6SSmYzZXO8KBNhYxR0+VqymqA== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -187,22 +296,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -224,6 +335,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -248,7 +364,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -260,17 +376,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -288,6 +404,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -305,6 +433,30 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -317,17 +469,52 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -337,6 +524,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" @@ -351,3 +543,8 @@ vscode-codicons@^0.0.14: version "0.0.14" resolved "https://registry.yarnpkg.com/vscode-codicons/-/vscode-codicons-0.0.14.tgz#e0d05418e2e195564ff6f6a2199d70415911c18f" integrity sha512-6CEH5KT9ct5WMw7n5dlX7rB8ya4CUI2FSq1Wk36XaW+c5RglFtAanUV0T+gvZVVFhl/WxfjTvFHq06Hz9c1SLA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/theme-defaults/themes/dark_vs.json b/extensions/theme-defaults/themes/dark_vs.json index 21af2d3cf3a..2b9f0d5a5ab 100644 --- a/extensions/theme-defaults/themes/dark_vs.json +++ b/extensions/theme-defaults/themes/dark_vs.json @@ -34,6 +34,7 @@ "meta.embedded", "source.groovy.embedded", "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#D4D4D4" diff --git a/extensions/theme-defaults/themes/hc_black.json b/extensions/theme-defaults/themes/hc_black.json index 26dadd320a0..816fbf9395a 100644 --- a/extensions/theme-defaults/themes/hc_black.json +++ b/extensions/theme-defaults/themes/hc_black.json @@ -19,7 +19,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#FFFFFF" diff --git a/extensions/theme-defaults/themes/hc_light.json b/extensions/theme-defaults/themes/hc_light.json index fde5393f070..17c1af9ef34 100644 --- a/extensions/theme-defaults/themes/hc_light.json +++ b/extensions/theme-defaults/themes/hc_light.json @@ -3,7 +3,11 @@ "name": "Light High Contrast", "tokenColors": [ { - "scope": ["meta.embedded", "source.groovy.embedded"], + "scope": [ + "meta.embedded", + "source.groovy.embedded", + "variable.legacy.builtin.python" + ], "settings": { "foreground": "#292929" } diff --git a/extensions/theme-defaults/themes/light_vs.json b/extensions/theme-defaults/themes/light_vs.json index 301730e078e..5e2d5a7889e 100644 --- a/extensions/theme-defaults/themes/light_vs.json +++ b/extensions/theme-defaults/themes/light_vs.json @@ -38,7 +38,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#000000ff" diff --git a/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json b/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json index eeb4eeb6b88..3554c486209 100644 --- a/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json +++ b/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json @@ -64,7 +64,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#d3af86" diff --git a/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json b/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json index ea84bededd5..691680512a4 100644 --- a/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json +++ b/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json @@ -71,7 +71,8 @@ { "scope": [ "meta.embedded", - "source.groovy.embedded" + "source.groovy.embedded", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#C5C8C6" diff --git a/extensions/theme-monokai/themes/monokai-color-theme.json b/extensions/theme-monokai/themes/monokai-color-theme.json index 6489b0dd39c..9a510748714 100644 --- a/extensions/theme-monokai/themes/monokai-color-theme.json +++ b/extensions/theme-monokai/themes/monokai-color-theme.json @@ -111,7 +111,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#F8F8F2" diff --git a/extensions/theme-quietlight/themes/quietlight-color-theme.json b/extensions/theme-quietlight/themes/quietlight-color-theme.json index 9d55f2e362b..3705ed48608 100644 --- a/extensions/theme-quietlight/themes/quietlight-color-theme.json +++ b/extensions/theme-quietlight/themes/quietlight-color-theme.json @@ -10,7 +10,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#333333" diff --git a/extensions/theme-red/themes/Red-color-theme.json b/extensions/theme-red/themes/Red-color-theme.json index c139400dc56..233fd9e83da 100644 --- a/extensions/theme-red/themes/Red-color-theme.json +++ b/extensions/theme-red/themes/Red-color-theme.json @@ -70,7 +70,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#F8F8F8" diff --git a/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json b/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json index e10c6e67403..e67135a9d99 100644 --- a/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json +++ b/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json @@ -10,7 +10,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#839496" diff --git a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json index 8b4074c9a07..d5f6dc11bf0 100644 --- a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json +++ b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json @@ -10,7 +10,8 @@ "scope": [ "meta.embedded", "source.groovy.embedded", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { "foreground": "#657B83" diff --git a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json index 8e24e6fe4de..b0bdf8e90a9 100644 --- a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json +++ b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json @@ -70,7 +70,8 @@ "meta.embedded", "source.groovy.embedded", "meta.jsx.children", - "string meta.image.inline.markdown" + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" ], "settings": { //"background": "#002451", diff --git a/extensions/typescript-basics/syntaxes/Readme.md b/extensions/typescript-basics/syntaxes/Readme.md index 2f9c2b95ee2..fa05c28d970 100644 --- a/extensions/typescript-basics/syntaxes/Readme.md +++ b/extensions/typescript-basics/syntaxes/Readme.md @@ -1,6 +1,7 @@ The file `TypeScript.tmLanguage.json` and `TypeScriptReact.tmLanguage.json` are derived from [TypeScript.tmLanguage](https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScript.tmLanguage) and [TypeScriptReact.tmLanguage](https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScriptReact.tmLanguage). To update to the latest version: + - `cd extensions/typescript` and run `npm run update-grammars` - don't forget to run the integration tests at `./scripts/test-integration.sh` diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index d855af70e68..e3c9a7f870d 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -33,7 +33,7 @@ "Programming Languages" ], "dependencies": { - "@vscode/extension-telemetry": "0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "jsonc-parser": "^3.2.0", "semver": "7.5.2", "vscode-tas-client": "^0.1.63", diff --git a/extensions/typescript-language-features/src/configuration/configuration.ts b/extensions/typescript-language-features/src/configuration/configuration.ts index cab1cf4c819..d338792c58c 100644 --- a/extensions/typescript-language-features/src/configuration/configuration.ts +++ b/extensions/typescript-language-features/src/configuration/configuration.ts @@ -112,6 +112,7 @@ export interface TypeScriptServiceConfiguration { readonly useSyntaxServer: SyntaxServerConfiguration; readonly webProjectWideIntellisenseEnabled: boolean; readonly webProjectWideIntellisenseSuppressSemanticErrors: boolean; + readonly enableDiagnosticsTelemetry: boolean; readonly enableProjectDiagnostics: boolean; readonly maxTsServerMemory: number; readonly enablePromptUseWorkspaceTsdk: boolean; @@ -144,6 +145,7 @@ export abstract class BaseServiceConfigurationProvider implements ServiceConfigu useSyntaxServer: this.readUseSyntaxServer(configuration), webProjectWideIntellisenseEnabled: this.readWebProjectWideIntellisenseEnable(configuration), webProjectWideIntellisenseSuppressSemanticErrors: this.readWebProjectWideIntellisenseSuppressSemanticErrors(configuration), + enableDiagnosticsTelemetry: this.readEnableDiagnosticsTelemetry(configuration), enableProjectDiagnostics: this.readEnableProjectDiagnostics(configuration), maxTsServerMemory: this.readMaxTsServerMemory(configuration), enablePromptUseWorkspaceTsdk: this.readEnablePromptUseWorkspaceTsdk(configuration), @@ -197,6 +199,11 @@ export abstract class BaseServiceConfigurationProvider implements ServiceConfigu return SyntaxServerConfiguration.Never; } + protected readEnableDiagnosticsTelemetry(configuration: vscode.WorkspaceConfiguration): boolean { + // This setting does not appear in the settings view, as it is not to be enabled by users outside the team + return configuration.get('typescript.enableDiagnosticsTelemetry', false); + } + protected readEnableProjectDiagnostics(configuration: vscode.WorkspaceConfiguration): boolean { return configuration.get('typescript.tsserver.experimental.enableProjectDiagnostics', false); } diff --git a/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts b/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts index aeb4491872e..1f6c21a5d88 100644 --- a/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts +++ b/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts @@ -8,6 +8,9 @@ import { DiagnosticLanguage } from '../configuration/languageDescription'; import * as arrays from '../utils/arrays'; import { Disposable } from '../utils/dispose'; import { ResourceMap } from '../utils/resourceMap'; +import { TelemetryReporter } from '../logging/telemetry'; +import { TypeScriptServiceConfiguration } from '../configuration/configuration'; +import { equals } from '../utils/objects'; function diagnosticsEquals(a: vscode.Diagnostic, b: vscode.Diagnostic): boolean { if (a === b) { @@ -148,6 +151,82 @@ class DiagnosticSettings { } } +class DiagnosticsTelemetryManager extends Disposable { + + private readonly _diagnosticCodesMap = new Map(); + private readonly _diagnosticSnapshotsMap = new ResourceMap(uri => uri.toString(), { onCaseInsensitiveFileSystem: false }); + private _timeout: NodeJS.Timeout | undefined; + private _telemetryEmitter: NodeJS.Timer | undefined; + + constructor( + private readonly _telemetryReporter: TelemetryReporter, + private readonly _diagnosticsCollection: vscode.DiagnosticCollection, + ) { + super(); + this._register(vscode.workspace.onDidChangeTextDocument(e => { + if (e.document.languageId === 'typescript' || e.document.languageId === 'typescriptreact') { + this._updateAllDiagnosticCodesAfterTimeout(); + } + })); + this._updateAllDiagnosticCodesAfterTimeout(); + this._registerTelemetryEventEmitter(); + } + + private _updateAllDiagnosticCodesAfterTimeout() { + clearTimeout(this._timeout); + this._timeout = setTimeout(() => this._updateDiagnosticCodes(), 5000); + } + + private _increaseDiagnosticCodeCount(code: string | number | undefined) { + if (code === undefined) { + return; + } + this._diagnosticCodesMap.set(Number(code), (this._diagnosticCodesMap.get(Number(code)) || 0) + 1); + } + + private _updateDiagnosticCodes() { + this._diagnosticsCollection.forEach((uri, diagnostics) => { + const previousDiagnostics = this._diagnosticSnapshotsMap.get(uri); + this._diagnosticSnapshotsMap.set(uri, diagnostics); + const diagnosticsDiff = diagnostics.filter((diagnostic) => !previousDiagnostics?.some((previousDiagnostic) => equals(diagnostic, previousDiagnostic))); + diagnosticsDiff.forEach((diagnostic) => { + const code = diagnostic.code; + this._increaseDiagnosticCodeCount(typeof code === 'string' || typeof code === 'number' ? code : code?.value); + }); + }); + } + + private _registerTelemetryEventEmitter() { + this._telemetryEmitter = setInterval(() => { + if (this._diagnosticCodesMap.size > 0) { + let diagnosticCodes = ''; + this._diagnosticCodesMap.forEach((value, key) => { + diagnosticCodes += `${key}:${value},`; + }); + this._diagnosticCodesMap.clear(); + /* __GDPR__ + "typescript.diagnostics" : { + "owner": "@aiday-mar", + "diagnosticCodes" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, + "${include}": [ + "${TypeScriptCommonProperties}" + ] + } + */ + this._telemetryReporter.logTelemetry('typescript.diagnostics', { + diagnoticCodes: diagnosticCodes + }); + } + }, 5 * 60 * 1000); // 5 minutes + } + + override dispose() { + super.dispose(); + clearTimeout(this._timeout); + clearInterval(this._telemetryEmitter); + } +} + export class DiagnosticsManager extends Disposable { private readonly _diagnostics: ResourceMap; private readonly _settings = new DiagnosticSettings(); @@ -158,6 +237,8 @@ export class DiagnosticsManager extends Disposable { constructor( owner: string, + configuration: TypeScriptServiceConfiguration, + telemetryReporter: TelemetryReporter, onCaseInsensitiveFileSystem: boolean ) { super(); @@ -165,6 +246,10 @@ export class DiagnosticsManager extends Disposable { this._pendingUpdates = new ResourceMap(undefined, { onCaseInsensitiveFileSystem }); this._currentDiagnostics = this._register(vscode.languages.createDiagnosticCollection(owner)); + // Here we are selecting only 1 user out of 1000 to send telemetry diagnostics + if (Math.random() * 1000 <= 1 || configuration.enableDiagnosticsTelemetry) { + this._register(new DiagnosticsTelemetryManager(telemetryReporter, this._currentDiagnostics)); + } } public override dispose() { diff --git a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts index 5363619579b..4fa38e4986b 100644 --- a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts +++ b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts @@ -6,6 +6,7 @@ import * as vscode from 'vscode'; import { DocumentSelector } from '../configuration/documentSelector'; import { LanguageDescription } from '../configuration/languageDescription'; +import { TelemetryReporter } from '../logging/telemetry'; import { API } from '../tsServer/api'; import type * as Proto from '../tsServer/protocol/protocol'; import { Location, Position } from '../typeConverters'; @@ -29,13 +30,16 @@ class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHin public static readonly minVersion = API.v440; - private readonly _onDidChangeInlayHints = new vscode.EventEmitter(); + private readonly _onDidChangeInlayHints = this._register(new vscode.EventEmitter()); public readonly onDidChangeInlayHints = this._onDidChangeInlayHints.event; + private hasReportedTelemetry = false; + constructor( private readonly language: LanguageDescription, private readonly client: ITypeScriptServiceClient, - private readonly fileConfigurationManager: FileConfigurationManager + private readonly fileConfigurationManager: FileConfigurationManager, + private readonly telemetryReporter: TelemetryReporter, ) { super(); @@ -54,31 +58,47 @@ class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHin })); } - async provideInlayHints(model: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise { + async provideInlayHints(model: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise { const filepath = this.client.toOpenTsFilePath(model); if (!filepath) { - return []; + return; } if (!areInlayHintsEnabledForFile(this.language, model)) { - return []; + return; } const start = model.offsetAt(range.start); const length = model.offsetAt(range.end) - start; await this.fileConfigurationManager.ensureConfigurationForDocument(model, token); + if (token.isCancellationRequested) { + return; + } + + if (!this.hasReportedTelemetry) { + this.hasReportedTelemetry = true; + /* __GDPR__ + "inlayHints.provide" : { + "owner": "mjbvz", + "${include}": [ + "${TypeScriptCommonProperties}" + ] + } + */ + this.telemetryReporter.logTelemetry('inlayHints.provide', {}); + } const response = await this.client.execute('provideInlayHints', { file: filepath, start, length }, token); if (response.type !== 'response' || !response.success || !response.body) { - return []; + return; } return response.body.map(hint => { const result = new vscode.InlayHint( Position.fromLocation(hint.position), - this.convertInlayHintText(model.uri, hint), - hint.kind && fromProtocolInlayHintKind(hint.kind) + this.convertInlayHintText(hint), + fromProtocolInlayHintKind(hint.kind) ); result.paddingLeft = hint.whitespaceBefore; result.paddingRight = hint.whitespaceAfter; @@ -86,19 +106,18 @@ class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHin }); } - private convertInlayHintText(resource: vscode.Uri, tsHint: Proto.InlayHintItem): string | vscode.InlayHintLabelPart[] { + private convertInlayHintText(tsHint: Proto.InlayHintItem): string | vscode.InlayHintLabelPart[] { if (tsHint.displayParts) { return tsHint.displayParts.map((part): vscode.InlayHintLabelPart => { const out = new vscode.InlayHintLabelPart(part.text); if (part.span) { - out.location = Location.fromTextSpan(resource, part.span); + out.location = Location.fromTextSpan(this.client.toResource(part.span.file), part.span); } return out; }); } return tsHint.text; - } } @@ -128,13 +147,14 @@ export function register( selector: DocumentSelector, language: LanguageDescription, client: ITypeScriptServiceClient, - fileConfigurationManager: FileConfigurationManager + fileConfigurationManager: FileConfigurationManager, + telemetryReporter: TelemetryReporter, ) { return conditionalRegistration([ requireMinVersion(client, TypeScriptInlayHintsProvider.minVersion), requireSomeCapability(client, ClientCapability.Semantic), ], () => { - const provider = new TypeScriptInlayHintsProvider(language, client, fileConfigurationManager); + const provider = new TypeScriptInlayHintsProvider(language, client, fileConfigurationManager, telemetryReporter); return vscode.languages.registerInlayHintsProvider(selector.semantic, provider); }); } diff --git a/extensions/typescript-language-features/src/languageProvider.ts b/extensions/typescript-language-features/src/languageProvider.ts index 1de34c6998c..7acbf733f0c 100644 --- a/extensions/typescript-language-features/src/languageProvider.ts +++ b/extensions/typescript-language-features/src/languageProvider.ts @@ -74,7 +74,7 @@ export default class LanguageProvider extends Disposable { import('./languageFeatures/formatting').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))), import('./languageFeatures/hover').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager))), import('./languageFeatures/implementations').then(provider => this._register(provider.register(selector, this.client))), - import('./languageFeatures/inlayHints').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))), + import('./languageFeatures/inlayHints').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager, this.telemetryReporter))), import('./languageFeatures/jsDocCompletions').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))), import('./languageFeatures/linkedEditing').then(provider => this._register(provider.register(selector, this.client))), import('./languageFeatures/organizeImports').then(provider => this._register(provider.register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter))), diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 86c6bb8d9f1..e00bed60b3f 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -176,7 +176,6 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.bufferSyncSupport = new BufferSyncSupport(this, allModeIds, onCaseInsenitiveFileSystem); this.onReady(() => { this.bufferSyncSupport.listen(); }); - this.diagnosticsManager = new DiagnosticsManager('typescript', onCaseInsenitiveFileSystem); this.bufferSyncSupport.onDelete(resource => { this.cancelInflightRequestsForResource(resource); this.diagnosticsManager.deleteAllDiagnosticsInFile(resource); @@ -213,7 +212,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType } return this.apiVersion.fullVersionString; }); - + this.diagnosticsManager = new DiagnosticsManager('typescript', this._configuration, this.telemetryReporter, onCaseInsenitiveFileSystem); this.typescriptServerSpawner = new TypeScriptServerSpawner(this.versionProvider, this._versionManager, this.logDirectoryProvider, this.pluginPathsProvider, this.logger, this.telemetryReporter, this.tracer, this.processFactory); this._register(this.pluginManager.onDidUpdateConfig(update => { diff --git a/extensions/typescript-language-features/web/README.md b/extensions/typescript-language-features/web/README.md index 9cae35b8cf3..a9c19b5d72a 100644 --- a/extensions/typescript-language-features/web/README.md +++ b/extensions/typescript-language-features/web/README.md @@ -1,4 +1,5 @@ # vscode-wasm-typescript + Language server host for typescript using vscode's sync-api in the browser ## TODOs @@ -22,33 +23,33 @@ Language server host for typescript using vscode's sync-api in the browser - LATER: Turns out you can skip the existing server by depending on tsserverlibrary instead of tsserver. - [x] figure out a webpack-native way to generate tsserver.web.js if possible - [x] path rewriting is pretty loosey-goosey; likely to be incorrect some of the time - - invert the logic from TypeScriptServiceClient.normalizedPath for requests - - invert the function from webServer.ts for responses (maybe) - - something with getWorkspaceRootForResource (or anything else that checks `resouce.scheme`) + - invert the logic from TypeScriptServiceClient.normalizedPath for requests + - invert the function from webServer.ts for responses (maybe) + - something with getWorkspaceRootForResource (or anything else that checks `resouce.scheme`) - [x] put files one level down from virtual root - [x] fill in missing environment files like lib.dom.d.ts - - toResource's isWeb branch *probably* knows where to find this, just need to put it in the virtual FS - - I guess during setup in serverProcess.browser.ts. - - Not sure whether it needs to have the data or just a fs entry. - - Wait, I don't know how files get added to the FS normally. + - toResource's isWeb branch *probably* knows where to find this, just need to put it in the virtual FS + - I guess during setup in serverProcess.browser.ts. + - Not sure whether it needs to have the data or just a fs entry. + - Wait, I don't know how files get added to the FS normally. - [x] cancellation should only retain one cancellation checker - - the one that matches the current request id - - but that means tracking (or retrieving from tsserver) the request id (aka seq?) - - and correctly setting/resetting it on the cancellation token too. - - I looked at the tsserver code. I think the web case is close to the single-pipe node case, + - the one that matches the current request id + - but that means tracking (or retrieving from tsserver) the request id (aka seq?) + - and correctly setting/resetting it on the cancellation token too. + - I looked at the tsserver code. I think the web case is close to the single-pipe node case, so I just require that requestId is set in order to call the *current* cancellation checker. - - Any incoming message with a cancellation checker will overwrite the current one. + - Any incoming message with a cancellation checker will overwrite the current one. - [x] Cancellation code in vscode is suspiciously prototypey. - - Specifically, it adds the vscode-wasm cancellation to original cancellation code, but should actually switch to the former for web only. - - looks like `isWeb()` is a way to check for being on the web + - Specifically, it adds the vscode-wasm cancellation to original cancellation code, but should actually switch to the former for web only. + - looks like `isWeb()` is a way to check for being on the web - [x] create multiple watchers - - on-demand instead of watching everything and checking on watch firing + - on-demand instead of watching everything and checking on watch firing - [x] get file watching to work - - it could *already* work, I just don't know how to test it - - look at extensions/markdown-language-features/src/client/fileWatchingManager.ts to see if I can use that - - later: it is OK. its main difference is that you can watch files in not-yet-created directories, and it maintains + - it could *already* work, I just don't know how to test it + - look at extensions/markdown-language-features/src/client/fileWatchingManager.ts to see if I can use that + - later: it is OK. its main difference is that you can watch files in not-yet-created directories, and it maintains a web of directory watches that then check whether the file is eventually created. - - even later: well, it works even though it is similar to my code. + - even later: well, it works even though it is similar to my code. I'm not sure what is different. - [x] copy fileWatchingManager.ts to web/ ; there's no sharing code between extensions - [x] Find out scheme the web actually uses instead of vscode-test-web (or switch over entirely to isWeb) @@ -106,6 +107,7 @@ Language server host for typescript using vscode's sync-api in the browser - so I can just redo whatever that did and it'll be fine ### Done + - [x] need to update 0.2 -> 0.7.* API (once it's working properly) - [x] including reshuffling the webpack hack if needed - [x] need to use the settings recommended by Sheetal @@ -113,7 +115,7 @@ Language server host for typescript using vscode's sync-api in the browser - [x] sync-api-client says fs is rooted at memfs:/sample-folder; the protocol 'memfs:' is confusing our file parsing I think - [x] nothing ever seems to find tsconfig.json - [x] messages aren't actually coming through, just the message from the first request - - fixed by simplifying the listener setup for now + - fixed by simplifying the listener setup for now - [x] once messages work, you can probably log by postMessage({ type: 'log', body: "some logging text" }) - [x] implement realpath, modifiedtime, resolvepath, then turn semantic mode on - [x] file watching implemented with saved map of filename to callback, and forwarding @@ -125,6 +127,7 @@ Language server host for typescript using vscode's sync-api in the browser ## Notes messages received by extension AND host use paths like ^/memfs/ts-nul-authority/sample-folder/file.ts + - problem: pretty sure the extension doesn't know what to do with that: it's not putting down error spans in file.ts - question: why is the extension requesting quickinfo in that URI format? And it works! (probably because the result is a tooltip, not an in-file span) - problem: weird concatenations with memfs:/ in the middle @@ -140,15 +143,14 @@ but readFile is getting called with things like memfs:/sample-folder/memfs:/type watchDirectory with /sample-folder/^ and directoryExists with /sample-folder/^/memfs/ts-nul-authority/sample-folder/workspaces/ watchFile with /sample-folder/memfs:/sample-folder/memfs:/lib.es2020.full.d.ts -### LATER: +### LATER OK, so the paths that tsserver has look like this: ^/scheme/mount/whatever.ts but the paths the filesystem has look like this: scheme:/whatever.ts (not sure about 'mount', that's only when cloning from the fs) so you have to shave off the scheme that the host combined with the path and put on the scheme that the vfs is using. -### LATER 2: +### LATER 2 Some commands ask for getExecutingFilePath or getCurrentDirectory and cons up a path themselves. This works, because URI.from({ scheme, path }) matches what the fs has in it Problem: In *some* messages (all?), vscode then refers to /x.ts and ^/vscode-test-web/mount/x.ts (or ^/memfs/ts-nul-authority/x.ts) - diff --git a/extensions/typescript-language-features/yarn.lock b/extensions/typescript-language-features/yarn.lock index 1b011de0449..eedf2d9c580 100644 --- a/extensions/typescript-language-features/yarn.lock +++ b/extensions/typescript-language-features/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,39 +185,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" @@ -175,15 +269,20 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ== -"@vscode/extension-telemetry@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" "@vscode/sync-api-client@^0.7.2": version "0.7.2" @@ -206,6 +305,16 @@ "@vscode/sync-api-common" "0.7.2" vscode-uri "3.0.3" +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -213,22 +322,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -257,6 +368,11 @@ axios@^0.26.1: dependencies: follow-redirects "^1.14.8" +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -281,7 +397,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -293,17 +409,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -326,6 +442,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -343,6 +471,23 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + jsonc-parser@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" @@ -367,11 +512,39 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@7.5.2: version "7.5.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" @@ -384,7 +557,14 @@ semver@^5.3.0, semver@^5.4.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -shimmer@^1.1.0, shimmer@^1.2.0: +semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -394,6 +574,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tas-client@0.1.58: version "0.1.58" resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.58.tgz#67d66bf0e27df5276ebc751105e6ad47791c36d8" diff --git a/extensions/vscode-api-tests/package.json b/extensions/vscode-api-tests/package.json index 5ee95741ff0..ad2305f8a6a 100644 --- a/extensions/vscode-api-tests/package.json +++ b/extensions/vscode-api-tests/package.json @@ -19,6 +19,7 @@ "fileSearchProvider", "findTextInFiles", "fsChunks", + "mappedEditsProvider", "notebookCellExecutionState", "notebookDeprecated", "notebookLiveShare", @@ -44,15 +45,12 @@ "textSearchProvider", "timeline", "tokenInformation", - "treeItemCheckbox", "treeViewActiveItem", "treeViewReveal", "workspaceTrust", "telemetry", "windowActivity", - "interactiveUserActions", - "envCollectionWorkspace", - "envCollectionOptions" + "interactiveUserActions" ], "private": true, "activationEvents": [], diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/mappedEdits.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/mappedEdits.test.ts new file mode 100644 index 00000000000..f4fc349f115 --- /dev/null +++ b/extensions/vscode-api-tests/src/singlefolder-tests/mappedEdits.test.ts @@ -0,0 +1,102 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as path from 'path'; +import * as vscode from 'vscode'; +import * as assert from 'assert'; + +suite('mapped edits provider', () => { + + test('mapped edits does not provide edits for unregistered langs', async function () { + + const uri = vscode.Uri.file(path.join(vscode.workspace.rootPath || '', './myFile.ts')); + + const tsDocFilter = [{ language: 'json' }]; + + const r1 = vscode.chat.registerMappedEditsProvider(tsDocFilter, { + provideMappedEdits: (_doc: vscode.TextDocument, codeBlocks: string[], context: vscode.MappedEditsContext, _token: vscode.CancellationToken) => { + + assert(context.selections.length === 1); + assert(context.related.length === 1); + assert('uri' in context.related[0] && 'range' in context.related[0]); + + const edit = new vscode.WorkspaceEdit(); + const text = codeBlocks.join('\n//----\n'); + edit.replace(uri, context.selections[0], text); + return edit; + } + }); + await vscode.workspace.openTextDocument(uri); + const result = await vscode.commands.executeCommand>( + 'vscode.executeMappedEditsProvider', + uri, + [ + '// hello', + `function foo() {\n\treturn 1;\n}`, + ], + { + selections: [new vscode.Selection(0, 0, 1, 0)], + related: [ + { + uri, + range: new vscode.Range(new vscode.Position(0, 0), new vscode.Position(1, 0)) + } + ] + } + ); + r1.dispose(); + + assert(result === null, 'returned null'); + }); + + test('mapped edits provides a single edit replacing the selection', async function () { + + const uri = vscode.Uri.file(path.join(vscode.workspace.rootPath || '', './myFile.ts')); + + const tsDocFilter = [{ language: 'typescript' }]; + + const r1 = vscode.chat.registerMappedEditsProvider(tsDocFilter, { + provideMappedEdits: (_doc: vscode.TextDocument, codeBlocks: string[], context: vscode.MappedEditsContext, _token: vscode.CancellationToken) => { + + assert(context.selections.length === 1); + assert(context.related.length === 1); + assert('uri' in context.related[0] && 'range' in context.related[0]); + + const edit = new vscode.WorkspaceEdit(); + const text = codeBlocks.join('\n//----\n'); + edit.replace(uri, context.selections[0], text); + return edit; + } + }); + + await vscode.workspace.openTextDocument(uri); + const result = await vscode.commands.executeCommand>( + 'vscode.executeMappedEditsProvider', + uri, + [ + '// hello', + `function foo() {\n\treturn 1;\n}`, + ], + { + selections: [new vscode.Selection(0, 0, 1, 0)], + related: [ + { + uri, + range: new vscode.Range(new vscode.Position(0, 0), new vscode.Position(1, 0)) + } + ] + } + ); + r1.dispose(); + + assert(result, 'non null response'); + const edits = result.get(uri); + assert(edits.length === 1); + assert(edits[0].range.start.line === 0); + assert(edits[0].range.start.character === 0); + assert(edits[0].range.end.line === 1); + assert(edits[0].range.end.character === 0); + }); +}); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts index f8c8b806853..4275898e244 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { deepStrictEqual, doesNotThrow, equal, ok, strictEqual, throws } from 'assert'; -import { commands, ConfigurationTarget, Disposable, env, EnvironmentVariableCollection, EnvironmentVariableMutator, EnvironmentVariableMutatorOptions, EnvironmentVariableMutatorType, EnvironmentVariableScope, EventEmitter, ExtensionContext, extensions, ExtensionTerminalOptions, Pseudoterminal, Terminal, TerminalDimensions, TerminalExitReason, TerminalOptions, TerminalState, UIKind, Uri, window, workspace } from 'vscode'; +import { commands, ConfigurationTarget, Disposable, env, EnvironmentVariableMutator, EnvironmentVariableMutatorOptions, EnvironmentVariableMutatorType, EventEmitter, ExtensionContext, extensions, ExtensionTerminalOptions, Pseudoterminal, Terminal, TerminalDimensions, TerminalExitReason, TerminalOptions, TerminalState, UIKind, Uri, window, workspace } from 'vscode'; import { assertNoRpc, poll } from '../utils'; // Disable terminal tests: @@ -912,11 +912,10 @@ import { assertNoRpc, poll } from '../utils'; }); test('get and forEach should work (scope)', () => { - // TODO: Remove cast once `envCollectionWorkspace` API is finalized. - const collection = extensionContext.environmentVariableCollection as (EnvironmentVariableCollection & { getScopedEnvironmentVariableCollection(scope: EnvironmentVariableScope): EnvironmentVariableCollection }); + const collection = extensionContext.environmentVariableCollection; disposables.push({ dispose: () => collection.clear() }); const scope = { workspaceFolder: { uri: Uri.file('workspace1'), name: 'workspace1', index: 0 } }; - const scopedCollection = collection.getScopedEnvironmentVariableCollection(scope); + const scopedCollection = collection.getScoped(scope); scopedCollection.replace('A', 'scoped~a2~'); scopedCollection.append('B', 'scoped~b2~'); scopedCollection.prepend('C', 'scoped~c2~'); @@ -928,7 +927,7 @@ import { assertNoRpc, poll } from '../utils'; applyAtProcessCreation: true, applyAtShellIntegration: false }; - const expectedScopedCollection = collection.getScopedEnvironmentVariableCollection(scope); + const expectedScopedCollection = collection.getScoped(scope); deepStrictEqual(expectedScopedCollection.get('A'), { value: 'scoped~a2~', type: EnvironmentVariableMutatorType.Replace, options: defaultOptions }); deepStrictEqual(expectedScopedCollection.get('B'), { value: 'scoped~b2~', type: EnvironmentVariableMutatorType.Append, options: defaultOptions }); deepStrictEqual(expectedScopedCollection.get('C'), { value: 'scoped~c2~', type: EnvironmentVariableMutatorType.Prepend, options: defaultOptions }); diff --git a/extensions/vscode-api-tests/testWorkspace/myFile.ts b/extensions/vscode-api-tests/testWorkspace/myFile.ts new file mode 100644 index 00000000000..2a2a4927869 --- /dev/null +++ b/extensions/vscode-api-tests/testWorkspace/myFile.ts @@ -0,0 +1,3 @@ +// 1 +// 2 +// 3 diff --git a/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md b/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md index 28f3590536e..309aa6de793 100644 --- a/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md +++ b/extensions/vscode-colorize-tests/test/colorize-fixtures/test.md @@ -103,4 +103,4 @@ Pop * Multiple definitions and terms are possible * Definitions can include multiple paragraphs too -*[ABBR]: Markdown plus abbreviations (produces an tag) \ No newline at end of file +*[ABBR]: Markdown plus abbreviations (produces an tag) diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_py.json b/extensions/vscode-colorize-tests/test/colorize-results/test_py.json index e858cd5f201..e8d718cad72 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_py.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_py.json @@ -1907,14 +1907,14 @@ "c": "reduce", "t": "source.python meta.function-call.python variable.legacy.builtin.python", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE", - "dark_modern": "variable: #9CDCFE", - "hc_light": "variable: #001080", - "light_modern": "variable: #001080" + "dark_plus": "variable.legacy.builtin.python: #D4D4D4", + "light_plus": "variable.legacy.builtin.python: #000000", + "dark_vs": "variable.legacy.builtin.python: #D4D4D4", + "light_vs": "variable.legacy.builtin.python: #000000", + "hc_black": "variable.legacy.builtin.python: #FFFFFF", + "dark_modern": "variable.legacy.builtin.python: #D4D4D4", + "hc_light": "variable.legacy.builtin.python: #292929", + "light_modern": "variable.legacy.builtin.python: #000000" } }, { @@ -6233,14 +6233,14 @@ "c": "raw_input", "t": "source.python meta.function-call.python variable.legacy.builtin.python", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE", - "dark_modern": "variable: #9CDCFE", - "hc_light": "variable: #001080", - "light_modern": "variable: #001080" + "dark_plus": "variable.legacy.builtin.python: #D4D4D4", + "light_plus": "variable.legacy.builtin.python: #000000", + "dark_vs": "variable.legacy.builtin.python: #D4D4D4", + "light_vs": "variable.legacy.builtin.python: #000000", + "hc_black": "variable.legacy.builtin.python: #FFFFFF", + "dark_modern": "variable.legacy.builtin.python: #D4D4D4", + "hc_light": "variable.legacy.builtin.python: #292929", + "light_modern": "variable.legacy.builtin.python: #000000" } }, { diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 08ae5fb06c3..b704d5f8a28 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -228,10 +228,10 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -typescript@^5.2.1-rc: - version "5.2.1-rc" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.1-rc.tgz#9cf33ff6bc39ba9e1fa59761124f596ecf5e0c07" - integrity sha512-gsOdmedQZEWLrYhNqHuzPmcV+4wX7UujzYqszDC5mVMjcN6Nm7lN2eAtndmjWl24aGdAwJqL2ooywkxpaTx8QQ== +typescript@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== vscode-grammar-updater@^1.1.0: version "1.1.0" diff --git a/package.json b/package.json index 7c5d9cb3444..080af3cecd2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.82.0", - "distro": "505b0336f71abdfa7d1ed0dbaafa20c812fa58e7", + "distro": "56bfb9ce4a8d2298f475a1b8d9c7a7b5a72204f2", "author": { "name": "Microsoft Corporation" }, @@ -95,14 +95,14 @@ "vscode-oniguruma": "1.7.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "9.0.0", - "xterm": "5.3.0-beta.46", - "xterm-addon-canvas": "0.5.0-beta.9", - "xterm-addon-image": "0.6.0-beta.2", - "xterm-addon-search": "0.13.0-beta.8", - "xterm-addon-serialize": "0.11.0-beta.8", - "xterm-addon-unicode11": "0.5.0", - "xterm-addon-webgl": "0.16.0-beta.16", - "xterm-headless": "5.3.0-beta.46", + "xterm": "5.3.0-beta.61", + "xterm-addon-canvas": "0.5.0-beta.22", + "xterm-addon-image": "0.6.0-beta.14", + "xterm-addon-search": "0.13.0-beta.20", + "xterm-addon-serialize": "0.11.0-beta.20", + "xterm-addon-unicode11": "0.6.0-beta.12", + "xterm-addon-webgl": "0.16.0-beta.30", + "xterm-headless": "5.3.0-beta.61", "yauzl": "^2.9.2", "yazl": "^2.4.3" }, @@ -212,7 +212,7 @@ "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "tsec": "0.2.7", - "typescript": "^5.3.0-dev.20230816", + "typescript": "^5.3.0-dev.20230824", "typescript-formatter": "7.1.0", "underscore": "^1.12.1", "util": "^0.12.4", diff --git a/remote/package.json b/remote/package.json index 28cf60a0252..8fe0e55c1de 100644 --- a/remote/package.json +++ b/remote/package.json @@ -27,14 +27,14 @@ "vscode-oniguruma": "1.7.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "9.0.0", - "xterm": "5.3.0-beta.46", - "xterm-addon-canvas": "0.5.0-beta.9", - "xterm-addon-image": "0.6.0-beta.2", - "xterm-addon-search": "0.13.0-beta.8", - "xterm-addon-serialize": "0.11.0-beta.8", - "xterm-addon-unicode11": "0.5.0", - "xterm-addon-webgl": "0.16.0-beta.16", - "xterm-headless": "5.3.0-beta.46", + "xterm": "5.3.0-beta.61", + "xterm-addon-canvas": "0.5.0-beta.22", + "xterm-addon-image": "0.6.0-beta.14", + "xterm-addon-search": "0.13.0-beta.20", + "xterm-addon-serialize": "0.11.0-beta.20", + "xterm-addon-unicode11": "0.6.0-beta.12", + "xterm-addon-webgl": "0.16.0-beta.30", + "xterm-headless": "5.3.0-beta.61", "yauzl": "^2.9.2", "yazl": "^2.4.3" } diff --git a/remote/web/package.json b/remote/web/package.json index bd22a24243a..6075a563e34 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -11,11 +11,11 @@ "tas-client-umd": "0.1.8", "vscode-oniguruma": "1.7.0", "vscode-textmate": "9.0.0", - "xterm": "5.3.0-beta.46", - "xterm-addon-canvas": "0.5.0-beta.9", - "xterm-addon-image": "0.6.0-beta.2", - "xterm-addon-search": "0.13.0-beta.8", - "xterm-addon-unicode11": "0.5.0", - "xterm-addon-webgl": "0.16.0-beta.16" + "xterm": "5.3.0-beta.61", + "xterm-addon-canvas": "0.5.0-beta.22", + "xterm-addon-image": "0.6.0-beta.14", + "xterm-addon-search": "0.13.0-beta.20", + "xterm-addon-unicode11": "0.6.0-beta.12", + "xterm-addon-webgl": "0.16.0-beta.30" } } diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index b57b5aa165d..b56fac51a45 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -68,32 +68,32 @@ vscode-textmate@9.0.0: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-9.0.0.tgz#313c6c8792b0507aef35aeb81b6b370b37c44d6c" integrity sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg== -xterm-addon-canvas@0.5.0-beta.9: - version "0.5.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.9.tgz#d4a9536cf586f78a54527751e03abf6445613886" - integrity sha512-AMyFctHbIWx0aLcACINuZqFFNoz4ndGtIAb4pQguIl9t8r+2otiV11MY4FJmPM0kUzEzoLWzVFJaGxOzykCWuw== +xterm-addon-canvas@0.5.0-beta.22: + version "0.5.0-beta.22" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.22.tgz#513f0c2b7cf96073f47627b27e8965c1b1a22431" + integrity sha512-9F6ZI0DMRgffVfHkLkDwl5n8VscvCaV10tWI3skXOX7Y7Aws6OEeglkOPoU3IllofCU792kHKM4pPoToUxTltg== -xterm-addon-image@0.6.0-beta.2: - version "0.6.0-beta.2" - resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.2.tgz#04c5ea11c89032b01b577b37f891109168ed0b09" - integrity sha512-58d1mqIpJwq8Zy/a/QM8JVuA1g5SceG8UvLoj9T6r+2XIktka6GK2oS66Fmo+0MP0s0HDPy+yJtl8lHY6UyzHw== +xterm-addon-image@0.6.0-beta.14: + version "0.6.0-beta.14" + resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.14.tgz#75fc3f824123183a4bbb5306e22f8b2c6966b0a6" + integrity sha512-D5Gh5JTKhHaPt1KwQNf6diF37KA4eToJw3XId1wy62tWmSqfq+QflhOGTfd+SnSQYCktU05ETzM+0tncIU62pQ== -xterm-addon-search@0.13.0-beta.8: - version "0.13.0-beta.8" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.8.tgz#90bc70bff87cd7e4f540cce51d9f968f04d5c0ef" - integrity sha512-Hlocg6gGvKAs4eRTW78wTtVqaOEurweJjdyPDjr7KrzwlEEsASsUXJaB2+vgsyTFKuYnCuLrp5u369jck993GQ== +xterm-addon-search@0.13.0-beta.20: + version "0.13.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.20.tgz#8ddd0513e2a70fcefa325722100d2e1bfaf3b9cb" + integrity sha512-wrx6187cJ1UenGL6ZeYv3jFvRPhhENTfbC+Hv1Fnww8LmsKhcj+0+Pm6yInNjX/9hNVsNzdqKyqNeEMoykyoyA== -xterm-addon-unicode11@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.5.0.tgz#41c0d96acc1e3bb6c6596eee64e163b6bca74be7" - integrity sha512-Jm4/g4QiTxiKiTbYICQgC791ubhIZyoIwxAIgOW8z8HWFNY+lwk+dwaKEaEeGBfM48Vk8fklsUW9u/PlenYEBg== +xterm-addon-unicode11@0.6.0-beta.12: + version "0.6.0-beta.12" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.12.tgz#ac6df9d635325dc692e4c602e74a2fc27a09405c" + integrity sha512-9wWWf/5nFafYgq0pn9EgAWnXaXGleVxfjNOqavpLRYFv0nw42QbaYyGvnGcxyYHM5Aqx/8rYE/DDVWZBqQZdYA== -xterm-addon-webgl@0.16.0-beta.16: - version "0.16.0-beta.16" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.16.tgz#2c31308f8c7f636576720adca529297f8fff3224" - integrity sha512-k0ZSwpBVtxXaqUc29CmlfFgIK7LEYAmwcDC3QVp2ESZo2JHYuQrWFpImjbzbYu0ON6qqcfbX8SnbzRid/XfGUg== +xterm-addon-webgl@0.16.0-beta.30: + version "0.16.0-beta.30" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.30.tgz#820d5c65f868b14ec4177bfb8a294931a53616bf" + integrity sha512-39qPHPFmNENxcHf8/CzGHS6wzKMMegoRkHB1+scqtBhSxFaD8tX5Ye33HZIEdQ9nXe9xtr4FWVp77T+n9hdrew== -xterm@5.3.0-beta.46: - version "5.3.0-beta.46" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.46.tgz#9bd2b2a588c88ae64f1989ca3bf5bd9116554b5a" - integrity sha512-keB3C6sXm56ug1+hylAQiNyZP4YtPgd2W+Gu/ZKwJMk5haD25DEnenBYL++Cl3+sNGYxOGS42QlmYj6Mrq1LPw== +xterm@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.61.tgz#a6c27d90a5314da51d80deeb32f3bd77f1e1c8f6" + integrity sha512-rJHpCc48GSpHnu0SSERynQ80D5ikvFVsqhv6JdmeONTrnAFRr134OglJRIpbi2YK8UPbV6F6Dfqm/AQh+9GZzA== diff --git a/remote/yarn.lock b/remote/yarn.lock index e222314587d..4716df355d5 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -877,45 +877,45 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -xterm-addon-canvas@0.5.0-beta.9: - version "0.5.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.9.tgz#d4a9536cf586f78a54527751e03abf6445613886" - integrity sha512-AMyFctHbIWx0aLcACINuZqFFNoz4ndGtIAb4pQguIl9t8r+2otiV11MY4FJmPM0kUzEzoLWzVFJaGxOzykCWuw== +xterm-addon-canvas@0.5.0-beta.22: + version "0.5.0-beta.22" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.22.tgz#513f0c2b7cf96073f47627b27e8965c1b1a22431" + integrity sha512-9F6ZI0DMRgffVfHkLkDwl5n8VscvCaV10tWI3skXOX7Y7Aws6OEeglkOPoU3IllofCU792kHKM4pPoToUxTltg== -xterm-addon-image@0.6.0-beta.2: - version "0.6.0-beta.2" - resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.2.tgz#04c5ea11c89032b01b577b37f891109168ed0b09" - integrity sha512-58d1mqIpJwq8Zy/a/QM8JVuA1g5SceG8UvLoj9T6r+2XIktka6GK2oS66Fmo+0MP0s0HDPy+yJtl8lHY6UyzHw== +xterm-addon-image@0.6.0-beta.14: + version "0.6.0-beta.14" + resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.14.tgz#75fc3f824123183a4bbb5306e22f8b2c6966b0a6" + integrity sha512-D5Gh5JTKhHaPt1KwQNf6diF37KA4eToJw3XId1wy62tWmSqfq+QflhOGTfd+SnSQYCktU05ETzM+0tncIU62pQ== -xterm-addon-search@0.13.0-beta.8: - version "0.13.0-beta.8" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.8.tgz#90bc70bff87cd7e4f540cce51d9f968f04d5c0ef" - integrity sha512-Hlocg6gGvKAs4eRTW78wTtVqaOEurweJjdyPDjr7KrzwlEEsASsUXJaB2+vgsyTFKuYnCuLrp5u369jck993GQ== +xterm-addon-search@0.13.0-beta.20: + version "0.13.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.20.tgz#8ddd0513e2a70fcefa325722100d2e1bfaf3b9cb" + integrity sha512-wrx6187cJ1UenGL6ZeYv3jFvRPhhENTfbC+Hv1Fnww8LmsKhcj+0+Pm6yInNjX/9hNVsNzdqKyqNeEMoykyoyA== -xterm-addon-serialize@0.11.0-beta.8: - version "0.11.0-beta.8" - resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.11.0-beta.8.tgz#343357aad7c549a37aacac2fb19692b1c2fd69cd" - integrity sha512-1jNrX+Y8dorWtjMvz02mRUP+ahqQ4STO0lYlKe8m06p+NYuFk24CylnPZFuBgk91OUU3RAdl4glaKh5M4f0/Zw== +xterm-addon-serialize@0.11.0-beta.20: + version "0.11.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.11.0-beta.20.tgz#e879b34d214761403f1081833f9221c6903bf0c3" + integrity sha512-OXnC1SATaz7kEFjFWhyv9MJaXi8yHdPjazpGLNi11h33CRTKtCQiqqPBHU87dztnXmpEX6Jw0/jr3zlyXuAmnw== -xterm-addon-unicode11@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.5.0.tgz#41c0d96acc1e3bb6c6596eee64e163b6bca74be7" - integrity sha512-Jm4/g4QiTxiKiTbYICQgC791ubhIZyoIwxAIgOW8z8HWFNY+lwk+dwaKEaEeGBfM48Vk8fklsUW9u/PlenYEBg== +xterm-addon-unicode11@0.6.0-beta.12: + version "0.6.0-beta.12" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.12.tgz#ac6df9d635325dc692e4c602e74a2fc27a09405c" + integrity sha512-9wWWf/5nFafYgq0pn9EgAWnXaXGleVxfjNOqavpLRYFv0nw42QbaYyGvnGcxyYHM5Aqx/8rYE/DDVWZBqQZdYA== -xterm-addon-webgl@0.16.0-beta.16: - version "0.16.0-beta.16" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.16.tgz#2c31308f8c7f636576720adca529297f8fff3224" - integrity sha512-k0ZSwpBVtxXaqUc29CmlfFgIK7LEYAmwcDC3QVp2ESZo2JHYuQrWFpImjbzbYu0ON6qqcfbX8SnbzRid/XfGUg== +xterm-addon-webgl@0.16.0-beta.30: + version "0.16.0-beta.30" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.30.tgz#820d5c65f868b14ec4177bfb8a294931a53616bf" + integrity sha512-39qPHPFmNENxcHf8/CzGHS6wzKMMegoRkHB1+scqtBhSxFaD8tX5Ye33HZIEdQ9nXe9xtr4FWVp77T+n9hdrew== -xterm-headless@5.3.0-beta.46: - version "5.3.0-beta.46" - resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.3.0-beta.46.tgz#3f941f673e3c61aad2705e4b34b42fbe467aed48" - integrity sha512-e/VbZKrfyD1TTxOY5/jah3dUih6q8nTO5v5GQV7YOASp+yyI0XHKiDjLrCyFPQOLTKxCcRutMHvr+CoCcPpcHg== +xterm-headless@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.3.0-beta.61.tgz#28654550cb572709b99ea3eb8672d4568ae141c9" + integrity sha512-yfkbPLUtKjE4K7DsZ204A1BuOKpu6Usqi6rIYWT4XRMi+LjnkTbBjGr2BSjyJ3Gmtm+cSgBD0SvRN+V3xNxbxA== -xterm@5.3.0-beta.46: - version "5.3.0-beta.46" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.46.tgz#9bd2b2a588c88ae64f1989ca3bf5bd9116554b5a" - integrity sha512-keB3C6sXm56ug1+hylAQiNyZP4YtPgd2W+Gu/ZKwJMk5haD25DEnenBYL++Cl3+sNGYxOGS42QlmYj6Mrq1LPw== +xterm@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.61.tgz#a6c27d90a5314da51d80deeb32f3bd77f1e1c8f6" + integrity sha512-rJHpCc48GSpHnu0SSERynQ80D5ikvFVsqhv6JdmeONTrnAFRr134OglJRIpbi2YK8UPbV6F6Dfqm/AQh+9GZzA== yallist@^4.0.0: version "4.0.0" diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index c89c6a7a063..9445c64286a 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -705,6 +705,7 @@ class BranchNode implements ISplitView, IDisposable { this.splitviewSashResetDisposable.dispose(); this.childrenSashResetDisposable.dispose(); this.childrenChangeDisposable.dispose(); + this.onDidScrollDisposable.dispose(); this.splitview.dispose(); } } diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index b822db43751..28f18d42537 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -565,11 +565,11 @@ export class SplitView extends Disposable { this.sashContainer = append(this.el, $('.sash-container')); this.viewContainer = $('.split-view-container'); - this.scrollable = new Scrollable({ + this.scrollable = this._register(new Scrollable({ forceIntegerValues: true, smoothScrollDuration: 125, scheduleAtNextAnimationFrame - }); + })); this.scrollableElement = this._register(new SmoothScrollableElement(this.viewContainer, { vertical: this.orientation === Orientation.VERTICAL ? (options.scrollbarVisibility ?? ScrollbarVisibility.Auto) : ScrollbarVisibility.Hidden, horizontal: this.orientation === Orientation.HORIZONTAL ? (options.scrollbarVisibility ?? ScrollbarVisibility.Auto) : ScrollbarVisibility.Hidden diff --git a/src/vs/base/browser/ui/toolbar/toolbar.ts b/src/vs/base/browser/ui/toolbar/toolbar.ts index 1a6089b5958..bcb90361b41 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.ts +++ b/src/vs/base/browser/ui/toolbar/toolbar.ts @@ -52,7 +52,7 @@ export class ToolBar extends Disposable { private _onDidChangeDropdownVisibility = this._register(new EventMultiplexer()); readonly onDidChangeDropdownVisibility = this._onDidChangeDropdownVisibility.event; - private disposables = new DisposableStore(); + private disposables = this._register(new DisposableStore()); constructor(container: HTMLElement, contextMenuProvider: IContextMenuProvider, options: IToolBarOptions = { orientation: ActionsOrientation.HORIZONTAL }) { super(); diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 3591193bab9..70199a8164c 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1218,7 +1218,7 @@ export interface IAbstractTreeOptions extends IAbstractTr readonly collapseByDefault?: boolean; // defaults to false readonly filter?: ITreeFilter; readonly dnd?: ITreeDragAndDrop; - readonly additionalScrollHeight?: number; + readonly paddingBottom?: number; readonly findWidgetEnabled?: boolean; readonly findWidgetStyles?: IFindWidgetStyles; readonly defaultFindVisibility?: TreeVisibility | ((e: T) => TreeVisibility); diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index a54c2c59f9c..22c2859f5e9 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -707,6 +707,8 @@ export function tieBreakComparators(...comparators: Comparator[]): */ export const numberComparator: Comparator = (a, b) => a - b; +export const booleanComparator: Comparator = (a, b) => numberComparator(a ? 1 : 0, b ? 1 : 0); + export function reverseOrder(comparator: Comparator): Comparator { return (a, b) => -comparator(a, b); } @@ -754,6 +756,21 @@ export function findMinBy(items: readonly T[], comparator: Comparator): T return findMaxBy(items, (a, b) => -comparator(a, b)); } +export function findMaxIdxBy(items: readonly T[], comparator: Comparator): number { + if (items.length === 0) { + return -1; + } + + let maxIdx = 0; + for (let i = 1; i < items.length; i++) { + const item = items[i]; + if (comparator(item, items[maxIdx]) > 0) { + maxIdx = i; + } + } + return maxIdx; +} + export class ArrayQueue { private firstIdx = 0; private lastIdx = this.items.length - 1; diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index e00f3d59653..152a6af7e4e 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -682,6 +682,31 @@ export class Queue extends Limiter { } } +/** + * Same as `Queue`, ensures that only 1 task is executed at the same time. The difference to `Queue` is that + * there is only 1 task about to be scheduled next. As such, calling `queue` while a task is executing will + * replace the currently queued task until it executes. + * + * As such, the returned promise may not be from the factory that is passed in but from the next factory that + * is running after having called `queue`. + */ +export class LimitedQueue { + + private readonly sequentializer = new TaskSequentializer(); + + private tasks = 0; + + queue(factory: ITask>): Promise { + if (!this.sequentializer.isRunning()) { + return this.sequentializer.run(this.tasks++, factory()); + } + + return this.sequentializer.queue(() => { + return this.sequentializer.run(this.tasks++, factory()); + }); + } +} + /** * A helper to organize queues per resource. The ResourceQueue makes sure to manage queues per resource * by disposing them once the queue is empty. @@ -1267,87 +1292,92 @@ export async function retry(task: ITask>, delay: number, retries: //#region Task Sequentializer -interface IPendingTask { +interface IRunningTask { readonly taskId: number; readonly cancel: () => void; readonly promise: Promise; } -interface INextTask { +interface IQueuedTask { readonly promise: Promise; readonly promiseResolve: () => void; readonly promiseReject: (error: Error) => void; - run: () => Promise; + run: ITask>; } -export interface ITaskSequentializerWithPendingTask { - readonly pending: Promise; +export interface ITaskSequentializerWithRunningTask { + readonly running: Promise; } -export interface ITaskSequentializerWithNextTask { - readonly next: INextTask; +export interface ITaskSequentializerWithQueuedTask { + readonly queued: IQueuedTask; } +/** + * @deprecated use `LimitedQueue` instead for an easier to use API + */ export class TaskSequentializer { - private _pending?: IPendingTask; - private _next?: INextTask; - - hasPending(taskId?: number): this is ITaskSequentializerWithPendingTask { - if (!this._pending) { - return false; - } + private _running?: IRunningTask; + private _queued?: IQueuedTask; + isRunning(taskId?: number): this is ITaskSequentializerWithRunningTask { if (typeof taskId === 'number') { - return this._pending.taskId === taskId; + return this._running?.taskId === taskId; } - return !!this._pending; + return !!this._running; } - get pending(): Promise | undefined { - return this._pending?.promise; + get running(): Promise | undefined { + return this._running?.promise; } - cancelPending(): void { - this._pending?.cancel(); + cancelRunning(): void { + this._running?.cancel(); } - setPending(taskId: number, promise: Promise, onCancel?: () => void,): Promise { - this._pending = { taskId, cancel: () => onCancel?.(), promise }; + run(taskId: number, promise: Promise, onCancel?: () => void,): Promise { + this._running = { taskId, cancel: () => onCancel?.(), promise }; - promise.then(() => this.donePending(taskId), () => this.donePending(taskId)); + promise.then(() => this.doneRunning(taskId), () => this.doneRunning(taskId)); return promise; } - private donePending(taskId: number): void { - if (this._pending && taskId === this._pending.taskId) { + private doneRunning(taskId: number): void { + if (this._running && taskId === this._running.taskId) { - // only set pending to done if the promise finished that is associated with that taskId - this._pending = undefined; + // only set running to done if the promise finished that is associated with that taskId + this._running = undefined; - // schedule the next task now that we are free if we have any - this.triggerNext(); + // schedule the queued task now that we are free if we have any + this.runQueued(); } } - private triggerNext(): void { - if (this._next) { - const next = this._next; - this._next = undefined; + private runQueued(): void { + if (this._queued) { + const queued = this._queued; + this._queued = undefined; - // Run next task and complete on the associated promise - next.run().then(next.promiseResolve, next.promiseReject); + // Run queued task and complete on the associated promise + queued.run().then(queued.promiseResolve, queued.promiseReject); } } - setNext(run: () => Promise): Promise { + /** + * Note: the promise to schedule as next run MUST itself call `run`. + * Otherwise, this sequentializer will report `false` for `isRunning` + * even when this task is running. Missing this detail means that + * suddenly multiple tasks will run in parallel. + */ + queue(run: ITask>): Promise { - // this is our first next task, so we create associated promise with it + // this is our first queued task, so we create associated promise with it // so that we can return a promise that completes when the task has // completed. - if (!this._next) { + if (!this._queued) { let promiseResolve: () => void; let promiseReject: (error: Error) => void; const promise = new Promise((resolve, reject) => { @@ -1355,7 +1385,7 @@ export class TaskSequentializer { promiseReject = reject; }); - this._next = { + this._queued = { run, promise, promiseResolve: promiseResolve!, @@ -1363,20 +1393,20 @@ export class TaskSequentializer { }; } - // we have a previous next task, just overwrite it + // we have a previous queued task, just overwrite it else { - this._next.run = run; + this._queued.run = run; } - return this._next.promise; + return this._queued.promise; } - hasNext(): this is ITaskSequentializerWithNextTask { - return !!this._next; + hasQueued(): this is ITaskSequentializerWithQueuedTask { + return !!this._queued; } async join(): Promise { - return this._next?.promise ?? this._pending?.promise; + return this._queued?.promise ?? this._running?.promise; } } diff --git a/src/vs/base/common/stream.ts b/src/vs/base/common/stream.ts index 9f1039c0e52..055558fc748 100644 --- a/src/vs/base/common/stream.ts +++ b/src/vs/base/common/stream.ts @@ -3,8 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationToken } from 'vs/base/common/cancellation'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; /** * The payload that flows in readable stream events. @@ -567,17 +568,16 @@ export interface IStreamListener { /** * Helper to listen to all events of a T stream in proper order. */ -export function listenStream(stream: ReadableStreamEvents, listener: IStreamListener): IDisposable { - let destroyed = false; +export function listenStream(stream: ReadableStreamEvents, listener: IStreamListener, token?: CancellationToken): void { stream.on('error', error => { - if (!destroyed) { + if (!token?.isCancellationRequested) { listener.onError(error); } }); stream.on('end', () => { - if (!destroyed) { + if (!token?.isCancellationRequested) { listener.onEnd(); } }); @@ -586,12 +586,10 @@ export function listenStream(stream: ReadableStreamEvents, listener: IStre // into flowing mode. As such it is important to // add this listener last (DO NOT CHANGE!) stream.on('data', data => { - if (!destroyed) { + if (!token?.isCancellationRequested) { listener.onData(data); } }); - - return toDisposable(() => destroyed = true); } /** diff --git a/src/vs/base/parts/ipc/node/ipc.mp.ts b/src/vs/base/parts/ipc/node/ipc.mp.ts index a7cfc538d5e..b1648d260d6 100644 --- a/src/vs/base/parts/ipc/node/ipc.mp.ts +++ b/src/vs/base/parts/ipc/node/ipc.mp.ts @@ -33,18 +33,35 @@ class Protocol implements IMessagePassingProtocol { } } +export interface IClientConnectionFilter { + + /** + * Allows to filter incoming messages to the + * server to handle them differently. + * + * @param e the message event to handle + * @returns `true` if the event was handled + * and should not be processed by the server. + */ + handledClientConnection(e: MessageEvent): boolean; +} + /** * An implementation of a `IPCServer` on top of MessagePort style IPC communication. * The clients register themselves via Electron Utility Process IPC transfer. */ export class Server extends IPCServer { - private static getOnDidClientConnect(): Event { + private static getOnDidClientConnect(filter?: IClientConnectionFilter): Event { assertType(isUtilityProcess(process), 'Electron Utility Process'); const onCreateMessageChannel = new Emitter(); - process.parentPort.on('message', (e: Electron.MessageEvent) => { + process.parentPort.on('message', (e: MessageEvent) => { + if (filter?.handledClientConnection(e)) { + return; + } + const port = firstOrDefault(e.ports); if (port) { onCreateMessageChannel.fire(port); @@ -66,8 +83,8 @@ export class Server extends IPCServer { }); } - constructor() { - super(Server.getOnDidClientConnect()); + constructor(filter?: IClientConnectionFilter) { + super(Server.getOnDidClientConnect(filter)); } } diff --git a/src/vs/base/test/common/async.test.ts b/src/vs/base/test/common/async.test.ts index 144c119389a..467708aa2c2 100644 --- a/src/vs/base/test/common/async.test.ts +++ b/src/vs/base/test/common/async.test.ts @@ -664,119 +664,119 @@ suite('Async', () => { }); suite('TaskSequentializer', () => { - test('pending basics', async function () { + test('execution basics', async function () { const sequentializer = new async.TaskSequentializer(); - assert.ok(!sequentializer.hasPending()); - assert.ok(!sequentializer.hasNext()); - assert.ok(!sequentializer.hasPending(2323)); - assert.ok(!sequentializer.pending); + assert.ok(!sequentializer.isRunning()); + assert.ok(!sequentializer.hasQueued()); + assert.ok(!sequentializer.isRunning(2323)); + assert.ok(!sequentializer.running); // pending removes itself after done - await sequentializer.setPending(1, Promise.resolve()); - assert.ok(!sequentializer.hasPending()); - assert.ok(!sequentializer.hasPending(1)); - assert.ok(!sequentializer.pending); - assert.ok(!sequentializer.hasNext()); + await sequentializer.run(1, Promise.resolve()); + assert.ok(!sequentializer.isRunning()); + assert.ok(!sequentializer.isRunning(1)); + assert.ok(!sequentializer.running); + assert.ok(!sequentializer.hasQueued()); // pending removes itself after done (use async.timeout) - sequentializer.setPending(2, async.timeout(1)); - assert.ok(sequentializer.hasPending()); - assert.ok(sequentializer.hasPending(2)); - assert.ok(!sequentializer.hasNext()); - assert.strictEqual(sequentializer.hasPending(1), false); - assert.ok(sequentializer.pending); + sequentializer.run(2, async.timeout(1)); + assert.ok(sequentializer.isRunning()); + assert.ok(sequentializer.isRunning(2)); + assert.ok(!sequentializer.hasQueued()); + assert.strictEqual(sequentializer.isRunning(1), false); + assert.ok(sequentializer.running); await async.timeout(2); - assert.strictEqual(sequentializer.hasPending(), false); - assert.strictEqual(sequentializer.hasPending(2), false); - assert.ok(!sequentializer.pending); + assert.strictEqual(sequentializer.isRunning(), false); + assert.strictEqual(sequentializer.isRunning(2), false); + assert.ok(!sequentializer.running); }); - test('pending and next (finishes instantly)', async function () { + test('executing and queued (finishes instantly)', async function () { const sequentializer = new async.TaskSequentializer(); let pendingDone = false; - sequentializer.setPending(1, async.timeout(1).then(() => { pendingDone = true; return; })); + sequentializer.run(1, async.timeout(1).then(() => { pendingDone = true; return; })); - // next finishes instantly - let nextDone = false; - const res = sequentializer.setNext(() => Promise.resolve(null).then(() => { nextDone = true; return; })); + // queued finishes instantly + let queuedDone = false; + const res = sequentializer.queue(() => Promise.resolve(null).then(() => { queuedDone = true; return; })); - assert.ok(sequentializer.hasNext()); + assert.ok(sequentializer.hasQueued()); await res; assert.ok(pendingDone); - assert.ok(nextDone); - assert.ok(!sequentializer.hasNext()); + assert.ok(queuedDone); + assert.ok(!sequentializer.hasQueued()); }); - test('pending and next (finishes after timeout)', async function () { + test('executing and queued (finishes after timeout)', async function () { const sequentializer = new async.TaskSequentializer(); let pendingDone = false; - sequentializer.setPending(1, async.timeout(1).then(() => { pendingDone = true; return; })); + sequentializer.run(1, async.timeout(1).then(() => { pendingDone = true; return; })); - // next finishes after async.timeout - let nextDone = false; - const res = sequentializer.setNext(() => async.timeout(1).then(() => { nextDone = true; return; })); + // queued finishes after async.timeout + let queuedDone = false; + const res = sequentializer.queue(() => async.timeout(1).then(() => { queuedDone = true; return; })); await res; assert.ok(pendingDone); - assert.ok(nextDone); - assert.ok(!sequentializer.hasNext()); + assert.ok(queuedDone); + assert.ok(!sequentializer.hasQueued()); }); - test('join (without next or pending)', async function () { + test('join (without executing or queued)', async function () { const sequentializer = new async.TaskSequentializer(); await sequentializer.join(); - assert.ok(!sequentializer.hasNext()); + assert.ok(!sequentializer.hasQueued()); }); - test('join (without next)', async function () { + test('join (without queued)', async function () { const sequentializer = new async.TaskSequentializer(); let pendingDone = false; - sequentializer.setPending(1, async.timeout(1).then(() => { pendingDone = true; return; })); + sequentializer.run(1, async.timeout(1).then(() => { pendingDone = true; return; })); await sequentializer.join(); assert.ok(pendingDone); - assert.ok(!sequentializer.hasPending()); + assert.ok(!sequentializer.isRunning()); }); - test('join (with next and pending)', async function () { + test('join (with executing and queued)', async function () { const sequentializer = new async.TaskSequentializer(); let pendingDone = false; - sequentializer.setPending(1, async.timeout(1).then(() => { pendingDone = true; return; })); + sequentializer.run(1, async.timeout(1).then(() => { pendingDone = true; return; })); - // next finishes after async.timeout - let nextDone = false; - sequentializer.setNext(() => async.timeout(1).then(() => { nextDone = true; return; })); + // queued finishes after async.timeout + let queuedDone = false; + sequentializer.queue(() => async.timeout(1).then(() => { queuedDone = true; return; })); await sequentializer.join(); assert.ok(pendingDone); - assert.ok(nextDone); - assert.ok(!sequentializer.hasPending()); - assert.ok(!sequentializer.hasNext()); + assert.ok(queuedDone); + assert.ok(!sequentializer.isRunning()); + assert.ok(!sequentializer.hasQueued()); }); - test('pending and multiple next (last one wins)', async function () { + test('executing and multiple queued (last one wins)', async function () { const sequentializer = new async.TaskSequentializer(); let pendingDone = false; - sequentializer.setPending(1, async.timeout(1).then(() => { pendingDone = true; return; })); + sequentializer.run(1, async.timeout(1).then(() => { pendingDone = true; return; })); - // next finishes after async.timeout + // queued finishes after async.timeout let firstDone = false; - const firstRes = sequentializer.setNext(() => async.timeout(2).then(() => { firstDone = true; return; })); + const firstRes = sequentializer.queue(() => async.timeout(2).then(() => { firstDone = true; return; })); let secondDone = false; - const secondRes = sequentializer.setNext(() => async.timeout(3).then(() => { secondDone = true; return; })); + const secondRes = sequentializer.queue(() => async.timeout(3).then(() => { secondDone = true; return; })); let thirdDone = false; - const thirdRes = sequentializer.setNext(() => async.timeout(4).then(() => { thirdDone = true; return; })); + const thirdRes = sequentializer.queue(() => async.timeout(4).then(() => { thirdDone = true; return; })); await Promise.all([firstRes, secondRes, thirdRes]); assert.ok(pendingDone); @@ -785,12 +785,12 @@ suite('Async', () => { assert.ok(thirdDone); }); - test('cancel pending', async function () { + test('cancel executing', async function () { const sequentializer = new async.TaskSequentializer(); let pendingCancelled = false; - sequentializer.setPending(1, async.timeout(1), () => pendingCancelled = true); - sequentializer.cancelPending(); + sequentializer.run(1, async.timeout(1), () => pendingCancelled = true); + sequentializer.cancelRunning(); assert.ok(pendingCancelled); }); @@ -1281,4 +1281,42 @@ suite('Async', () => { assert.strictEqual(worked, false); }); }); + + suite('LimitedQueue', () => { + + test('basics (with long running task)', async () => { + const limitedQueue = new async.LimitedQueue(); + + let counter = 0; + const promises = []; + for (let i = 0; i < 5; i++) { + promises.push(limitedQueue.queue(async () => { + counter = i; + await async.timeout(1); + })); + } + + await Promise.all(promises); + + // only the last task executed + assert.strictEqual(counter, 4); + }); + + test('basics (with sync running task)', async () => { + const limitedQueue = new async.LimitedQueue(); + + let counter = 0; + const promises = []; + for (let i = 0; i < 5; i++) { + promises.push(limitedQueue.queue(async () => { + counter = i; + })); + } + + await Promise.all(promises); + + // only the last task executed + assert.strictEqual(counter, 4); + }); + }); }); diff --git a/src/vs/base/test/common/stream.test.ts b/src/vs/base/test/common/stream.test.ts index 78c38d691a4..63d30530a95 100644 --- a/src/vs/base/test/common/stream.test.ts +++ b/src/vs/base/test/common/stream.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import { timeout } from 'vs/base/common/async'; import { bufferToReadable, VSBuffer } from 'vs/base/common/buffer'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { consumeReadable, consumeStream, isReadable, isReadableBufferedStream, isReadableStream, listenStream, newWriteableStream, peekReadable, peekStream, prefixedReadable, prefixedStream, Readable, ReadableStream, toReadable, toStream, transform } from 'vs/base/common/stream'; suite('Stream', () => { @@ -351,14 +352,16 @@ suite('Stream', () => { assert.strictEqual(end, true); }); - test('listenStream - dispose', () => { + test('listenStream - cancellation', () => { const stream = newWriteableStream(strings => strings.join()); let error = false; let end = false; let data = ''; - const disposable = listenStream(stream, { + const cts = new CancellationTokenSource(); + + listenStream(stream, { onData: d => { data = d; }, @@ -368,9 +371,9 @@ suite('Stream', () => { onEnd: () => { end = true; } - }); + }, cts.token); - disposable.dispose(); + cts.cancel(); stream.write('Hello'); assert.strictEqual(data, ''); diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index bd6fb95a75d..c6536298e05 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -162,24 +162,36 @@ export class CodeApplication extends Disposable { const isUrlFromWebview = (requestingUrl: string | undefined) => requestingUrl?.startsWith(`${Schemas.vscodeWebview}://`); + const allowedPermissionsInMainFrame = new Set( + this.productService.quality === 'stable' ? [] : ['media'] + ); + const allowedPermissionsInWebview = new Set([ 'clipboard-read', 'clipboard-sanitized-write', ]); - session.defaultSession.setPermissionRequestHandler((_webContents, permission /* 'media' | 'geolocation' | 'notifications' | 'midiSysex' | 'pointerLock' | 'fullscreen' | 'openExternal' */, callback, details) => { + session.defaultSession.setPermissionRequestHandler((_webContents, permission, callback, details) => { if (isUrlFromWebview(details.requestingUrl)) { return callback(allowedPermissionsInWebview.has(permission)); } + if (details.isMainFrame && details.securityOrigin === 'vscode-file://vscode-app/') { + return callback(allowedPermissionsInMainFrame.has(permission)); + } + return callback(false); }); - session.defaultSession.setPermissionCheckHandler((_webContents, permission /* 'media' */, _origin, details) => { + session.defaultSession.setPermissionCheckHandler((_webContents, permission, _origin, details) => { if (isUrlFromWebview(details.requestingUrl)) { return allowedPermissionsInWebview.has(permission); } + if (details.isMainFrame && details.securityOrigin === 'vscode-file://vscode-app/') { + return allowedPermissionsInMainFrame.has(permission); + } + return false; }); diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 3b823317303..4770e9ef0bd 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -15,7 +15,7 @@ import { whenDeleted, writeFileSync } from 'vs/base/node/pfs'; import { findFreePort } from 'vs/base/node/ports'; import { watchFileContents } from 'vs/platform/files/node/watcher/nodejs/nodejsWatcherLib'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; -import { buildHelpMessage, buildVersionMessage, OPTIONS } from 'vs/platform/environment/node/argv'; +import { buildHelpMessage, buildVersionMessage, NATIVE_CLI_COMMANDS, OPTIONS } from 'vs/platform/environment/node/argv'; import { addArg, parseCLIProcessArgv } from 'vs/platform/environment/node/argvHelper'; import { getStdinFilePath, hasStdinWithoutTty, readFromStdin, stdinDataListener } from 'vs/platform/environment/node/stdin'; import { createWaitMarkerFileSync } from 'vs/platform/environment/node/wait'; @@ -51,31 +51,33 @@ export async function main(argv: string[]): Promise { return; } - if (args.tunnel) { - if (!product.tunnelApplicationName) { - console.error(`'tunnel' command not supported in ${product.applicationName}`); - return; - } - const tunnelArgs = argv.slice(argv.indexOf('tunnel') + 1); // all arguments behind `tunnel` - return new Promise((resolve, reject) => { - let tunnelProcess: ChildProcess; - const stdio: StdioOptions = ['ignore', 'pipe', 'pipe']; - if (process.env['VSCODE_DEV']) { - tunnelProcess = spawn('cargo', ['run', '--', 'tunnel', ...tunnelArgs], { cwd: join(getAppRoot(), 'cli'), stdio }); - } else { - const appPath = process.platform === 'darwin' - // ./Contents/MacOS/Electron => ./Contents/Resources/app/bin/code-tunnel-insiders - ? join(dirname(dirname(process.execPath)), 'Resources', 'app') - : dirname(process.execPath); - const tunnelCommand = join(appPath, 'bin', `${product.tunnelApplicationName}${isWindows ? '.exe' : ''}`); - tunnelProcess = spawn(tunnelCommand, ['tunnel', ...tunnelArgs], { cwd: cwd(), stdio }); + for (const subcommand of NATIVE_CLI_COMMANDS) { + if (args[subcommand]) { + if (!product.tunnelApplicationName) { + console.error(`'${subcommand}' command not supported in ${product.applicationName}`); + return; } + const tunnelArgs = argv.slice(argv.indexOf(subcommand) + 1); // all arguments behind `tunnel` + return new Promise((resolve, reject) => { + let tunnelProcess: ChildProcess; + const stdio: StdioOptions = ['ignore', 'pipe', 'pipe']; + if (process.env['VSCODE_DEV']) { + tunnelProcess = spawn('cargo', ['run', '--', subcommand, ...tunnelArgs], { cwd: join(getAppRoot(), 'cli'), stdio }); + } else { + const appPath = process.platform === 'darwin' + // ./Contents/MacOS/Electron => ./Contents/Resources/app/bin/code-tunnel-insiders + ? join(dirname(dirname(process.execPath)), 'Resources', 'app') + : dirname(process.execPath); + const tunnelCommand = join(appPath, 'bin', `${product.tunnelApplicationName}${isWindows ? '.exe' : ''}`); + tunnelProcess = spawn(tunnelCommand, [subcommand, ...tunnelArgs], { cwd: cwd(), stdio }); + } - tunnelProcess.stdout!.pipe(process.stdout); - tunnelProcess.stderr!.pipe(process.stderr); - tunnelProcess.on('exit', resolve); - tunnelProcess.on('error', reject); - }); + tunnelProcess.stdout!.pipe(process.stdout); + tunnelProcess.stderr!.pipe(process.stderr); + tunnelProcess.on('exit', resolve); + tunnelProcess.on('error', reject); + }); + } } // Help diff --git a/src/vs/code/node/sharedProcess/contrib/voiceTranscriber.ts b/src/vs/code/node/sharedProcess/contrib/voiceTranscriber.ts new file mode 100644 index 00000000000..11299d0848e --- /dev/null +++ b/src/vs/code/node/sharedProcess/contrib/voiceTranscriber.ts @@ -0,0 +1,125 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from 'vs/base/common/event'; +import { MessagePortMain, MessageEvent } from 'vs/base/parts/sandbox/node/electronTypes'; +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IVoiceRecognitionService } from 'vs/platform/voiceRecognition/node/voiceRecognitionService'; +import { ILogService } from 'vs/platform/log/common/log'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { LimitedQueue } from 'vs/base/common/async'; + +export class VoiceTranscriptionManager extends Disposable { + + constructor( + private readonly onDidWindowConnectRaw: Event, + @IVoiceRecognitionService private readonly voiceRecognitionService: IVoiceRecognitionService, + @ILogService private readonly logService: ILogService + ) { + super(); + + this.registerListeners(); + } + + private registerListeners(): void { + this._register(this.onDidWindowConnectRaw(port => { + this._register(new VoiceTranscriber(port, this.voiceRecognitionService, this.logService)); + })); + } +} + +class VoiceTranscriber extends Disposable { + + private static MAX_DATA_LENGTH = 30 /* seconds */ * 16000 /* sampling rate */ * 16 /* bith depth */ * 1 /* channels */ / 8; + + private readonly transcriptionQueue = new LimitedQueue(); + + private data: Float32Array | undefined = undefined; + + constructor( + private readonly port: MessagePortMain, + private readonly voiceRecognitionService: IVoiceRecognitionService, + private readonly logService: ILogService + ) { + super(); + + this.registerListeners(); + } + + private registerListeners(): void { + this.logService.info(`[voice] transcriber: new connection`); + + const cts = new CancellationTokenSource(); + this._register(toDisposable(() => cts.dispose(true))); + + const requestHandler = (e: MessageEvent) => this.handleRequest(e, cts.token); + this.port.on('message', requestHandler); + this._register(toDisposable(() => this.port.off('message', requestHandler))); + + this.port.start(); + this._register(toDisposable(() => this.port.close())); + + this.port.on('close', () => { + this.logService.info(`[voice] transcriber: closed connection`); + + cts.dispose(true); + }); + } + + private async handleRequest(e: MessageEvent, cancellation: CancellationToken): Promise { + if (!(Array.isArray(e.data))) { + return; + } + + const newData: Float32Array[] = []; + for (const channelData of e.data) { + if (channelData instanceof Float32Array) { + newData.push(channelData); + } + } + + const dataCandidate = this.joinFloat32Arrays(this.data ? [this.data, ...newData] : newData); + + if (dataCandidate.length > VoiceTranscriber.MAX_DATA_LENGTH) { + this.logService.warn(`[voice] transcriber: refusing to accept more than 30s of audio data`); + return; + } + + this.data = dataCandidate; + + this.transcriptionQueue.queue(() => this.transcribe(cancellation)); + } + + private async transcribe(cancellation: CancellationToken): Promise { + if (cancellation.isCancellationRequested) { + return; + } + + const data = this.data?.slice(0); + if (!data) { + return; + } + + const result = await this.voiceRecognitionService.transcribe(data, cancellation); + + if (cancellation.isCancellationRequested) { + return; + } + + this.port.postMessage(result); + } + + private joinFloat32Arrays(float32Arrays: Float32Array[]): Float32Array { + const result = new Float32Array(float32Arrays.reduce((prev, curr) => prev + curr.length, 0)); + + let offset = 0; + for (const float32Array of float32Arrays) { + result.set(float32Array, offset); + offset += float32Array.length; + } + + return result; + } +} diff --git a/src/vs/code/node/sharedProcess/sharedProcessMain.ts b/src/vs/code/node/sharedProcess/sharedProcessMain.ts index f911b0da431..a81bedb9ab4 100644 --- a/src/vs/code/node/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/node/sharedProcess/sharedProcessMain.ts @@ -3,15 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/* eslint-disable local/code-layering, local/code-import-patterns */ import { hostname, release } from 'os'; +import { MessagePortMain, MessageEvent } from 'vs/base/parts/sandbox/node/electronTypes'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { combinedDisposable, Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; +import { firstOrDefault } from 'vs/base/common/arrays'; +import { Emitter } from 'vs/base/common/event'; import { ProxyChannel, StaticRouter } from 'vs/base/parts/ipc/common/ipc'; -import { Server as UtilityProcessMessagePortServer, once } from 'vs/base/parts/ipc/node/ipc.mp'; +import { IClientConnectionFilter, Server as UtilityProcessMessagePortServer, once } from 'vs/base/parts/ipc/node/ipc.mp'; import { CodeCacheCleaner } from 'vs/code/node/sharedProcess/contrib/codeCacheCleaner'; import { LanguagePackCachedDataCleaner } from 'vs/code/node/sharedProcess/contrib/languagePackCachedDataCleaner'; import { LocalizationsUpdater } from 'vs/code/node/sharedProcess/contrib/localizationsUpdater'; @@ -112,13 +114,18 @@ import { IRemoteSocketFactoryService, RemoteSocketFactoryService } from 'vs/plat import { RemoteConnectionType } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory'; import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService'; +import { IVoiceRecognitionService, VoiceRecognitionService } from 'vs/platform/voiceRecognition/node/voiceRecognitionService'; +import { VoiceTranscriptionManager } from 'vs/code/node/sharedProcess/contrib/voiceTranscriber'; +import { SharedProcessRawConnection, SharedProcessLifecycle } from 'vs/platform/sharedProcess/common/sharedProcess'; -class SharedProcessMain extends Disposable { +class SharedProcessMain extends Disposable implements IClientConnectionFilter { - private readonly server = this._register(new UtilityProcessMessagePortServer()); + private readonly server = this._register(new UtilityProcessMessagePortServer(this)); private lifecycleService: SharedProcessLifecycleService | undefined = undefined; + private readonly onDidWindowConnectRaw = this._register(new Emitter()); + constructor(private configuration: ISharedProcessConfiguration) { super(); @@ -138,7 +145,7 @@ class SharedProcessMain extends Disposable { } }; process.once('exit', onExit); - once(process.parentPort, 'vscode:electron-main->shared-process=exit', onExit); + once(process.parentPort, SharedProcessLifecycle.exit, onExit); } async init(): Promise { @@ -170,7 +177,8 @@ class SharedProcessMain extends Disposable { instantiationService.createInstance(LogsDataCleaner), instantiationService.createInstance(LocalizationsUpdater), instantiationService.createInstance(ExtensionsContributions), - instantiationService.createInstance(UserDataProfilesCleaner) + instantiationService.createInstance(UserDataProfilesCleaner), + instantiationService.createInstance(VoiceTranscriptionManager, this.onDidWindowConnectRaw.event) )); } @@ -351,6 +359,9 @@ class SharedProcessMain extends Disposable { // Remote Tunnel services.set(IRemoteTunnelService, new SyncDescriptor(RemoteTunnelService)); + // Voice Recognition + services.set(IVoiceRecognitionService, new SyncDescriptor(VoiceRecognitionService)); + return new InstantiationService(services); } @@ -426,6 +437,27 @@ class SharedProcessMain extends Disposable { logService.error(`[uncaught exception in sharedProcess]: ${message}`); }); } + + handledClientConnection(e: MessageEvent): boolean { + + // This filter on message port messages will look for + // attempts of a window to connect raw to the shared + // process to handle these connections separate from + // our IPC based protocol. + + if (e.data !== SharedProcessRawConnection.response) { + return false; + } + + const port = firstOrDefault(e.ports); + if (port) { + this.onDidWindowConnectRaw.fire(port); + + return true; + } + + return false; + } } export async function main(configuration: ISharedProcessConfiguration): Promise { @@ -434,12 +466,12 @@ export async function main(configuration: ISharedProcessConfiguration): Promise< // ready to accept message ports as client connections const sharedProcess = new SharedProcessMain(configuration); - process.parentPort.postMessage('vscode:shared-process->electron-main=ipc-ready'); + process.parentPort.postMessage(SharedProcessLifecycle.ipcReady); // await initialization and signal this back to electron-main await sharedProcess.init(); - process.parentPort.postMessage('vscode:shared-process->electron-main=init-done'); + process.parentPort.postMessage(SharedProcessLifecycle.initDone); } process.parentPort.once('message', (e: Electron.MessageEvent) => { diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index 0215f9031a6..b39b8f95ba6 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -198,6 +198,13 @@ class ElementPath { ); } + public static isChildOfOverflowGuard(path: Uint8Array): boolean { + return ( + path.length >= 1 + && path[0] === PartFingerprint.OverflowGuard + ); + } + public static isChildOfOverflowingContentWidgets(path: Uint8Array): boolean { return ( path.length >= 1 @@ -538,6 +545,11 @@ export class MouseTargetFactory { let result: IMouseTarget | null = null; + if (!ElementPath.isChildOfOverflowGuard(request.targetPath) && !ElementPath.isChildOfOverflowingContentWidgets(request.targetPath)) { + // We only render dom nodes inside the overflow guard or in the overflowing content widgets + result = result || request.fulfillUnknown(); + } + result = result || MouseTargetFactory._hitTestContentWidget(ctx, resolvedRequest); result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, resolvedRequest); result = result || MouseTargetFactory._hitTestMinimap(ctx, resolvedRequest); diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index ae6cfd542d3..1ea2dff1bb6 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -15,7 +15,7 @@ import { IRange, Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { IWordAtPosition } from 'vs/editor/common/core/wordHelper'; import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/editor/common/cursorEvents'; -import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { GlyphMarginLane, ICursorStateComputer, IIdentifiedSingleEditOperation, IModelDecoration, IModelDeltaDecoration, ITextModel, PositionAffinity } from 'vs/editor/common/model'; import { InjectedText } from 'vs/editor/common/modelLineProjectionData'; diff --git a/src/vs/editor/browser/services/editorWorkerService.ts b/src/vs/editor/browser/services/editorWorkerService.ts index 6757066169f..993fe8e813c 100644 --- a/src/vs/editor/browser/services/editorWorkerService.ts +++ b/src/vs/editor/browser/services/editorWorkerService.ts @@ -24,7 +24,7 @@ import { canceled, onUnexpectedError } from 'vs/base/common/errors'; import { UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; import { ILinesDiffComputerOptions, LineRangeMapping, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; import { LineRange } from 'vs/editor/common/core/lineRange'; diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.css b/src/vs/editor/browser/viewParts/lines/viewLines.css index 8fff7ae3155..fe686d3e441 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.css +++ b/src/vs/editor/browser/viewParts/lines/viewLines.css @@ -20,8 +20,8 @@ } .mtkoverflow { - background-color: var(--vscode-button-background, --vscode-editor-background); - color: var(--vscode-button-foreground, --vscode-editor-foreground); + background-color: var(--vscode-button-background, var(--vscode-editor-background)); + color: var(--vscode-button-foreground, var(--vscode-editor-foreground)); border-width: 1px; border-style: solid; border-color: var(--vscode-contrastBorder); diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 4eae29a335e..5588ae6f5ec 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -11,6 +11,7 @@ import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from 'vs/base/browser/ui/mouseCursor import { IBoundarySashes, ISashEvent, IVerticalSashLayoutProvider, Orientation, Sash, SashState } from 'vs/base/browser/ui/sash/sash'; import * as assert from 'vs/base/common/assert'; import { RunOnceScheduler } from 'vs/base/common/async'; +import { CancellationToken } from 'vs/base/common/cancellation'; import { Codicon } from 'vs/base/common/codicons'; import { Color } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -40,7 +41,7 @@ import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ISelection, Selection } from 'vs/editor/common/core/selection'; import { StringBuilder } from 'vs/editor/common/core/stringBuilder'; -import { IChange, ICharChange, IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange, ICharChange, IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; @@ -1186,7 +1187,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE ignoreTrimWhitespace: this._options.ignoreTrimWhitespace, maxComputationTimeMs: this._options.maxComputationTime, computeMoves: false, - }).then(result => { + }, CancellationToken.None).then(result => { if (currentToken === this._diffComputationToken && currentOriginalModel === this._originalEditor.getModel() && currentModifiedModel === this._modifiedEditor.getModel() diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts b/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts index d66333e1aec..32f45d85186 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts @@ -18,6 +18,7 @@ import { applyStyle } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; import { DiffReview } from 'vs/editor/browser/widget/diffReview'; import { EditorFontLigatures, EditorOption, IComputedEditorOptions } from 'vs/editor/common/config/editorOptions'; import { LineRange } from 'vs/editor/common/core/lineRange'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { LineRangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; @@ -163,7 +164,7 @@ class ViewModel extends Disposable { const groups = this.groups.get(); if (!groups || groups.length <= 1) { return; } subtransaction(tx, tx => { - this._currentGroupIdx.set((this._currentGroupIdx.get() + groups.length + delta) % groups.length, tx); + this._currentGroupIdx.set(OffsetRange.ofLength(groups.length).clipCyclic(this._currentGroupIdx.get() + delta), tx); this._currentElementIdx.set(0, tx); }); } @@ -175,7 +176,7 @@ class ViewModel extends Disposable { const group = this.currentGroup.get(); if (!group || group.lines.length <= 1) { return; } transaction(tx => { - this._currentElementIdx.set((this._currentElementIdx.get() + group.lines.length + delta) % group.lines.length, tx); + this._currentElementIdx.set(OffsetRange.ofLength(group.lines.length).clip(this._currentElementIdx.get() + delta), tx); }); } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/colors.ts b/src/vs/editor/browser/widget/diffEditorWidget2/colors.ts index 8c78445d74b..449e67f06f8 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/colors.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/colors.ts @@ -11,3 +11,9 @@ export const diffMoveBorder = registerColor( { dark: '#8b8b8b9c', light: '#8b8b8b9c', hcDark: '#8b8b8b9c', hcLight: '#8b8b8b9c', }, localize('diffEditor.move.border', 'The border color for text that got moved in the diff editor.') ); + +export const diffMoveBorderActive = registerColor( + 'diffEditor.moveActive.border', + { dark: '#FFA500', light: '#FFA500', hcDark: '#FFA500', hcLight: '#FFA500', }, + localize('diffEditor.moveActive.border', 'The active border color for text that got moved in the diff editor.') +); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts index 5d9af4098f9..9a4b5bcf094 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts @@ -5,14 +5,12 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IObservable, derived } from 'vs/base/common/observable'; -import { isDefined } from 'vs/base/common/types'; import { arrowRevertChange, diffAddDecoration, diffAddDecorationEmpty, diffDeleteDecoration, diffDeleteDecorationEmpty, diffLineAddDecorationBackground, diffLineAddDecorationBackgroundWithIndicator, diffLineDeleteDecorationBackground, diffLineDeleteDecorationBackgroundWithIndicator, diffWholeLineAddDecoration, diffWholeLineDeleteDecoration } from 'vs/editor/browser/widget/diffEditorWidget2/decorations'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; import { DiffEditorOptions } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions'; import { DiffEditorViewModel } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; import { MovedBlocksLinesPart } from 'vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines'; import { applyObservableDecorations } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; -import { LineRange } from 'vs/editor/common/core/lineRange'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { IModelDeltaDecoration } from 'vs/editor/common/model'; @@ -36,57 +34,48 @@ export class DiffEditorDecorations extends Disposable { return null; } - const currentMove = this._diffModel.read(reader)!.syncedMovedTexts.read(reader); + const movedTextToCompare = this._diffModel.read(reader)!.movedTextToCompare.read(reader); const renderIndicators = this._options.renderIndicators.read(reader); const showEmptyDecorations = this._options.showEmptyDecorations.read(reader); const originalDecorations: IModelDeltaDecoration[] = []; const modifiedDecorations: IModelDeltaDecoration[] = []; - for (const m of diff.mappings) { - const fullRangeOriginal = LineRange.subtract(m.lineRangeMapping.originalRange, currentMove?.lineRangeMapping.original) - .map(i => i.toInclusiveRange()).filter(isDefined); - for (const range of fullRangeOriginal) { - originalDecorations.push({ range, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); - } - - const fullRangeModified = LineRange.subtract(m.lineRangeMapping.modifiedRange, currentMove?.lineRangeMapping.modified) - .map(i => i.toInclusiveRange()).filter(isDefined); - for (const range of fullRangeModified) { - modifiedDecorations.push({ range, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground }); - } - - if (m.lineRangeMapping.modifiedRange.isEmpty || m.lineRangeMapping.originalRange.isEmpty) { - for (const range of fullRangeOriginal) { - originalDecorations.push({ range, options: diffWholeLineDeleteDecoration }); + if (!movedTextToCompare) { + for (const m of diff.mappings) { + if (!m.lineRangeMapping.originalRange.isEmpty) { + originalDecorations.push({ range: m.lineRangeMapping.originalRange.toInclusiveRange()!, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); } - for (const range of fullRangeModified) { - modifiedDecorations.push({ range, options: diffWholeLineAddDecoration }); + if (!m.lineRangeMapping.modifiedRange.isEmpty) { + modifiedDecorations.push({ range: m.lineRangeMapping.modifiedRange.toInclusiveRange()!, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground }); } - } else { - for (const i of m.lineRangeMapping.innerChanges || []) { - if (currentMove - && (currentMove.lineRangeMapping.original.intersect(new LineRange(i.originalRange.startLineNumber, i.originalRange.endLineNumber)) - || currentMove.lineRangeMapping.modified.intersect(new LineRange(i.modifiedRange.startLineNumber, i.modifiedRange.endLineNumber)))) { - continue; - } - // Don't show empty markers outside the line range - if (m.lineRangeMapping.originalRange.contains(i.originalRange.startLineNumber)) { - originalDecorations.push({ range: i.originalRange, options: (i.originalRange.isEmpty() && showEmptyDecorations) ? diffDeleteDecorationEmpty : diffDeleteDecoration }); + if (m.lineRangeMapping.modifiedRange.isEmpty || m.lineRangeMapping.originalRange.isEmpty) { + if (!m.lineRangeMapping.originalRange.isEmpty) { + originalDecorations.push({ range: m.lineRangeMapping.originalRange.toInclusiveRange()!, options: diffWholeLineDeleteDecoration }); } - if (m.lineRangeMapping.modifiedRange.contains(i.modifiedRange.startLineNumber)) { - modifiedDecorations.push({ range: i.modifiedRange, options: (i.modifiedRange.isEmpty() && showEmptyDecorations) ? diffAddDecorationEmpty : diffAddDecoration }); + if (!m.lineRangeMapping.modifiedRange.isEmpty) { + modifiedDecorations.push({ range: m.lineRangeMapping.modifiedRange.toInclusiveRange()!, options: diffWholeLineAddDecoration }); + } + } else { + for (const i of m.lineRangeMapping.innerChanges || []) { + // Don't show empty markers outside the line range + if (m.lineRangeMapping.originalRange.contains(i.originalRange.startLineNumber)) { + originalDecorations.push({ range: i.originalRange, options: (i.originalRange.isEmpty() && showEmptyDecorations) ? diffDeleteDecorationEmpty : diffDeleteDecoration }); + } + if (m.lineRangeMapping.modifiedRange.contains(i.modifiedRange.startLineNumber)) { + modifiedDecorations.push({ range: i.modifiedRange, options: (i.modifiedRange.isEmpty() && showEmptyDecorations) ? diffAddDecorationEmpty : diffAddDecoration }); + } } } - } - if (!m.lineRangeMapping.modifiedRange.isEmpty && this._options.shouldRenderRevertArrows.read(reader) && !currentMove) { - modifiedDecorations.push({ range: Range.fromPositions(new Position(m.lineRangeMapping.modifiedRange.startLineNumber, 1)), options: arrowRevertChange }); + if (!m.lineRangeMapping.modifiedRange.isEmpty && this._options.shouldRenderRevertArrows.read(reader) && !movedTextToCompare) { + modifiedDecorations.push({ range: Range.fromPositions(new Position(m.lineRangeMapping.modifiedRange.startLineNumber, 1)), options: arrowRevertChange }); + } } } - if (currentMove) { - for (const m of currentMove.changes) { + if (movedTextToCompare) { + for (const m of movedTextToCompare.changes) { const fullRangeOriginal = m.originalRange.toInclusiveRange(); if (fullRangeOriginal) { originalDecorations.push({ range: fullRangeOriginal, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); @@ -102,12 +91,13 @@ export class DiffEditorDecorations extends Disposable { } } } + const activeMovedText = this._diffModel.read(reader)!.activeMovedText.read(reader); for (const m of diff.movedTexts) { originalDecorations.push({ range: m.lineRangeMapping.original.toInclusiveRange()!, options: { description: 'moved', - blockClassName: 'movedOriginal', + blockClassName: 'movedOriginal' + (m === activeMovedText ? ' currentMove' : ''), blockPadding: [MovedBlocksLinesPart.movedCodeBlockPadding, 0, MovedBlocksLinesPart.movedCodeBlockPadding, MovedBlocksLinesPart.movedCodeBlockPadding], } }); @@ -115,7 +105,7 @@ export class DiffEditorDecorations extends Disposable { modifiedDecorations.push({ range: m.lineRangeMapping.modified.toInclusiveRange()!, options: { description: 'moved', - blockClassName: 'movedModified', + blockClassName: 'movedModified' + (m === activeMovedText ? ' currentMove' : ''), blockPadding: [4, 0, 4, 4], } }); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts index cce99a94271..877f79ce430 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts @@ -35,8 +35,8 @@ export class DiffEditorEditors extends Disposable { ) { super(); - this.original = this._createLeftHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.originalEditor || {}); - this.modified = this._createRightHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.modifiedEditor || {}); + this.original = this._register(this._createLeftHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.originalEditor || {})); + this.modified = this._register(this._createRightHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.modifiedEditor || {})); this._register(autorunHandleChanges({ createEmptyChangeSummary: () => ({} as IDiffEditorConstructionOptions), @@ -50,6 +50,8 @@ export class DiffEditorEditors extends Disposable { /** @description update editor options */ _options.editorOptions.read(reader); + this._options.renderSideBySide.read(reader); + this.modified.updateOptions(this._adjustOptionsForRightHandSide(reader, changeSummary)); this.original.updateOptions(this._adjustOptionsForLeftHandSide(reader, changeSummary)); })); @@ -93,7 +95,11 @@ export class DiffEditorEditors extends Disposable { result.wordWrapOverride1 = 'off'; result.wordWrapOverride2 = 'off'; result.stickyScroll = { enabled: false }; + + // Disable unicode highlighting for the original side in inline mode, as they are not shown anyway. + result.unicodeHighlight = { nonBasicASCII: false, ambiguousCharacters: false, invisibleCharacters: false }; } else { + result.unicodeHighlight = this._options.editorOptions.get().unicodeHighlight; result.wordWrapOverride1 = this._options.diffWordWrap.get(); } if (changedOptions.originalAriaLabel) { diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index 448ccb5b27e..a41ba6a9909 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -4,20 +4,22 @@ *--------------------------------------------------------------------------------------------*/ import { RunOnceScheduler } from 'vs/base/common/async'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IObservable, IReader, ISettableObservable, ITransaction, autorunWithStore, derived, observableSignal, observableSignalFromEvent, observableValue, transaction, waitForState } from 'vs/base/common/observable'; import { isDefined } from 'vs/base/common/types'; import { ISerializedLineRange, LineRange } from 'vs/editor/common/core/lineRange'; import { Range } from 'vs/editor/common/core/range'; import { IDocumentDiff, IDocumentDiffProvider } from 'vs/editor/common/diff/documentDiffProvider'; import { LineRangeMapping, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -import { lineRangeMappingFromRangeMappings } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { AdvancedLinesDiffComputer, lineRangeMappingFromRangeMappings } from 'vs/editor/common/diff/advancedLinesDiffComputer'; import { IDiffEditorModel, IDiffEditorViewModel } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { TextEditInfo } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper'; import { combineTextEditInfos } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos'; import { lengthAdd, lengthDiffNonNegative, lengthGetLineCount, lengthOfRange, lengthToPosition, lengthZero, positionToLength } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length'; import { DiffEditorOptions } from './diffEditorOptions'; +import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; export class DiffEditorViewModel extends Disposable implements IDiffEditorViewModel { private readonly _isDiffUpToDate = observableValue('isDiffUpToDate', false); @@ -47,7 +49,23 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo } ); - public readonly syncedMovedTexts = observableValue('syncedMovedText', undefined); + public readonly movedTextToCompare = observableValue('movedTextToCompare', undefined); + + private readonly _activeMovedText = observableValue('activeMovedText', undefined); + private readonly _hoveredMovedText = observableValue('hoveredMovedText', undefined); + + + public readonly activeMovedText = derived(r => this.movedTextToCompare.read(r) ?? this._hoveredMovedText.read(r) ?? this._activeMovedText.read(r)); + + public setActiveMovedText(movedText: MovedText | undefined): void { + this._activeMovedText.set(movedText, undefined); + } + + public setHoveredMovedText(movedText: MovedText | undefined): void { + this._hoveredMovedText.set(movedText, undefined); + } + + private readonly _cancellationTokenSource = new CancellationTokenSource(); constructor( public readonly model: IDiffEditorModel, @@ -56,6 +74,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo ) { super(); + this._register(toDisposable(() => this._cancellationTokenSource.cancel())); + const contentChangedSignal = observableSignal('contentChangedSignal'); const debouncer = this._register(new RunOnceScheduler(() => contentChangedSignal.trigger(undefined), 200)); @@ -113,8 +133,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo transaction(tx => { this._diff.set(DiffState.fromDiffResult(this._lastDiff!), tx); updateUnchangedRegions(result, tx); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); + const currentSyncedMovedText = this.movedTextToCompare.get(); + this.movedTextToCompare.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); }); } } @@ -131,8 +151,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo transaction(tx => { this._diff.set(DiffState.fromDiffResult(this._lastDiff!), tx); updateUnchangedRegions(result, tx); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); + const currentSyncedMovedText = this.movedTextToCompare.get(); + this.movedTextToCompare.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); }); } } @@ -147,6 +167,7 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo debouncer.cancel(); contentChangedSignal.read(reader); documentDiffProviderOptionChanged.read(reader); + readHotReloadableExport(AdvancedLinesDiffComputer, reader); this._isDiffUpToDate.set(false, undefined); @@ -166,7 +187,11 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo ignoreTrimWhitespace: this._options.ignoreTrimWhitespace.read(reader), maxComputationTimeMs: this._options.maxComputationTimeMs.read(reader), computeMoves: this._options.showMoves.read(reader), - }); + }, this._cancellationTokenSource.token); + + if (this._cancellationTokenSource.token.isCancellationRequested) { + return; + } result = applyOriginalEdits(result, originalTextEditInfos, model.original, model.modified) ?? result; result = applyModifiedEdits(result, modifiedTextEditInfos, model.original, model.modified) ?? result; @@ -178,8 +203,8 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo const state = DiffState.fromDiffResult(result); this._diff.set(state, tx); this._isDiffUpToDate.set(true, tx); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); + const currentSyncedMovedText = this.movedTextToCompare.get(); + this.movedTextToCompare.set(currentSyncedMovedText ? this._lastDiff.moves.find(m => m.lineRangeMapping.modified.intersect(currentSyncedMovedText.lineRangeMapping.modified)) : undefined, tx); }); })); } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts index d312eb5629a..7421abcd386 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Codicon } from 'vs/base/common/codicons'; +import { KeyCode } from 'vs/base/common/keyCodes'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction2, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { findFocusedDiffEditor } from 'vs/editor/browser/widget/diffEditor.contribution'; @@ -91,14 +92,10 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { ) }); -/* -TODO@hediet add this back once move detection is more polished. -Users can still enable this via settings.json (config.diffEditor.experimental.showMoves). - MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: new ToggleShowMovedCodeBlocks().desc.id, - title: localize('showMoves', "Show Moves"), + title: localize('showMoves', "Show Moved Code Blocks"), icon: Codicon.move, toggled: ContextKeyEqualsExpr.create('config.diffEditor.experimental.showMoves', true), }, @@ -106,7 +103,6 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { group: '1_diff', when: ContextKeyEqualsExpr.create('diffEditorVersion', 2) }); -*/ const diffEditorCategory: ILocalizedString = { value: localize('diffEditor', 'Diff Editor'), @@ -133,3 +129,29 @@ export class SwitchSide extends EditorAction2 { } registerAction2(SwitchSide); + +export class ExitCompareMove extends EditorAction2 { + constructor() { + super({ + id: 'diffEditor.exitCompareMove', + title: { value: localize('exitCompareMove', "Exit Compare Move"), original: 'Exit Compare Move' }, + icon: Codicon.close, + precondition: EditorContextKeys.comparingMovedCode, + f1: false, + category: diffEditorCategory, + keybinding: { + weight: 10000, + primary: KeyCode.Escape, + } + }); + } + + runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, ...args: unknown[]): void { + const diffEditor = findFocusedDiffEditor(accessor); + if (diffEditor instanceof DiffEditorWidget2) { + diffEditor.exitCompareMove(); + } + } +} + +registerAction2(ExitCompareMove); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 21b5f67aaae..b8c42ae717f 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -30,7 +30,7 @@ import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { CursorChangeReason } from 'vs/editor/common/cursorEvents'; import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { EditorType, IDiffEditorModel, IDiffEditorViewModel, IDiffEditorViewState } from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IIdentifiedSingleEditOperation } from 'vs/editor/common/model'; @@ -79,6 +79,8 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { private readonly _options: DiffEditorOptions; private readonly _editors: DiffEditorEditors; + private readonly movedBlocksLinesPart = observableValue('MovedBlocksLinesPart', undefined); + constructor( private readonly _domElement: HTMLElement, options: Readonly, @@ -109,6 +111,12 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { isEmbeddedDiffEditorKey.set(this._options.isInEmbeddedEditor.read(reader)); })); + const comparingMovedCodeKey = EditorContextKeys.comparingMovedCode.bindTo(this._contextKeyService); + this._register(autorun(reader => { + /** @description update comparingMovedCodeKey */ + comparingMovedCodeKey.set(!!this._diffModel.read(reader)?.movedTextToCompare.read(reader)); + })); + const diffEditorRenderSideBySideInlineBreakpointReachedContextKeyValue = EditorContextKeys.diffEditorRenderSideBySideInlineBreakpointReached.bindTo(this._contextKeyService); this._register(autorun(reader => { /** @description update accessibleDiffViewerVisible context key */ @@ -149,7 +157,9 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._register(autorunWithStore((reader, store) => { /** @description UnchangedRangesFeature */ - this.unchangedRangesFeature = store.add(new (readHotReloadableExport(UnchangedRangesFeature, reader))(this._editors, this._diffModel, this._options)); + this.unchangedRangesFeature = store.add( + this._instantiationService.createInstance(readHotReloadableExport(UnchangedRangesFeature, reader), this._editors, this._diffModel, this._options) + ); })); this._register(autorunWithStore((reader, store) => { @@ -170,7 +180,9 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._register(autorunWithStore((reader, store) => { /** @description OverviewRulerPart */ - store.add(this._instantiationService.createInstance(readHotReloadableExport(OverviewRulerPart, reader), this._editors, + store.add(this._instantiationService.createInstance( + readHotReloadableExport(OverviewRulerPart, reader), + this._editors, this.elements.root, this._diffModel, this._rootSizeObserver.width, @@ -204,13 +216,15 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._register(keepAlive(this._layoutInfo, true)); - this._register(new MovedBlocksLinesPart( - this.elements.root, - this._diffModel, - this._layoutInfo.map(i => i.originalEditor), - this._layoutInfo.map(i => i.modifiedEditor), - this._editors, - )); + this._register(autorunWithStore((reader, store) => { + this.movedBlocksLinesPart.set(store.add(new (readHotReloadableExport(MovedBlocksLinesPart, reader))( + this.elements.root, + this._diffModel, + this._layoutInfo.map(i => i.originalEditor), + this._layoutInfo.map(i => i.modifiedEditor), + this._editors, + )), undefined); + })); this._register(applyStyle(this.elements.overlay, { width: this._layoutInfo.map((i, r) => i.originalEditor.width + (this._options.renderSideBySide.read(r) ? 0 : i.modifiedEditor.width)), @@ -219,19 +233,6 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { ), })); - this._register(this._editors.original.onDidChangeCursorPosition(e => { - const m = this._diffModel.get(); - if (!m) { return; } - const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.original.contains(e.position.lineNumber)); - m.syncedMovedTexts.set(movedText, undefined); - })); - this._register(this._editors.modified.onDidChangeCursorPosition(e => { - const m = this._diffModel.get(); - if (!m) { return; } - const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.modified.contains(e.position.lineNumber)); - m.syncedMovedTexts.set(movedText, undefined); - })); - // Revert change when an arrow is clicked. this._register(this._editors.modified.onMouseDown(event => { if (!event.event.rightButton && event.target.position && event.target.element?.className.includes('arrow-revert-change')) { @@ -285,13 +286,15 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { const originalWidth = sashLeft ?? Math.max(5, this._editors.original.getLayoutInfo().decorationsLeft); const modifiedWidth = width - originalWidth - (this._options.renderOverviewRuler.read(reader) ? OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH : 0); - this.elements.original.style.width = originalWidth + 'px'; + const movedBlocksLinesWidth = this.movedBlocksLinesPart.read(reader)?.width.read(reader) ?? 0; + const originalWidthWithoutMovedBlockLines = originalWidth - movedBlocksLinesWidth; + this.elements.original.style.width = originalWidthWithoutMovedBlockLines + 'px'; this.elements.original.style.left = '0px'; this.elements.modified.style.width = modifiedWidth + 'px'; this.elements.modified.style.left = originalWidth + 'px'; - this._editors.original.layout({ width: originalWidth, height }); + this._editors.original.layout({ width: originalWidthWithoutMovedBlockLines, height }); this._editors.modified.layout({ width: modifiedWidth, height }); return { @@ -512,6 +515,12 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { } destination.focus(); } + + exitCompareMove(): void { + const model = this._diffModel.get(); + if (!model) { return; } + model.movedTextToCompare.set(undefined, undefined); + } } function translatePosition(posInOriginal: Position, mappings: LineRangeMapping[]): Range { diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts b/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts index 92fb780d62c..56357753f62 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts @@ -103,7 +103,7 @@ export class ViewZoneManager extends Disposable { const alignmentsSyncedMovedText = derived((reader) => { /** @description alignments */ - const syncedMovedText = this._diffModel.read(reader)?.syncedMovedTexts.read(reader); + const syncedMovedText = this._diffModel.read(reader)?.movedTextToCompare.read(reader); if (!syncedMovedText) { return null; } state.read(reader); const mappings = syncedMovedText.changes.map(c => new DiffMapping(c)); @@ -171,7 +171,7 @@ export class ViewZoneManager extends Disposable { const modLineHeight = this._editors.modified.getOption(EditorOption.lineHeight); - const syncedMovedText = this._diffModel.read(reader)?.syncedMovedTexts.read(reader); + const syncedMovedText = this._diffModel.read(reader)?.movedTextToCompare.read(reader); const mightContainNonBasicASCII = this._editors.original.getModel()?.mightContainNonBasicASCII() ?? false; const mightContainRTL = this._editors.original.getModel()?.mightContainRTL() ?? false; @@ -265,7 +265,7 @@ export class ViewZoneManager extends Disposable { } else { const delta = a.modifiedHeightInPx - a.originalHeightInPx; if (delta > 0) { - if (syncedMovedText?.lineRangeMapping.original.contains(a.originalRange.endLineNumberExclusive - 1)) { + if (syncedMovedText?.lineRangeMapping.original.delta(-1).deltaLength(2).contains(a.originalRange.endLineNumberExclusive - 1)) { continue; } @@ -276,7 +276,7 @@ export class ViewZoneManager extends Disposable { showInHiddenAreas: true, }); } else { - if (syncedMovedText?.lineRangeMapping.modified.contains(a.modifiedRange.endLineNumberExclusive - 1)) { + if (syncedMovedText?.lineRangeMapping.modified.delta(-1).deltaLength(2).contains(a.modifiedRange.endLineNumberExclusive - 1)) { continue; } @@ -424,7 +424,7 @@ export class ViewZoneManager extends Disposable { this._register(autorun(reader => { /** @description update editor top offsets */ - const m = this._diffModel.read(reader)?.syncedMovedTexts.read(reader); + const m = this._diffModel.read(reader)?.movedTextToCompare.read(reader); let deltaOrigToMod = 0; if (m) { diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts index b4b628c711f..c4144924bce 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts @@ -3,17 +3,34 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable } from 'vs/base/common/lifecycle'; -import { IObservable, autorun, observableFromEvent, observableSignalFromEvent } from 'vs/base/common/observable'; +import { h } from 'vs/base/browser/dom'; +import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +import { Action } from 'vs/base/common/actions'; +import { booleanComparator, compareBy, findMaxIdxBy, numberComparator, tieBreakComparators } from 'vs/base/common/arrays'; +import { Codicon } from 'vs/base/common/codicons'; +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IObservable, autorun, autorunWithStore, constObservable, derived, derivedWithStore, keepAlive, observableFromEvent, observableSignalFromEvent, observableValue } from 'vs/base/common/observable'; +import { ThemeIcon } from 'vs/base/common/themables'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; import { DiffEditorViewModel } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; +import { PlaceholderViewZone, ViewZoneOverlayWidget, applyStyle, applyViewZones } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions'; import { LineRange } from 'vs/editor/common/core/lineRange'; +import { OffsetRange, OffsetRangeSet } from 'vs/editor/common/core/offsetRange'; +import { MovedText } from 'vs/editor/common/diff/linesDiffComputer'; +import { localize } from 'vs/nls'; export class MovedBlocksLinesPart extends Disposable { public static readonly movedCodeBlockPadding = 4; + private readonly _element: SVGElement; + private readonly _originalScrollTop = observableFromEvent(this._editors.original.onDidScrollChange, () => this._editors.original.getScrollTop()); + private readonly _modifiedScrollTop = observableFromEvent(this._editors.modified.onDidScrollChange, () => this._editors.modified.getScrollTop()); + private readonly _viewZonesChanged = observableSignalFromEvent('onDidChangeViewZones', this._editors.modified.onDidChangeViewZones); + + public readonly width = observableValue('width', 0); + constructor( private readonly _rootElement: HTMLElement, private readonly _diffModel: IObservable, @@ -23,9 +40,10 @@ export class MovedBlocksLinesPart extends Disposable { ) { super(); - const element = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - element.setAttribute('class', 'moved-blocks-lines'); - this._rootElement.appendChild(element); + this._element = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + this._element.setAttribute('class', 'moved-blocks-lines'); + this._rootElement.appendChild(this._element); + this._register(toDisposable(() => this._element.remove())); this._register(autorun(reader => { /** @description update moved blocks lines positioning */ @@ -35,58 +53,279 @@ export class MovedBlocksLinesPart extends Disposable { return; } - element.style.left = `${info.width - info.verticalScrollbarWidth}px`; - element.style.height = `${info.height}px`; - element.style.width = `${info.verticalScrollbarWidth + info.contentLeft - MovedBlocksLinesPart.movedCodeBlockPadding}px`; + this._element.style.left = `${info.width - info.verticalScrollbarWidth}px`; + this._element.style.height = `${info.height}px`; + this._element.style.width = `${info.verticalScrollbarWidth + info.contentLeft - MovedBlocksLinesPart.movedCodeBlockPadding + this.width.read(reader)}px`; })); - const originalScrollTop = observableFromEvent(this._editors.original.onDidScrollChange, () => this._editors.original.getScrollTop()); - const modifiedScrollTop = observableFromEvent(this._editors.modified.onDidScrollChange, () => this._editors.modified.getScrollTop()); - const viewZonesChanged = observableSignalFromEvent('onDidChangeViewZones', this._editors.modified.onDidChangeViewZones); + this._register(keepAlive(this._state, true)); - this._register(autorun(reader => { - element.replaceChildren(); + const movedBlockViewZones = derived(reader => { + const model = this._diffModel.read(reader); + const d = model?.diff.read(reader); + if (!d) { return []; } + return d.movedTexts.map(move => ({ + move, + original: new PlaceholderViewZone(constObservable(move.lineRangeMapping.original.startLineNumber - 1), 18), + modified: new PlaceholderViewZone(constObservable(move.lineRangeMapping.modified.startLineNumber - 1), 18), + })); + }); - /** @description update moved blocks lines */ - const moves = this._diffModel.read(reader)?.diff.read(reader)?.movedTexts; - if (!moves) { - return; + this._register(applyViewZones(this._editors.original, movedBlockViewZones.map(zones => zones.map(z => z.original)))); + this._register(applyViewZones(this._editors.modified, movedBlockViewZones.map(zones => zones.map(z => z.modified)))); + + this._register(autorunWithStore((reader, store) => { + const blocks = movedBlockViewZones.read(reader); + for (const b of blocks) { + store.add(new MovedBlockOverlayWidget(this._editors.original, b.original, b.move, 'original', this._diffModel.get()!)); + store.add(new MovedBlockOverlayWidget(this._editors.modified, b.modified, b.move, 'modified', this._diffModel.get()!)); } + })); - viewZonesChanged.read(reader); - - const info = this._originalEditorLayoutInfo.read(reader); - const info2 = this._modifiedEditorLayoutInfo.read(reader); - if (!info || !info2) { - return; + this._register(this._editors.original.onDidChangeCursorPosition(e => { + const m = this._diffModel.get(); + if (!m) { return; } + const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.original.contains(e.position.lineNumber)); + if (movedText !== m.movedTextToCompare.get()) { + m.movedTextToCompare.set(undefined, undefined); } - const width = info.verticalScrollbarWidth + info.contentLeft - MovedBlocksLinesPart.movedCodeBlockPadding; - - let idx = 0; - for (const m of moves) { - function computeLineStart(range: LineRange, editor: ICodeEditor) { - const t1 = editor.getTopForLineNumber(range.startLineNumber); - const t2 = editor.getTopForLineNumber(range.endLineNumberExclusive); - return (t1 + t2) / 2; - } - - const start = computeLineStart(m.lineRangeMapping.original, this._editors.original); - const startOffset = originalScrollTop.read(reader); - const end = computeLineStart(m.lineRangeMapping.modified, this._editors.modified); - const endOffset = modifiedScrollTop.read(reader); - - const top = start - startOffset; - const bottom = end - endOffset; - - const center = (width / 2) - moves.length * 5 + idx * 10; - idx++; - - const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', `M ${0} ${top} L ${center} ${top} L ${center} ${bottom} L ${width} ${bottom}`); - - path.setAttribute('fill', 'none'); - element.appendChild(path); + m.setActiveMovedText(movedText); + })); + this._register(this._editors.modified.onDidChangeCursorPosition(e => { + const m = this._diffModel.get(); + if (!m) { return; } + const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.modified.contains(e.position.lineNumber)); + if (movedText !== m.movedTextToCompare.get()) { + m.movedTextToCompare.set(undefined, undefined); } + m.setActiveMovedText(movedText); })); } + + private readonly _state = derivedWithStore('state', (reader, store) => { + /** @description update moved blocks lines */ + + this._element.replaceChildren(); + const model = this._diffModel.read(reader); + const moves = model?.diff.read(reader)?.movedTexts; + if (!moves || moves.length === 0) { + this.width.set(0, undefined); + return; + } + + this._viewZonesChanged.read(reader); + + const infoOrig = this._originalEditorLayoutInfo.read(reader); + const infoMod = this._modifiedEditorLayoutInfo.read(reader); + if (!infoOrig || !infoMod) { + this.width.set(0, undefined); + return; + } + + const lines = moves.map((move) => { + function computeLineStart(range: LineRange, editor: ICodeEditor) { + const t1 = editor.getTopForLineNumber(range.startLineNumber); + const t2 = editor.getTopForLineNumber(range.endLineNumberExclusive); + return (t1 + t2) / 2; + } + + const start = computeLineStart(move.lineRangeMapping.original, this._editors.original); + const startOffset = this._originalScrollTop.read(reader); + const end = computeLineStart(move.lineRangeMapping.modified, this._editors.modified); + const endOffset = this._modifiedScrollTop.read(reader); + + const from = start - startOffset; + const to = end - endOffset; + + const top = Math.min(start, end); + const bottom = Math.max(start, end); + + return { range: new OffsetRange(top, bottom), from, to, fromWithoutScroll: start, toWithoutScroll: end, move }; + }); + + lines.sort(tieBreakComparators( + compareBy(l => l.fromWithoutScroll > l.toWithoutScroll, booleanComparator), + compareBy(l => l.fromWithoutScroll > l.toWithoutScroll ? l.fromWithoutScroll : -l.toWithoutScroll, numberComparator) + )); + + const layout = LinesLayout.compute(lines.map(l => l.range)); + + const padding = 10; + const lineAreaLeft = infoOrig.verticalScrollbarWidth; + const lineAreaWidth = (layout.getTrackCount() - 1) * 10 + padding * 2; + const width = lineAreaLeft + lineAreaWidth + (infoMod.contentLeft - MovedBlocksLinesPart.movedCodeBlockPadding); + + let idx = 0; + for (const line of lines) { + const track = layout.getTrack(idx); + const verticalY = lineAreaLeft + padding + track * 10; + + const arrowHeight = 15; + const arrowWidth = 15; + const right = width; + + const rectWidth = infoMod.glyphMarginWidth + infoMod.lineNumbersWidth; + const rectHeight = 18; + const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + rect.classList.add('arrow-rectangle'); + rect.setAttribute('x', `${right - rectWidth}`); + rect.setAttribute('y', `${line.to - rectHeight / 2}`); + rect.setAttribute('width', `${rectWidth}`); + rect.setAttribute('height', `${rectHeight}`); + this._element.appendChild(rect); + + const g = document.createElementNS('http://www.w3.org/2000/svg', 'g'); + + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + + path.setAttribute('d', `M ${0} ${line.from} L ${verticalY} ${line.from} L ${verticalY} ${line.to} L ${right - arrowWidth} ${line.to}`); + path.setAttribute('fill', 'none'); + g.appendChild(path); + + const arrowRight = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); + arrowRight.classList.add('arrow'); + + store.add(autorun(reader => { + path.classList.toggle('currentMove', line.move === model.activeMovedText.read(reader)); + arrowRight.classList.toggle('currentMove', line.move === model.activeMovedText.read(reader)); + })); + + arrowRight.setAttribute('points', `${right - arrowWidth},${line.to - arrowHeight / 2} ${right},${line.to} ${right - arrowWidth},${line.to + arrowHeight / 2}`); + g.appendChild(arrowRight); + + this._element.appendChild(g); + + /* + TODO@hediet + path.addEventListener('mouseenter', () => { + model.setHoveredMovedText(line.move); + }); + path.addEventListener('mouseleave', () => { + model.setHoveredMovedText(undefined); + });*/ + + idx++; + } + + this.width.set(lineAreaWidth, undefined); + }); +} + +class LinesLayout { + public static compute(lines: OffsetRange[]): LinesLayout { + const setsPerTrack: OffsetRangeSet[] = []; + const trackPerLineIdx: number[] = []; + + for (const line of lines) { + let trackIdx = setsPerTrack.findIndex(set => !set.intersectsStrict(line)); + if (trackIdx === -1) { + const maxTrackCount = 6; + if (setsPerTrack.length >= maxTrackCount) { + trackIdx = findMaxIdxBy(setsPerTrack, compareBy(set => set.intersectWithRangeLength(line), numberComparator)); + } else { + trackIdx = setsPerTrack.length; + setsPerTrack.push(new OffsetRangeSet()); + } + } + setsPerTrack[trackIdx].addRange(line); + trackPerLineIdx.push(trackIdx); + } + + return new LinesLayout(setsPerTrack.length, trackPerLineIdx); + } + + private constructor( + private readonly _trackCount: number, + private readonly trackPerLineIdx: number[] + ) { } + + getTrack(lineIdx: number): number { + return this.trackPerLineIdx[lineIdx]; + } + + getTrackCount(): number { + return this._trackCount; + } +} + +class MovedBlockOverlayWidget extends ViewZoneOverlayWidget { + private readonly _nodes = h('div.diff-moved-code-block', { style: { marginRight: '4px' } }, [ + h('div.text-content@textContent'), + h('div.action-bar@actionBar'), + ]); + + constructor( + private readonly _editor: ICodeEditor, + _viewZone: PlaceholderViewZone, + private readonly _move: MovedText, + private readonly _kind: 'original' | 'modified', + private readonly _diffModel: DiffEditorViewModel, + ) { + const root = h('div.diff-hidden-lines-widget'); + super(_editor, _viewZone, root.root); + root.root.appendChild(this._nodes.root); + + const editorLayout = observableFromEvent(this._editor.onDidLayoutChange, () => this._editor.getLayoutInfo()); + + this._register(applyStyle(this._nodes.root, { + paddingRight: editorLayout.map(l => l.verticalScrollbarWidth) + })); + + let text: string; + + if (_move.changes.length > 0) { + text = this._kind === 'original' ? localize( + 'codeMovedToWithChanges', + 'Code moved with changes to line {0}-{1}', + this._move.lineRangeMapping.modified.startLineNumber, + this._move.lineRangeMapping.modified.endLineNumberExclusive + ) : localize( + 'codeMovedFromWithChanges', + 'Code moved with changes from line {0}-{1}', + this._move.lineRangeMapping.original.startLineNumber, + this._move.lineRangeMapping.original.endLineNumberExclusive + ); + } else { + text = this._kind === 'original' ? localize( + 'codeMovedTo', + 'Code moved to line {0}-{1}', + this._move.lineRangeMapping.modified.startLineNumber, + this._move.lineRangeMapping.modified.endLineNumberExclusive + ) : localize( + 'codeMovedFrom', + 'Code moved from line {0}-{1}', + this._move.lineRangeMapping.original.startLineNumber, + this._move.lineRangeMapping.original.endLineNumberExclusive + ); + } + + const actionBar = this._register(new ActionBar(this._nodes.actionBar, { + highlightToggledItems: true, + })); + + const caption = new Action( + '', + text, + '', + false, + ); + actionBar.push(caption, { icon: false, label: true }); + + const actionCompare = new Action( + '', + 'Compare', + ThemeIcon.asClassName(Codicon.compareChanges), + true, + () => { + this._editor.focus(); + this._diffModel.movedTextToCompare.set(this._diffModel.movedTextToCompare.get() ? undefined : this._move, undefined); + }, + ); + this._register(autorun(reader => { + const isActive = this._diffModel.movedTextToCompare.read(reader) === _move; + actionCompare.checked = isActive; + })); + + actionBar.push(actionCompare, { icon: false, label: true }); + } } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/outlineModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/outlineModel.ts new file mode 100644 index 00000000000..cd12277b82c --- /dev/null +++ b/src/vs/editor/browser/widget/diffEditorWidget2/outlineModel.ts @@ -0,0 +1,384 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { binarySearch, coalesceInPlace, equals } from 'vs/base/common/arrays'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { onUnexpectedExternalError } from 'vs/base/common/errors'; +import { Iterable } from 'vs/base/common/iterator'; +import { commonPrefixLength } from 'vs/base/common/strings'; +import { URI } from 'vs/base/common/uri'; +import { IPosition, Position } from 'vs/editor/common/core/position'; +import { IRange, Range } from 'vs/editor/common/core/range'; +import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; +import { DocumentSymbol, DocumentSymbolProvider } from 'vs/editor/common/languages'; +import { ITextModel } from 'vs/editor/common/model'; +import { MarkerSeverity } from 'vs/platform/markers/common/markers'; + +// TODO@hediet: These classes are copied from outlineModel.ts because of layering issues. +// Because these classes just depend on the DocumentSymbolProvider (which is in the core editor), +// they should be moved to the core editor as well. + +export abstract class TreeElement { + + abstract id: string; + abstract children: Map; + abstract parent: TreeElement | undefined; + + remove(): void { + this.parent?.children.delete(this.id); + } + + static findId(candidate: DocumentSymbol | string, container: TreeElement): string { + // complex id-computation which contains the origin/extension, + // the parent path, and some dedupe logic when names collide + let candidateId: string; + if (typeof candidate === 'string') { + candidateId = `${container.id}/${candidate}`; + } else { + candidateId = `${container.id}/${candidate.name}`; + if (container.children.get(candidateId) !== undefined) { + candidateId = `${container.id}/${candidate.name}_${candidate.range.startLineNumber}_${candidate.range.startColumn}`; + } + } + + let id = candidateId; + for (let i = 0; container.children.get(id) !== undefined; i++) { + id = `${candidateId}_${i}`; + } + + return id; + } + + static getElementById(id: string, element: TreeElement): TreeElement | undefined { + if (!id) { + return undefined; + } + const len = commonPrefixLength(id, element.id); + if (len === id.length) { + return element; + } + if (len < element.id.length) { + return undefined; + } + for (const [, child] of element.children) { + const candidate = TreeElement.getElementById(id, child); + if (candidate) { + return candidate; + } + } + return undefined; + } + + static size(element: TreeElement): number { + let res = 1; + for (const [, child] of element.children) { + res += TreeElement.size(child); + } + return res; + } + + static empty(element: TreeElement): boolean { + return element.children.size === 0; + } +} + +export interface IOutlineMarker { + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; + severity: MarkerSeverity; +} + +export class OutlineElement extends TreeElement { + + children = new Map(); + marker: { count: number; topSev: MarkerSeverity } | undefined; + + constructor( + readonly id: string, + public parent: TreeElement | undefined, + readonly symbol: DocumentSymbol + ) { + super(); + } +} + +export class OutlineGroup extends TreeElement { + + children = new Map(); + + constructor( + readonly id: string, + public parent: TreeElement | undefined, + readonly label: string, + readonly order: number, + ) { + super(); + } + + getItemEnclosingPosition(position: IPosition): OutlineElement | undefined { + return position ? this._getItemEnclosingPosition(position, this.children) : undefined; + } + + private _getItemEnclosingPosition(position: IPosition, children: Map): OutlineElement | undefined { + for (const [, item] of children) { + if (!item.symbol.range || !Range.containsPosition(item.symbol.range, position)) { + continue; + } + return this._getItemEnclosingPosition(position, item.children) || item; + } + return undefined; + } + + updateMarker(marker: IOutlineMarker[]): void { + for (const [, child] of this.children) { + this._updateMarker(marker, child); + } + } + + private _updateMarker(markers: IOutlineMarker[], item: OutlineElement): void { + item.marker = undefined; + + // find the proper start index to check for item/marker overlap. + const idx = binarySearch(markers, item.symbol.range, Range.compareRangesUsingStarts); + let start: number; + if (idx < 0) { + start = ~idx; + if (start > 0 && Range.areIntersecting(markers[start - 1], item.symbol.range)) { + start -= 1; + } + } else { + start = idx; + } + + const myMarkers: IOutlineMarker[] = []; + let myTopSev: MarkerSeverity | undefined; + + for (; start < markers.length && Range.areIntersecting(item.symbol.range, markers[start]); start++) { + // remove markers intersecting with this outline element + // and store them in a 'private' array. + const marker = markers[start]; + myMarkers.push(marker); + (markers as Array)[start] = undefined; + if (!myTopSev || marker.severity > myTopSev) { + myTopSev = marker.severity; + } + } + + // Recurse into children and let them match markers that have matched + // this outline element. This might remove markers from this element and + // therefore we remember that we have had markers. That allows us to render + // the dot, saying 'this element has children with markers' + for (const [, child] of item.children) { + this._updateMarker(myMarkers, child); + } + + if (myTopSev) { + item.marker = { + count: myMarkers.length, + topSev: myTopSev + }; + } + + coalesceInPlace(markers); + } +} + +export class OutlineModel extends TreeElement { + + static create(registry: LanguageFeatureRegistry, textModel: ITextModel, token: CancellationToken): Promise { + + const cts = new CancellationTokenSource(token); + const result = new OutlineModel(textModel.uri); + const provider = registry.ordered(textModel); + const promises = provider.map((provider, index) => { + + const id = TreeElement.findId(`provider_${index}`, result); + const group = new OutlineGroup(id, result, provider.displayName ?? 'Unknown Outline Provider', index); + + + return Promise.resolve(provider.provideDocumentSymbols(textModel, cts.token)).then(result => { + for (const info of result || []) { + OutlineModel._makeOutlineElement(info, group); + } + return group; + }, err => { + onUnexpectedExternalError(err); + return group; + }).then(group => { + if (!TreeElement.empty(group)) { + result._groups.set(id, group); + } else { + group.remove(); + } + }); + }); + + const listener = registry.onDidChange(() => { + const newProvider = registry.ordered(textModel); + if (!equals(newProvider, provider)) { + cts.cancel(); + } + }); + + return Promise.all(promises).then(() => { + if (cts.token.isCancellationRequested && !token.isCancellationRequested) { + return OutlineModel.create(registry, textModel, token); + } else { + return result._compact(); + } + }).finally(() => { + listener.dispose(); + }); + } + + private static _makeOutlineElement(info: DocumentSymbol, container: OutlineGroup | OutlineElement): void { + const id = TreeElement.findId(info, container); + const res = new OutlineElement(id, container, info); + if (info.children) { + for (const childInfo of info.children) { + OutlineModel._makeOutlineElement(childInfo, res); + } + } + container.children.set(res.id, res); + } + + static get(element: TreeElement | undefined): OutlineModel | undefined { + while (element) { + if (element instanceof OutlineModel) { + return element; + } + element = element.parent; + } + return undefined; + } + + readonly id = 'root'; + readonly parent = undefined; + + protected _groups = new Map(); + children = new Map(); + + protected constructor(readonly uri: URI) { + super(); + + this.id = 'root'; + this.parent = undefined; + } + + private _compact(): this { + let count = 0; + for (const [key, group] of this._groups) { + if (group.children.size === 0) { // empty + this._groups.delete(key); + } else { + count += 1; + } + } + if (count !== 1) { + // + this.children = this._groups; + } else { + // adopt all elements of the first group + const group = Iterable.first(this._groups.values())!; + for (const [, child] of group.children) { + child.parent = this; + this.children.set(child.id, child); + } + } + return this; + } + + merge(other: OutlineModel): boolean { + if (this.uri.toString() !== other.uri.toString()) { + return false; + } + if (this._groups.size !== other._groups.size) { + return false; + } + this._groups = other._groups; + this.children = other.children; + return true; + } + + getItemEnclosingPosition(position: IPosition, context?: OutlineElement): OutlineElement | undefined { + + let preferredGroup: OutlineGroup | undefined; + if (context) { + let candidate = context.parent; + while (candidate && !preferredGroup) { + if (candidate instanceof OutlineGroup) { + preferredGroup = candidate; + } + candidate = candidate.parent; + } + } + + let result: OutlineElement | undefined = undefined; + for (const [, group] of this._groups) { + result = group.getItemEnclosingPosition(position); + if (result && (!preferredGroup || preferredGroup === group)) { + break; + } + } + return result; + } + + getItemById(id: string): TreeElement | undefined { + return TreeElement.getElementById(id, this); + } + + updateMarker(marker: IOutlineMarker[]): void { + // sort markers by start range so that we can use + // outline element starts for quicker look up + marker.sort(Range.compareRangesUsingStarts); + + for (const [, group] of this._groups) { + group.updateMarker(marker.slice(0)); + } + } + + getTopLevelSymbols(): DocumentSymbol[] { + const roots: DocumentSymbol[] = []; + for (const child of this.children.values()) { + if (child instanceof OutlineElement) { + roots.push(child.symbol); + } else { + roots.push(...Iterable.map(child.children.values(), child => child.symbol)); + } + } + return roots.sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range)); + } + + asListOfDocumentSymbols(): DocumentSymbol[] { + const roots = this.getTopLevelSymbols(); + const bucket: DocumentSymbol[] = []; + OutlineModel._flattenDocumentSymbols(bucket, roots, ''); + return bucket.sort((a, b) => + Position.compare(Range.getStartPosition(a.range), Range.getStartPosition(b.range)) || Position.compare(Range.getEndPosition(b.range), Range.getEndPosition(a.range)) + ); + } + + private static _flattenDocumentSymbols(bucket: DocumentSymbol[], entries: DocumentSymbol[], overrideContainerLabel: string): void { + for (const entry of entries) { + bucket.push({ + kind: entry.kind, + tags: entry.tags, + name: entry.name, + detail: entry.detail, + containerName: entry.containerName || overrideContainerLabel, + range: entry.range, + selectionRange: entry.selectionRange, + children: undefined, // we flatten it... + }); + + // Recurse over children + if (entry.children) { + OutlineModel._flattenDocumentSymbols(bucket, entry.children, entry.name); + } + } + } +} diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/style.css b/src/vs/editor/browser/widget/diffEditorWidget2/style.css index f8243853b70..aa681f8f617 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/style.css +++ b/src/vs/editor/browser/widget/diffEditorWidget2/style.css @@ -78,6 +78,30 @@ border: 2px solid var(--vscode-diffEditor-move-border); } +.monaco-editor .movedOriginal.currentMove, .monaco-editor .movedModified.currentMove { + border: 2px solid var(--vscode-diffEditor-moveActive-border); +} + +.monaco-diff-editor .moved-blocks-lines path.currentMove { + stroke: var(--vscode-diffEditor-moveActive-border); +} + +.monaco-diff-editor .moved-blocks-lines path { + pointer-events: visiblestroke; +} + +.monaco-diff-editor .moved-blocks-lines .arrow { + fill: var(--vscode-diffEditor-move-border); +} + +.monaco-diff-editor .moved-blocks-lines .arrow.currentMove { + fill: var(--vscode-diffEditor-moveActive-border); +} + +.monaco-diff-editor .moved-blocks-lines .arrow-rectangle { + fill: var(--vscode-editor-background); +} + .monaco-diff-editor .moved-blocks-lines { position: absolute; pointer-events: none; @@ -101,3 +125,15 @@ .monaco-editor .fold-unchanged { cursor: pointer; } + +.monaco-diff-editor .diff-moved-code-block { + display: flex; + justify-content: flex-end; + margin-top: -4px; +} + +.monaco-diff-editor .diff-moved-code-block .action-bar .action-label.codicon { + width: 12px; + height: 12px; + font-size: 12px; +} diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts index 7272f56b11f..b3ac905331d 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts @@ -4,34 +4,49 @@ *--------------------------------------------------------------------------------------------*/ import { $, addDisposableListener, h, reset } from 'vs/base/browser/dom'; -import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; +import { renderIcon, renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; +import { compareBy, numberComparator, reverseOrder } from 'vs/base/common/arrays'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { Codicon } from 'vs/base/common/codicons'; +import { Event } from 'vs/base/common/event'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { Disposable } from 'vs/base/common/lifecycle'; -import { IObservable, autorun, derived, derivedWithStore, observableFromEvent, transaction } from 'vs/base/common/observable'; +import { IObservable, IReader, autorun, autorunWithStore, derived, derivedWithStore, observableFromEvent, observableSignalFromEvent, observableValue, transaction } from 'vs/base/common/observable'; import { ThemeIcon } from 'vs/base/common/themables'; import { isDefined } from 'vs/base/common/types'; import { ICodeEditor, IViewZone } from 'vs/editor/browser/editorBrowser'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; import { DiffEditorOptions } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions'; import { DiffEditorViewModel, UnchangedRegion } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; +import { OutlineModel } from 'vs/editor/browser/widget/diffEditorWidget2/outlineModel'; import { PlaceholderViewZone, ViewZoneOverlayWidget, applyObservableDecorations, applyStyle, applyViewZones } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { CursorChangeReason } from 'vs/editor/common/cursorEvents'; -import { IModelDecorationOptions, IModelDeltaDecoration } from 'vs/editor/common/model'; +import { SymbolKind, SymbolKinds } from 'vs/editor/common/languages'; +import { IModelDecorationOptions, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { localize } from 'vs/nls'; export class UnchangedRangesFeature extends Disposable { private _isUpdatingViewZones = false; public get isUpdatingViewZones(): boolean { return this._isUpdatingViewZones; } + private readonly _modifiedModel = observableFromEvent(this._editors.modified.onDidChangeModel, () => this._editors.modified.getModel()); + + private readonly _modifiedOutlineSource = derivedWithStore('modified outline source', (reader, store) => { + const m = this._modifiedModel.read(reader); + if (!m) { return undefined; } + return store.add(new OutlineSource(this._languageFeaturesService, m)); + }); + constructor( private readonly _editors: DiffEditorEditors, private readonly _diffModel: IObservable, private readonly _options: DiffEditorOptions, + @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService, ) { super(); @@ -66,6 +81,9 @@ export class UnchangedRangesFeature extends Disposable { const modViewZones: IViewZone[] = []; const sideBySide = this._options.renderSideBySide.read(reader); + const modifiedOutlineSource = this._modifiedOutlineSource.read(reader); + if (!modifiedOutlineSource) { return { origViewZones, modViewZones }; } + const curUnchangedRegions = unchangedRegions.read(reader); for (const r of curUnchangedRegions) { if (r.shouldHideControls(reader)) { @@ -76,13 +94,13 @@ export class UnchangedRangesFeature extends Disposable { const d = derived(reader => /** @description hiddenOriginalRangeStart */ r.getHiddenOriginalRange(reader).startLineNumber - 1); const origVz = new PlaceholderViewZone(d, 24); origViewZones.push(origVz); - store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, !sideBySide)); + store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, !sideBySide, modifiedOutlineSource)); } { const d = derived(reader => /** @description hiddenModifiedRangeStart */ r.getHiddenModifiedRange(reader).startLineNumber - 1); const modViewZone = new PlaceholderViewZone(d, 24); modViewZones.push(modViewZone); - store.add(new CollapsedCodeOverlayWidget(this._editors.modified, modViewZone, r, false)); + store.add(new CollapsedCodeOverlayWidget(this._editors.modified, modViewZone, r, false, modifiedOutlineSource)); } } @@ -177,6 +195,57 @@ export class UnchangedRangesFeature extends Disposable { } } +class DisposableCancellationTokenSource extends CancellationTokenSource { + public override dispose() { + super.dispose(true); + } +} + +class OutlineSource extends Disposable { + private readonly _currentModel = observableValue('current model', undefined); + + constructor( + @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService, + private readonly _textModel: ITextModel, + ) { + super(); + + const documentSymbolProviderChanged = observableSignalFromEvent( + 'documentSymbolProvider.onDidChange', + this._languageFeaturesService.documentSymbolProvider.onDidChange + ); + + const textModelChanged = observableSignalFromEvent( + '_textModel.onDidChangeContent', + Event.debounce(e => this._textModel.onDidChangeContent(e), () => undefined, 100) + ); + + this._register(autorunWithStore(async (reader, store) => { + documentSymbolProviderChanged.read(reader); + textModelChanged.read(reader); + + const src = store.add(new DisposableCancellationTokenSource()); + const model = await OutlineModel.create( + this._languageFeaturesService.documentSymbolProvider, + this._textModel, + src.token, + ); + if (store.isDisposed) { return; } + + this._currentModel.set(model, undefined); + })); + } + + public getBreadcrumbItems(startRange: LineRange, reader: IReader): { name: string; kind: SymbolKind }[] { + const m = this._currentModel.read(reader); + if (!m) { return []; } + const symbols = m.asListOfDocumentSymbols() + .filter(s => startRange.contains(s.range.startLineNumber) && !startRange.contains(s.range.endLineNumber)); + symbols.sort(reverseOrder(compareBy(s => s.range.endLineNumber - s.range.startLineNumber, numberComparator))); + return symbols.map(s => ({ name: s.name, kind: s.kind })); + } +} + class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { private readonly _nodes = h('div.diff-hidden-lines', [ h('div.top@top', { title: localize('diff.hiddenLines.top', 'Click or drag to show more above') }), @@ -194,6 +263,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { _viewZone: PlaceholderViewZone, private readonly _unchangedRegion: UnchangedRegion, private readonly hide: boolean, + private readonly _modifiedOutlineSource: OutlineSource, ) { const root = h('div.diff-hidden-lines-widget'); super(_editor, _viewZone, root.root); @@ -296,19 +366,25 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { children.push($('span', { title: linesHiddenText }, linesHiddenText)); } - // TODO@hediet implement breadcrumbs for collapsed regions - /* - if (_unchangedRegion.originalLineNumber === 48) { + const range = this._unchangedRegion.getHiddenModifiedRange(reader); + const items = this._modifiedOutlineSource.getBreadcrumbItems(range, reader); + + if (items.length > 0) { children.push($('span', undefined, '\u00a0|\u00a0')); - children.push($('span', { title: 'test' }, ...renderLabelWithIcons('$(symbol-class) DiffEditorWidget2'))); - } else if (_unchangedRegion.originalLineNumber === 88) { - children.push($('span', undefined, '\u00a0|\u00a0')); - children.push($('span', { title: 'test' }, ...renderLabelWithIcons('$(symbol-constructor) constructor'))); + + let isFirst = true; + for (const item of items) { + if (!isFirst) { + children.push($('span', {}, ' ', renderIcon(Codicon.chevronRight), ' ')); + } + + const icon = SymbolKinds.toIcon(item.kind); + children.push($('span', {}, renderIcon(icon), ' ', item.name)); + isFirst = false; + } } - */ reset(this._nodes.others, ...children); - })); } } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts b/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts index 9a86bfd448b..8460b24326e 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts @@ -268,6 +268,8 @@ export interface CSSStyle { top: number | string; visibility: 'visible' | 'hidden' | 'collapse'; display: 'block' | 'inline' | 'inline-block' | 'flex' | 'none'; + paddingLeft: number | string; + paddingRight: number | string; } export function applyStyle(domNode: HTMLElement, style: Partial<{ [TKey in keyof CSSStyle]: CSSStyle[TKey] | IObservable | undefined }>) { @@ -280,6 +282,7 @@ export function applyStyle(domNode: HTMLElement, style: Partial<{ [TKey in keyof if (typeof val === 'number') { val = `${val}px`; } + key = key.replace(/[A-Z]/g, m => '-' + m.toLowerCase()); domNode.style[key as any] = val as any; } }); diff --git a/src/vs/editor/browser/widget/diffNavigator.ts b/src/vs/editor/browser/widget/diffNavigator.ts index 0f34a1e5960..1edce99edf6 100644 --- a/src/vs/editor/browser/widget/diffNavigator.ts +++ b/src/vs/editor/browser/widget/diffNavigator.ts @@ -10,7 +10,7 @@ import * as objects from 'vs/base/common/objects'; import { IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { ICursorPositionChangedEvent } from 'vs/editor/common/cursorEvents'; import { Range } from 'vs/editor/common/core/range'; -import { ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; diff --git a/src/vs/editor/browser/widget/diffReview.ts b/src/vs/editor/browser/widget/diffReview.ts index ea813d85aa5..268d41d2f3b 100644 --- a/src/vs/editor/browser/widget/diffReview.ts +++ b/src/vs/editor/browser/widget/diffReview.ts @@ -19,7 +19,7 @@ import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget'; import { EditorFontLigatures, EditorOption, IComputedEditorOptions } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; -import { ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { ILanguageIdCodec } from 'vs/editor/common/languages'; import { ILanguageService } from 'vs/editor/common/languages/language'; diff --git a/src/vs/editor/browser/widget/media/diffEditor.css b/src/vs/editor/browser/widget/media/diffEditor.css index 66fa2b5ab83..6d086fe1031 100644 --- a/src/vs/editor/browser/widget/media/diffEditor.css +++ b/src/vs/editor/browser/widget/media/diffEditor.css @@ -81,7 +81,7 @@ } .monaco-editor .line-insert, .monaco-diff-editor .line-insert { - background-color: var(--vscode-diffEditor-insertedLineBackground, --vscode-diffEditor-insertedTextBackground); + background-color: var(--vscode-diffEditor-insertedLineBackground, var(--vscode-diffEditor-insertedTextBackground)); } .monaco-editor .line-insert, @@ -106,7 +106,7 @@ .monaco-editor .inline-added-margin-view-zone, .monaco-editor .gutter-insert, .monaco-diff-editor .gutter-insert { - background-color: var(--vscode-diffEditorGutter-insertedLineBackground, --vscode-diffEditor-insertedLineBackground, --vscode-diffEditor-insertedTextBackground); + background-color: var(--vscode-diffEditorGutter-insertedLineBackground, var(--vscode-diffEditor-insertedLineBackground), var(--vscode-diffEditor-insertedTextBackground)); } .monaco-editor .char-delete, .monaco-diff-editor .char-delete { @@ -114,12 +114,12 @@ } .monaco-editor .line-delete, .monaco-diff-editor .line-delete { - background-color: var(--vscode-diffEditor-removedLineBackground, --vscode-diffEditor-removedTextBackground); + background-color: var(--vscode-diffEditor-removedLineBackground, var(--vscode-diffEditor-removedTextBackground)); } .monaco-editor .inline-deleted-margin-view-zone, .monaco-editor .gutter-delete, .monaco-diff-editor .gutter-delete { - background-color: var(--vscode-diffEditorGutter-removedLineBackground, --vscode-diffEditor-removedLineBackground, --vscode-diffEditor-removedTextBackground); + background-color: var(--vscode-diffEditorGutter-removedLineBackground, var(--vscode-diffEditor-removedLineBackground), var(--vscode-diffEditor-removedTextBackground)); } .monaco-diff-editor.side-by-side .editor.modified { diff --git a/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts b/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts index cca1f5ab297..648ba44763c 100644 --- a/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts +++ b/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter, Event } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; import { StopWatch } from 'vs/base/common/stopwatch'; @@ -34,9 +35,9 @@ export class WorkerBasedDocumentDiffProvider implements IDocumentDiffProvider, I this.diffAlgorithmOnDidChangeSubscription?.dispose(); } - async computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions): Promise { + async computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions, cancellationToken: CancellationToken): Promise { if (typeof this.diffAlgorithm !== 'string') { - return this.diffAlgorithm.computeDiff(original, modified, options); + return this.diffAlgorithm.computeDiff(original, modified, options, cancellationToken); } // This significantly speeds up the case when the original file is empty @@ -95,6 +96,16 @@ export class WorkerBasedDocumentDiffProvider implements IDocumentDiffProvider, I timedOut: result?.quitEarly ?? true, }); + if (cancellationToken.isCancellationRequested) { + // Text models might be disposed! + return { + changes: [], + identical: false, + quitEarly: true, + moves: [], + }; + } + if (!result) { throw new Error('no diff result available'); } diff --git a/src/vs/editor/common/core/lineRange.ts b/src/vs/editor/common/core/lineRange.ts index c8779a2881a..70acb0476d6 100644 --- a/src/vs/editor/common/core/lineRange.ts +++ b/src/vs/editor/common/core/lineRange.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { BugIndicatingError } from 'vs/base/common/errors'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { Range } from 'vs/editor/common/core/range'; /** @@ -154,6 +155,10 @@ export class LineRange { return new LineRange(this.startLineNumber + offset, this.endLineNumberExclusive + offset); } + public deltaLength(offset: number): LineRange { + return new LineRange(this.startLineNumber, this.endLineNumberExclusive + offset); + } + /** * The number of lines this line range spans. */ @@ -235,6 +240,14 @@ export class LineRange { public includes(lineNumber: number): boolean { return this.startLineNumber <= lineNumber && lineNumber < this.endLineNumberExclusive; } + + /** + * Converts this 1-based line range to a 0-based offset range (subtracts 1!). + * @internal + */ + public toOffsetRange(): OffsetRange { + return new OffsetRange(this.startLineNumber - 1, this.endLineNumberExclusive - 1); + } } export type ISerializedLineRange = [startLineNumber: number, endLineNumberExclusive: number]; diff --git a/src/vs/editor/common/core/offsetRange.ts b/src/vs/editor/common/core/offsetRange.ts index 14ff2039fc7..27e60bca2df 100644 --- a/src/vs/editor/common/core/offsetRange.ts +++ b/src/vs/editor/common/core/offsetRange.ts @@ -34,6 +34,10 @@ export class OffsetRange { return new OffsetRange(start, endExclusive); } + public static ofLength(length: number): OffsetRange { + return new OffsetRange(0, length); + } + constructor(public readonly start: number, public readonly endExclusive: number) { if (start > endExclusive) { throw new BugIndicatingError(`Invalid range: ${this.toString()}`); @@ -48,6 +52,14 @@ export class OffsetRange { return new OffsetRange(this.start + offset, this.endExclusive + offset); } + public deltaStart(offset: number): OffsetRange { + return new OffsetRange(this.start + offset, this.endExclusive); + } + + public deltaEnd(offset: number): OffsetRange { + return new OffsetRange(this.start, this.endExclusive + offset); + } + public get length(): number { return this.endExclusive - this.start; } @@ -90,4 +102,96 @@ export class OffsetRange { } return undefined; } + + public slice(arr: T[]): T[] { + return arr.slice(this.start, this.endExclusive); + } + + /** + * Returns the given value if it is contained in this instance, otherwise the closest value that is contained. + * The range must not be empty. + */ + public clip(value: number): number { + if (this.isEmpty) { + throw new BugIndicatingError(`Invalid clipping range: ${this.toString()}`); + } + return Math.max(this.start, Math.min(this.endExclusive - 1, value)); + } + + /** + * Returns `r := value + k * length` such that `r` is contained in this range. + * The range must not be empty. + * + * E.g. `[5, 10).clipCyclic(10) === 5`, `[5, 10).clipCyclic(11) === 6` and `[5, 10).clipCyclic(4) === 9`. + */ + public clipCyclic(value: number): number { + if (this.isEmpty) { + throw new BugIndicatingError(`Invalid clipping range: ${this.toString()}`); + } + if (value < this.start) { + return this.endExclusive - ((this.start - value) % this.length); + } + if (value >= this.endExclusive) { + return this.start + ((value - this.start) % this.length); + } + return value; + } +} + +export class OffsetRangeSet { + private readonly _sortedRanges: OffsetRange[] = []; + + public addRange(range: OffsetRange): void { + let i = 0; + while (i < this._sortedRanges.length && this._sortedRanges[i].endExclusive < range.start) { + i++; + } + let j = i; + while (j < this._sortedRanges.length && this._sortedRanges[j].start <= range.endExclusive) { + j++; + } + if (i === j) { + this._sortedRanges.splice(i, 0, range); + } else { + const start = Math.min(range.start, this._sortedRanges[i].start); + const end = Math.max(range.endExclusive, this._sortedRanges[j - 1].endExclusive); + this._sortedRanges.splice(i, j - i, new OffsetRange(start, end)); + } + } + + public toString(): string { + return this._sortedRanges.map(r => r.toString()).join(', '); + } + + /** + * Returns of there is a value that is contained in this instance and the given range. + */ + public intersectsStrict(other: OffsetRange): boolean { + // TODO use binary search + let i = 0; + while (i < this._sortedRanges.length && this._sortedRanges[i].endExclusive <= other.start) { + i++; + } + return i < this._sortedRanges.length && this._sortedRanges[i].start < other.endExclusive; + } + + public intersectWithRange(other: OffsetRange): OffsetRangeSet { + // TODO use binary search + slice + const result = new OffsetRangeSet(); + for (const range of this._sortedRanges) { + const intersection = range.intersect(other); + if (intersection) { + result.addRange(intersection); + } + } + return result; + } + + public intersectWithRangeLength(other: OffsetRange): number { + return this.intersectWithRange(other).length; + } + + public get length(): number { + return this._sortedRanges.reduce((prev, cur) => prev + cur.length, 0); + } } diff --git a/src/vs/editor/common/diff/standardLinesDiffComputer.ts b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts similarity index 90% rename from src/vs/editor/common/diff/standardLinesDiffComputer.ts rename to src/vs/editor/common/diff/advancedLinesDiffComputer.ts index b9ef58b85c2..a7d9605d78c 100644 --- a/src/vs/editor/common/diff/standardLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts @@ -17,7 +17,7 @@ import { optimizeSequenceDiffs, removeRandomLineMatches, removeRandomMatches, sm import { MyersDiffAlgorithm } from 'vs/editor/common/diff/algorithms/myersDiffAlgorithm'; import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping, LinesDiff, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -export class StandardLinesDiffComputer implements ILinesDiffComputer { +export class AdvancedLinesDiffComputer implements ILinesDiffComputer { private readonly dynamicProgrammingDiffing = new DynamicProgrammingDiffing(); private readonly myersDiffingAlgorithm = new MyersDiffAlgorithm(); @@ -177,7 +177,7 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { } private computeMoves(changes: LineRangeMapping[], originalLines: string[], modifiedLines: string[], hashedOriginalLines: number[], hashedModifiedLines: number[], timeout: ITimeout, considerWhitespaceChanges: boolean): MovedText[] { - const moves: MovedText[] = []; + const moves: SimpleLineRangeMapping[] = []; const deletions = changes .filter(c => c.modifiedRange.isEmpty && c.originalRange.length >= 3) .map(d => new LineRangeFragment(d.originalRange, originalLines, d)); @@ -199,17 +199,15 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { } if (highestSimilarity > 0.90 && best) { - const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff( - new OffsetRange(deletion.range.startLineNumber - 1, deletion.range.endLineNumberExclusive - 1), - new OffsetRange(best.range.startLineNumber - 1, best.range.endLineNumberExclusive - 1) - ), timeout, considerWhitespaceChanges); - const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true); - insertions.delete(best); - moves.push(new MovedText(new SimpleLineRangeMapping(deletion.range, best.range), mappings)); + moves.push(new SimpleLineRangeMapping(deletion.range, best.range)); excludedChanges.add(deletion.source); excludedChanges.add(best.source); } + + if (!timeout.isValid()) { + return []; + } } const original3LineHashes = new SetMap(); @@ -242,9 +240,6 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { let lastMappings: PossibleMapping[] = []; for (let i = change.modifiedRange.startLineNumber; i < change.modifiedRange.endLineNumberExclusive - 2; i++) { const key = `${hashedModifiedLines[i - 1]}:${hashedModifiedLines[i + 1 - 1]}:${hashedModifiedLines[i + 2 - 1]}`; - - //const isWeakKey = (originalLines[i].trim().length + originalLines[i + 1].trim().length + originalLines[i + 2].trim().length < 20); - const currentModifiedRange = new LineRange(i, i + 3); const nextMappings: PossibleMapping[] = []; @@ -269,6 +264,10 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { }); lastMappings = nextMappings; } + + if (!timeout.isValid()) { + return []; + } } possibleMappings.sort(reverseOrder(compareBy(m => m.modifiedLineRange.length, numberComparator))); @@ -291,19 +290,49 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { const modifiedLineRange = s; const originalLineRange = s.delta(-diffOrigToMod); - const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff( - new OffsetRange(originalLineRange.startLineNumber - 1, originalLineRange.endLineNumberExclusive - 1), - new OffsetRange(modifiedLineRange.startLineNumber - 1, modifiedLineRange.endLineNumberExclusive - 1) - ), timeout, considerWhitespaceChanges); - const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true); - moves.push(new MovedText(new SimpleLineRangeMapping(originalLineRange, modifiedLineRange), mappings)); + moves.push(new SimpleLineRangeMapping(originalLineRange, modifiedLineRange)); modifiedSet.addRange(modifiedLineRange); originalSet.addRange(originalLineRange); } } - return moves; + // join moves + moves.sort(compareBy(m => m.original.startLineNumber, numberComparator)); + if (moves.length === 0) { + return []; + } + const joinedMoves = [moves[0]]; + for (let i = 1; i < moves.length; i++) { + const last = joinedMoves[joinedMoves.length - 1]; + const current = moves[i]; + + const originalDist = current.original.startLineNumber - last.original.endLineNumberExclusive; + const modifiedDist = current.modified.startLineNumber - last.modified.endLineNumberExclusive; + const currentMoveAfterLast = originalDist >= 0 && modifiedDist >= 0; + + if (currentMoveAfterLast && originalDist + modifiedDist <= 2) { + joinedMoves[joinedMoves.length - 1] = last.join(current); + continue; + } + + const originalText = current.original.toOffsetRange().slice(originalLines).map(l => l.trim()).join('\n'); + if (originalText.length <= 10) { + // Ignore small moves + continue; + } + joinedMoves.push(current); + } + + const fullMoves = joinedMoves.map(m => { + const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff( + m.original.toOffsetRange(), + m.modified.toOffsetRange(), + ), timeout, considerWhitespaceChanges); + const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true); + return new MovedText(m, mappings); + }); + return fullMoves; } private refineDiff(originalLines: string[], modifiedLines: string[], diff: SequenceDiff, timeout: ITimeout, considerWhitespaceChanges: boolean): { mappings: RangeMapping[]; hitTimeout: boolean } { @@ -659,7 +688,7 @@ export class LinesSliceCharSequence implements ISequence { private readonly firstCharOffsetByLineMinusOne: number[] = []; public readonly lineRange: OffsetRange; // To account for trimming - private readonly offsetByLine: number[] = []; + private readonly additionalOffsetByLine: number[] = []; constructor(public readonly lines: string[], lineRange: OffsetRange, public readonly considerWhitespaceChanges: boolean) { // This slice has to have lineRange.length many \n! (otherwise diffing against an empty slice will be problematic) @@ -687,7 +716,7 @@ export class LinesSliceCharSequence implements ISequence { line = trimmedStartLine.trimEnd(); } - this.offsetByLine.push(offset); + this.additionalOffsetByLine.push(offset); for (let i = 0; i < line.length; i++) { this.elements.push(line.charCodeAt(i)); @@ -700,7 +729,7 @@ export class LinesSliceCharSequence implements ISequence { } } // To account for the last line - this.offsetByLine.push(0); + this.additionalOffsetByLine.push(0); } toString() { @@ -767,7 +796,7 @@ export class LinesSliceCharSequence implements ISequence { } const offsetOfFirstCharInLine = i === 0 ? 0 : this.firstCharOffsetByLineMinusOne[i - 1]; - return new Position(this.lineRange.start + i + 1, offset - offsetOfFirstCharInLine + 1 + this.offsetByLine[i]); + return new Position(this.lineRange.start + i + 1, offset - offsetOfFirstCharInLine + 1 + this.additionalOffsetByLine[i]); } public translateRange(range: OffsetRange): Range { @@ -805,9 +834,52 @@ export class LinesSliceCharSequence implements ISequence { return this.translateOffset(range.endExclusive).lineNumber - this.translateOffset(range.start).lineNumber; } - isStronglyEqual(offset1: number, offset2: number): boolean { + public isStronglyEqual(offset1: number, offset2: number): boolean { return this.elements[offset1] === this.elements[offset2]; } + + public extendToFullLines(range: OffsetRange): OffsetRange { + const firstIdx = findLastIdxMonotonous(this.firstCharOffsetByLineMinusOne, x => x <= range.start); + const lastIdx = findFirstIdxMonotonous(this.firstCharOffsetByLineMinusOne, x => range.endExclusive <= x); + + const start = firstIdx === -1 ? 0 : this.firstCharOffsetByLineMinusOne[firstIdx]; + const end = lastIdx === this.firstCharOffsetByLineMinusOne.length ? this.elements.length : this.firstCharOffsetByLineMinusOne[lastIdx]; + return new OffsetRange(start, end); + } +} + +/** + * @returns -1 if predicate is false for all items + */ +function findLastIdxMonotonous(arr: T[], predicate: (item: T) => boolean): number { + let i = 0; + let j = arr.length; + while (i < j) { + const k = Math.floor((i + j) / 2); + if (predicate(arr[k])) { + i = k + 1; + } else { + j = k; + } + } + return i - 1; +} + +/** + * @returns arr.length if predicate is false for all items + */ +function findFirstIdxMonotonous(arr: T[], predicate: (item: T) => boolean): number { + let i = 0; + let j = arr.length; + while (i < j) { + const k = Math.floor((i + j) / 2); + if (predicate(arr[k])) { + j = k; + } else { + i = k + 1; + } + } + return i; } function isWordChar(charCode: number): boolean { diff --git a/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts b/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts index b76c82d371b..cef14d466c8 100644 --- a/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts +++ b/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts @@ -5,7 +5,7 @@ import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { ISequence, SequenceDiff } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; -import { LineSequence, LinesSliceCharSequence } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { LineSequence, LinesSliceCharSequence } from 'vs/editor/common/diff/advancedLinesDiffComputer'; export function optimizeSequenceDiffs(sequence1: ISequence, sequence2: ISequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { let result = sequenceDiffs; @@ -149,6 +149,29 @@ export function removeRandomMatches(sequence1: LinesSliceCharSequence, sequence2 diffs = result; } while (counter++ < 10 && shouldRepeat); + // Remove short suffixes/prefixes + for (let i = 0; i < diffs.length; i++) { + const cur = diffs[i]; + + let range1 = cur.seq1Range; + let range2 = cur.seq2Range; + + const fullRange1 = sequence1.extendToFullLines(cur.seq1Range); + const prefix = sequence1.getText(new OffsetRange(fullRange1.start, cur.seq1Range.start)); + if (prefix.length > 0 && prefix.trim().length <= 3 && cur.seq1Range.length + cur.seq2Range.length > 100) { + range1 = cur.seq1Range.deltaStart(-prefix.length); + range2 = cur.seq2Range.deltaStart(-prefix.length); + } + + const suffix = sequence1.getText(new OffsetRange(cur.seq1Range.endExclusive, fullRange1.endExclusive)); + if (suffix.length > 0 && (suffix.trim().length <= 3 && cur.seq1Range.length + cur.seq2Range.length > 150)) { + range1 = range1.deltaEnd(suffix.length); + range2 = range2.deltaEnd(suffix.length); + } + + diffs[i] = new SequenceDiff(range1, range2); + } + return diffs; } diff --git a/src/vs/editor/common/diff/documentDiffProvider.ts b/src/vs/editor/common/diff/documentDiffProvider.ts index ad707d114b5..02907dddca3 100644 --- a/src/vs/editor/common/diff/documentDiffProvider.ts +++ b/src/vs/editor/common/diff/documentDiffProvider.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationToken } from 'vs/base/common/cancellation'; import { Event } from 'vs/base/common/event'; import { LineRangeMapping, MovedText } from 'vs/editor/common/diff/linesDiffComputer'; import { ITextModel } from 'vs/editor/common/model'; @@ -14,7 +15,7 @@ export interface IDocumentDiffProvider { /** * Computes the diff between the text models `original` and `modified`. */ - computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions): Promise; + computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions, cancellationToken: CancellationToken): Promise; /** * Is fired when settings of the diff algorithm change that could alter the result of the diffing computation. diff --git a/src/vs/editor/common/diff/smartLinesDiffComputer.ts b/src/vs/editor/common/diff/legacyLinesDiffComputer.ts similarity index 99% rename from src/vs/editor/common/diff/smartLinesDiffComputer.ts rename to src/vs/editor/common/diff/legacyLinesDiffComputer.ts index fe7fdcdc5bf..5ea6524a41e 100644 --- a/src/vs/editor/common/diff/smartLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/legacyLinesDiffComputer.ts @@ -13,7 +13,7 @@ import { LineRange } from 'vs/editor/common/core/lineRange'; const MINIMUM_MATCHING_CHARACTER_LENGTH = 3; -export class SmartLinesDiffComputer implements ILinesDiffComputer { +export class LegacyLinesDiffComputer implements ILinesDiffComputer { computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): LinesDiff { const diffComputer = new DiffComputer(originalLines, modifiedLines, { maxComputationTime: options.maxComputationTimeMs, diff --git a/src/vs/editor/common/diff/linesDiffComputer.ts b/src/vs/editor/common/diff/linesDiffComputer.ts index 84505ab563a..d10888cb93f 100644 --- a/src/vs/editor/common/diff/linesDiffComputer.ts +++ b/src/vs/editor/common/diff/linesDiffComputer.ts @@ -155,6 +155,13 @@ export class SimpleLineRangeMapping { public flip(): SimpleLineRangeMapping { return new SimpleLineRangeMapping(this.modified, this.original); } + + public join(other: SimpleLineRangeMapping): SimpleLineRangeMapping { + return new SimpleLineRangeMapping( + this.original.join(other.original), + this.modified.join(other.modified), + ); + } } export class MovedText { diff --git a/src/vs/editor/common/diff/linesDiffComputers.ts b/src/vs/editor/common/diff/linesDiffComputers.ts index 415c72e8f04..727b91455b7 100644 --- a/src/vs/editor/common/diff/linesDiffComputers.ts +++ b/src/vs/editor/common/diff/linesDiffComputers.ts @@ -3,10 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SmartLinesDiffComputer } from 'vs/editor/common/diff/smartLinesDiffComputer'; -import { StandardLinesDiffComputer } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { LegacyLinesDiffComputer } from 'vs/editor/common/diff/legacyLinesDiffComputer'; +import { AdvancedLinesDiffComputer } from 'vs/editor/common/diff/advancedLinesDiffComputer'; export const linesDiffComputers = { - getLegacy: () => new SmartLinesDiffComputer(), - getAdvanced: () => new StandardLinesDiffComputer(), + getLegacy: () => new LegacyLinesDiffComputer(), + getAdvanced: () => new AdvancedLinesDiffComputer(), }; diff --git a/src/vs/editor/common/editorContextKeys.ts b/src/vs/editor/common/editorContextKeys.ts index c831d05fe21..a2b1a88cc44 100644 --- a/src/vs/editor/common/editorContextKeys.ts +++ b/src/vs/editor/common/editorContextKeys.ts @@ -27,6 +27,7 @@ export namespace EditorContextKeys { export const readOnly = new RawContextKey('editorReadonly', false, nls.localize('editorReadonly', "Whether the editor is read-only")); export const inDiffEditor = new RawContextKey('inDiffEditor', false, nls.localize('inDiffEditor', "Whether the context is a diff editor")); export const isEmbeddedDiffEditor = new RawContextKey('isEmbeddedDiffEditor', false, nls.localize('isEmbeddedDiffEditor', "Whether the context is an embedded diff editor")); + export const comparingMovedCode = new RawContextKey('comparingMovedCode', false, nls.localize('comparingMovedCode', "Whether a moved code block is selected for comparison")); export const accessibleDiffViewerVisible = new RawContextKey('accessibleDiffViewerVisible', false, nls.localize('accessibleDiffViewerVisible', "Whether the accessible diff viewer is visible")); export const diffEditorRenderSideBySideInlineBreakpointReached = new RawContextKey('diffEditorRenderSideBySideInlineBreakpointReached', false, nls.localize('diffEditorRenderSideBySideInlineBreakpointReached', "Whether the diff editor render side by side inline breakpoint is reached")); export const columnSelection = new RawContextKey('editorColumnSelection', false, nls.localize('editorColumnSelection', "Whether `editor.columnSelection` is enabled")); diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 409b993d05b..15b63cf0386 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -16,7 +16,7 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import { EditOperation, ISingleEditOperation } from 'vs/editor/common/core/editOperation'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; -import { Selection } from 'vs/editor/common/core/selection'; +import { ISelection, Selection } from 'vs/editor/common/core/selection'; import { LanguageId } from 'vs/editor/common/encodedTokenAttributes'; import * as model from 'vs/editor/common/model'; import { TokenizationRegistry as TokenizationRegistryImpl } from 'vs/editor/common/tokenizationRegistry'; @@ -2033,3 +2033,33 @@ export interface DocumentOnDropEditProvider { provideDocumentOnDropEdits(model: model.ITextModel, position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): ProviderResult; } + +export interface RelatedContextItem { + readonly uri: URI; + readonly range: IRange; +} + +export interface MappedEditsContext { + selections: ISelection[]; + related: RelatedContextItem[]; +} + +export interface MappedEditsProvider { + + /** + * Provider maps code blocks from the chat into a workspace edit. + * + * @param document The document to provide mapped edits for. + * @param codeBlocks Code blocks that come from an LLM's reply. + * "Insert at cursor" in the panel chat only sends one edit that the user clicks on, but inline chat can send multiple blocks and let the lang server decide what to do with them. + * @param context The context for providing mapped edits. + * @param token A cancellation token. + * @returns A provider result of text edits. + */ + provideMappedEdits( + document: model.ITextModel, + codeBlocks: string[], + context: MappedEditsContext, + token: CancellationToken + ): Promise; +} diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index 2c26721fd47..ca8364f62d3 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -20,7 +20,7 @@ import { createMonacoBaseAPI } from 'vs/editor/common/services/editorBaseApi'; import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost'; import { StopWatch } from 'vs/base/common/stopwatch'; import { UnicodeTextModelHighlighter, UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; -import { DiffComputer, IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { DiffComputer, IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; import { linesDiffComputers } from 'vs/editor/common/diff/linesDiffComputers'; import { createProxyObject, getAllMethodNames } from 'vs/base/common/objects'; diff --git a/src/vs/editor/common/services/editorWorker.ts b/src/vs/editor/common/services/editorWorker.ts index 9038e313a9c..9e1cca8a460 100644 --- a/src/vs/editor/common/services/editorWorker.ts +++ b/src/vs/editor/common/services/editorWorker.ts @@ -6,7 +6,7 @@ import { URI } from 'vs/base/common/uri'; import { IRange } from 'vs/editor/common/core/range'; import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IInplaceReplaceSupportResult, TextEdit } from 'vs/editor/common/languages'; import { UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; diff --git a/src/vs/editor/common/services/languageFeatures.ts b/src/vs/editor/common/services/languageFeatures.ts index 2c80887df1a..df53beaecdb 100644 --- a/src/vs/editor/common/services/languageFeatures.ts +++ b/src/vs/editor/common/services/languageFeatures.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { LanguageFeatureRegistry, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry'; -import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentPasteEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; +import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentPasteEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, MappedEditsProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const ILanguageFeaturesService = createDecorator('ILanguageFeaturesService'); @@ -71,6 +71,8 @@ export interface ILanguageFeaturesService { readonly documentOnDropEditProvider: LanguageFeatureRegistry; + readonly mappedEditsProvider: LanguageFeatureRegistry; + // -- setNotebookTypeResolver(resolver: NotebookInfoResolver | undefined): void; diff --git a/src/vs/editor/common/services/languageFeaturesService.ts b/src/vs/editor/common/services/languageFeaturesService.ts index 35d321b4ef2..3ef13891fb7 100644 --- a/src/vs/editor/common/services/languageFeaturesService.ts +++ b/src/vs/editor/common/services/languageFeaturesService.ts @@ -5,7 +5,7 @@ import { URI } from 'vs/base/common/uri'; import { LanguageFeatureRegistry, NotebookInfo, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry'; -import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DocumentPasteEditProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; +import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DocumentPasteEditProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentOnDropEditProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider, MappedEditsProvider } from 'vs/editor/common/languages'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -42,6 +42,7 @@ export class LanguageFeaturesService implements ILanguageFeaturesService { readonly documentSemanticTokensProvider = new LanguageFeatureRegistry(this._score.bind(this)); readonly documentOnDropEditProvider = new LanguageFeatureRegistry(this._score.bind(this)); readonly documentPasteEditProvider = new LanguageFeatureRegistry(this._score.bind(this)); + readonly mappedEditsProvider: LanguageFeatureRegistry = new LanguageFeatureRegistry(this._score.bind(this)); private _notebookTypeResolver?: NotebookInfoResolver; diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index 0f645908a5f..fc33e04fdd0 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -22,13 +22,13 @@ interface ActionGroup { const uncategorizedCodeActionGroup = Object.freeze({ kind: CodeActionKind.Empty, title: localize('codeAction.widget.id.more', 'More Actions...') }); const codeActionGroups = Object.freeze([ - { kind: CodeActionKind.QuickFix, title: localize('codeAction.widget.id.quickfix', 'Quick Fix...') }, - { kind: CodeActionKind.RefactorExtract, title: localize('codeAction.widget.id.extract', 'Extract...'), icon: Codicon.wrench }, - { kind: CodeActionKind.RefactorInline, title: localize('codeAction.widget.id.inline', 'Inline...'), icon: Codicon.wrench }, - { kind: CodeActionKind.RefactorRewrite, title: localize('codeAction.widget.id.convert', 'Rewrite...'), icon: Codicon.wrench }, - { kind: CodeActionKind.RefactorMove, title: localize('codeAction.widget.id.move', 'Move...'), icon: Codicon.wrench }, - { kind: CodeActionKind.SurroundWith, title: localize('codeAction.widget.id.surround', 'Surround With...'), icon: Codicon.symbolSnippet }, - { kind: CodeActionKind.Source, title: localize('codeAction.widget.id.source', 'Source Action...'), icon: Codicon.symbolFile }, + { kind: CodeActionKind.QuickFix, title: localize('codeAction.widget.id.quickfix', 'Quick Fix:') }, + { kind: CodeActionKind.RefactorExtract, title: localize('codeAction.widget.id.extract', 'Extract:'), icon: Codicon.wrench }, + { kind: CodeActionKind.RefactorInline, title: localize('codeAction.widget.id.inline', 'Inline:'), icon: Codicon.wrench }, + { kind: CodeActionKind.RefactorRewrite, title: localize('codeAction.widget.id.convert', 'Rewrite:'), icon: Codicon.wrench }, + { kind: CodeActionKind.RefactorMove, title: localize('codeAction.widget.id.move', 'Move:'), icon: Codicon.wrench }, + { kind: CodeActionKind.SurroundWith, title: localize('codeAction.widget.id.surround', 'Surround With:'), icon: Codicon.symbolSnippet }, + { kind: CodeActionKind.Source, title: localize('codeAction.widget.id.source', 'Source Action:'), icon: Codicon.symbolFile }, uncategorizedCodeActionGroup, ]); diff --git a/src/vs/editor/contrib/colorPicker/browser/standaloneColorPickerWidget.ts b/src/vs/editor/contrib/colorPicker/browser/standaloneColorPickerWidget.ts index 6d874e71d4b..a6ef1b75116 100644 --- a/src/vs/editor/contrib/colorPicker/browser/standaloneColorPickerWidget.ts +++ b/src/vs/editor/contrib/colorPicker/browser/standaloneColorPickerWidget.ts @@ -87,11 +87,10 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW static readonly ID = 'editor.contrib.standaloneColorPickerWidget'; readonly allowEditorOverflow = true; - private body: HTMLElement = document.createElement('div'); - private readonly _position: Position | undefined = undefined; private readonly _standaloneColorPickerParticipant: StandaloneColorPickerParticipant; + private _body: HTMLElement = document.createElement('div'); private _colorHover: StandaloneColorPickerHover | null = null; private _selectionSetInEditor: boolean = false; @@ -120,7 +119,7 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW endLineNumber: editorSelection.endLineNumber, endColumn: editorSelection.endColumn } : { startLineNumber: 0, endLineNumber: 0, endColumn: 0, startColumn: 0 }; - const focusTracker = this._register(dom.trackFocus(this.body)); + const focusTracker = this._register(dom.trackFocus(this._body)); this._register(focusTracker.onDidBlur(_ => { this.hide(); })); @@ -146,6 +145,7 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW this._render(result.value, result.foundInEditor); })); this._start(selection); + this._body.style.zIndex = '50'; this._editor.addContentWidget(this); } @@ -160,7 +160,7 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW } public getDomNode(): HTMLElement { - return this.body; + return this._body; } public getPosition(): IContentWidgetPosition | null { @@ -186,7 +186,7 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW public focus(): void { this._standaloneColorPickerFocused.set(true); - this.body.focus(); + this._body.focus(); } private async _start(selection: IRange) { @@ -230,11 +230,11 @@ export class StandaloneColorPickerWidget extends Disposable implements IContentW if (colorPickerWidget === undefined) { return; } - this.body.classList.add('standalone-colorpicker-body'); - this.body.style.maxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250) + 'px'; - this.body.style.maxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500) + 'px'; - this.body.tabIndex = 0; - this.body.appendChild(fragment); + this._body.classList.add('standalone-colorpicker-body'); + this._body.style.maxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250) + 'px'; + this._body.style.maxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500) + 'px'; + this._body.tabIndex = 0; + this._body.appendChild(fragment); colorPickerWidget.layout(); const colorPickerBody = colorPickerWidget.body; diff --git a/src/vs/editor/contrib/inlineCompletions/browser/commands.ts b/src/vs/editor/contrib/inlineCompletions/browser/commands.ts index 799433568e0..ac7535f9231 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/commands.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/commands.ts @@ -148,7 +148,8 @@ export class AcceptInlineCompletion extends EditorAction { InlineCompletionContextKeys.inlineSuggestionVisible, EditorContextKeys.tabMovesFocus.toNegated(), InlineCompletionContextKeys.inlineSuggestionHasIndentationLessThanTabSize, - SuggestContext.Visible.toNegated() + SuggestContext.Visible.toNegated(), + EditorContextKeys.hoverFocused.toNegated(), ), } }); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts index 51b2d4fc562..094393e32c5 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts @@ -117,7 +117,7 @@ export class InlineCompletionsController extends Disposable { this._register(editor.onDidChangeCursorPosition(e => transaction(tx => { /** @description onDidChangeCursorPosition */ this.updateObservables(tx, VersionIdChangeReason.Other); - if (e.reason === CursorChangeReason.Explicit) { + if (e.reason === CursorChangeReason.Explicit || e.source === 'api') { this.model.get()?.stop(tx); } }))); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css index 642e6c51d7a..196307cc49e 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.css @@ -29,7 +29,7 @@ padding: 2px 3px; } -.monaco-editor .inlineSuggestionsHints .custom-actions .action-item:nth-child(2) a { +.monaco-editor .inlineSuggestionsHints .availableSuggestionCount a { display: flex; min-width: 19px; justify-content: center; diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts index eb9aa10b05c..0cde6e9a9b5 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsHintsWidget.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { h } from 'vs/base/browser/dom'; -import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { KeybindingLabel, unthemedKeybindingLabelOptions } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel'; import { Action, IAction, Separator } from 'vs/base/common/actions'; import { equals } from 'vs/base/common/arrays'; @@ -112,10 +112,7 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC public readonly suppressMouseDown = false; private readonly nodes = h('div.inlineSuggestionsHints', { className: this.withBorder ? '.withBorder' : '' }, [ - h('div', { style: { display: 'flex' } }, [ - h('div@actionBar', { className: 'custom-actions' }), - h('div@toolBar'), - ]) + h('div@toolBar'), ]); private createCommandAction(commandId: string, label: string, iconClassName: string): Action { @@ -173,21 +170,29 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC ) { super(); - const actionBar = this._register(new ActionBar(this.nodes.actionBar)); - - actionBar.push(this.previousAction, { icon: true, label: false }); - actionBar.push(this.availableSuggestionCountAction); - actionBar.push(this.nextAction, { icon: true, label: false }); - this.toolBar = this._register(instantiationService.createInstance(CustomizedMenuWorkbenchToolBar, this.nodes.toolBar, MenuId.InlineSuggestionToolbar, { menuOptions: { renderShortTitle: true }, toolbarOptions: { primaryGroup: g => g.startsWith('primary') }, actionViewItemProvider: (action, options) => { - return action instanceof MenuItemAction ? instantiationService.createInstance(StatusBarViewItem, action, undefined) : undefined; + if (action instanceof MenuItemAction) { + return instantiationService.createInstance(StatusBarViewItem, action, undefined); + } + if (action === this.availableSuggestionCountAction) { + const a = new ActionViewItemWithClassName(undefined, action, { label: true, icon: false }); + a.setClass('availableSuggestionCount'); + return a; + } + return undefined; }, telemetrySource: 'InlineSuggestionToolbar', })); + this.toolBar.setPrependedPrimaryActions([ + this.previousAction, + this.availableSuggestionCountAction, + this.nextAction, + ]); + this._register(this.toolBar.onDidChangeDropdownVisibility(e => { InlineSuggestionHintsContentWidget._dropDownVisible = e; })); @@ -270,6 +275,21 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC } } +class ActionViewItemWithClassName extends ActionViewItem { + private _className: string | undefined = undefined; + + setClass(className: string | undefined): void { + this._className = className; + } + + override render(container: HTMLElement): void { + super.render(container); + if (this._className) { + container.classList.add(this._className); + } + } +} + class StatusBarViewItem extends MenuEntryActionViewItem { protected override updateLabel() { const kb = this._keybindingService.lookupKeybinding(this._action.id, this._contextKeyService); @@ -291,6 +311,7 @@ class StatusBarViewItem extends MenuEntryActionViewItem { export class CustomizedMenuWorkbenchToolBar extends WorkbenchToolBar { private readonly menu = this._store.add(this.menuService.createMenu(this.menuId, this.contextKeyService, { emitEventsForSubmenuChanges: true })); private additionalActions: IAction[] = []; + private prependedPrimaryActions: IAction[] = []; constructor( container: HTMLElement, @@ -319,12 +340,21 @@ export class CustomizedMenuWorkbenchToolBar extends WorkbenchToolBar { ); secondary.push(...this.additionalActions); + primary.unshift(...this.prependedPrimaryActions); this.setActions(primary, secondary); } + setPrependedPrimaryActions(actions: IAction[]): void { + if (equals(this.prependedPrimaryActions, actions, (a, b) => a === b)) { + return; + } + + this.prependedPrimaryActions = actions; + this.updateToolbar(); + } + setAdditionalSecondaryActions(actions: IAction[]): void { if (equals(this.additionalActions, actions, (a, b) => a === b)) { - // don't update if the actions are the same return; } diff --git a/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts b/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts index 0e3355907af..11a5c6c4f27 100644 --- a/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts +++ b/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts @@ -953,8 +953,8 @@ export class TransposeAction extends EditorAction { constructor() { super({ id: 'editor.action.transpose', - label: nls.localize('editor.transpose', "Transpose characters around the cursor"), - alias: 'Transpose characters around the cursor', + label: nls.localize('editor.transpose', "Transpose Characters around the Cursor"), + alias: 'Transpose Characters around the Cursor', precondition: EditorContextKeys.writable }); } diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts index 77f08ff3598..cc340f143e9 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts @@ -375,7 +375,6 @@ export class StickyScrollController extends Disposable implements IEditorContrib private _readConfiguration() { const options = this._editor.getOption(EditorOption.stickyScroll); - if (options.enabled === false) { this._editor.removeOverlayWidget(this._stickyScrollWidget); this._sessionStore.clear(); @@ -434,10 +433,11 @@ export class StickyScrollController extends Disposable implements IEditorContrib } private _renderStickyScroll() { - if (!(this._editor.hasModel())) { + const model = this._editor.getModel(); + if (!model || model.isTooLargeForTokenization()) { + this._stickyScrollWidget.setState(undefined); return; } - const model = this._editor.getModel(); const stickyLineVersion = this._stickyLineCandidateProvider.getVersionId(); if (stickyLineVersion === undefined || stickyLineVersion === model.getVersionId()) { this._widgetState = this.findScrollWidgetState(); diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts index 610eff4fb8c..15899c9a054 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts @@ -110,11 +110,8 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { } setState(state: StickyScrollWidgetState): void { - this._stickyLines = []; - this._foldingIconStore.clear(); - dom.clearNode(this._lineNumbersDomNode); - dom.clearNode(this._linesDomNode); - if (!this._editor._getViewModel()) { + this._clearStickyWidget(); + if (!state) { return; } const futureWidgetHeight = state.startLineNumbers.length * this._lineHeight + state.lastLineRelativePosition; @@ -142,6 +139,14 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { this._rootDomNode.style.width = `${layoutInfo.width - layoutInfo.minimap.minimapCanvasOuterWidth - layoutInfo.verticalScrollbarWidth}px`; } + private _clearStickyWidget() { + this._stickyLines = []; + this._foldingIconStore.clear(); + dom.clearNode(this._lineNumbersDomNode); + dom.clearNode(this._linesDomNode); + this._rootDomNode.style.display = 'none'; + } + private async _renderRootNode(): Promise { const foldingModel = await FoldingController.get(this._editor)?.getFoldingModel(); @@ -157,7 +162,11 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { } const widgetHeight: number = this._lineNumbers.length * this._lineHeight + this._lastLineRelativePosition; - this._rootDomNode.style.display = widgetHeight > 0 ? 'block' : 'none'; + if (widgetHeight === 0) { + this._clearStickyWidget(); + return; + } + this._rootDomNode.style.display = 'block'; this._lineNumbersDomNode.style.height = `${widgetHeight}px`; this._linesDomNodeScrollable.style.height = `${widgetHeight}px`; this._rootDomNode.style.height = `${widgetHeight}px`; diff --git a/src/vs/editor/contrib/suggest/browser/suggestController.ts b/src/vs/editor/contrib/suggest/browser/suggestController.ts index 887fb23cb2d..6450e989bce 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestController.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestController.ts @@ -143,7 +143,7 @@ export class SuggestController implements IEditorContribution { // context key: update insert/replace mode const ctxInsertMode = SuggestContext.InsertMode.bindTo(_contextKeyService); ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode); - this.model.onDidTrigger(() => ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode)); + this._toDispose.add(this.model.onDidTrigger(() => ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode))); this.widget = this._toDispose.add(new IdleValue(() => { diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index 4ff53468f06..005e48ad530 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -352,8 +352,9 @@ export function createWebWorker(opts: IWebWorkerOptions): Mona export function colorizeElement(domNode: HTMLElement, options: IColorizerElementOptions): Promise { const languageService = StandaloneServices.get(ILanguageService); const themeService = StandaloneServices.get(IStandaloneThemeService); - themeService.registerEditorContainer(domNode); - return Colorizer.colorizeElement(themeService, languageService, domNode, options); + return Colorizer.colorizeElement(themeService, languageService, domNode, options).then(() => { + themeService.registerEditorContainer(domNode); + }); } /** diff --git a/src/vs/editor/test/common/diff/diffComputer.test.ts b/src/vs/editor/test/common/diff/diffComputer.test.ts index a8eb52b07c1..aca599dc6e5 100644 --- a/src/vs/editor/test/common/diff/diffComputer.test.ts +++ b/src/vs/editor/test/common/diff/diffComputer.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { Constants } from 'vs/base/common/uint'; import { Range } from 'vs/editor/common/core/range'; -import { DiffComputer, ICharChange, ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { DiffComputer, ICharChange, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; diff --git a/src/vs/editor/test/common/services/testEditorWorkerService.ts b/src/vs/editor/test/common/services/testEditorWorkerService.ts index 640a3e4b596..e6693d821e9 100644 --- a/src/vs/editor/test/common/services/testEditorWorkerService.ts +++ b/src/vs/editor/test/common/services/testEditorWorkerService.ts @@ -8,7 +8,7 @@ import { IRange } from 'vs/editor/common/core/range'; import { DiffAlgorithmName, IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker'; import { TextEdit, IInplaceReplaceSupportResult } from 'vs/editor/common/languages'; import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; export class TestEditorWorkerService implements IEditorWorkerService { diff --git a/src/vs/editor/test/node/diffing/diffingFixture.test.ts b/src/vs/editor/test/node/diffing/diffingFixture.test.ts index 59173290fc8..a04f2edf9d8 100644 --- a/src/vs/editor/test/node/diffing/diffingFixture.test.ts +++ b/src/vs/editor/test/node/diffing/diffingFixture.test.ts @@ -9,8 +9,8 @@ import { join, resolve } from 'path'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { FileAccess } from 'vs/base/common/network'; import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -import { SmartLinesDiffComputer } from 'vs/editor/common/diff/smartLinesDiffComputer'; -import { StandardLinesDiffComputer } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { LegacyLinesDiffComputer } from 'vs/editor/common/diff/legacyLinesDiffComputer'; +import { AdvancedLinesDiffComputer } from 'vs/editor/common/diff/advancedLinesDiffComputer'; suite('diff fixtures', () => { setup(() => { @@ -38,7 +38,7 @@ suite('diff fixtures', () => { const secondContent = readFileSync(join(folderPath, secondFileName), 'utf8').replaceAll('\r\n', '\n').replaceAll('\r', '\n'); const secondContentLines = secondContent.split(/\n/); - const diffingAlgo = diffingAlgoName === 'legacy' ? new SmartLinesDiffComputer() : new StandardLinesDiffComputer(); + const diffingAlgo = diffingAlgoName === 'legacy' ? new LegacyLinesDiffComputer() : new AdvancedLinesDiffComputer(); const ignoreTrimWhitespace = folder.indexOf('trimws') >= 0; const diff = diffingAlgo.computeDiff(firstContentLines, secondContentLines, { ignoreTrimWhitespace, maxComputationTimeMs: Number.MAX_SAFE_INTEGER, computeMoves: false }); diff --git a/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json index 2b8f1b4ab1a..5cbd3c45666 100644 --- a/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json @@ -13,8 +13,8 @@ "modifiedRange": "[29,37)", "innerChanges": [ { - "originalRange": "[29,1 -> 60,48]", - "modifiedRange": "[29,1 -> 36,66]" + "originalRange": "[29,1 -> 61,1]", + "modifiedRange": "[29,1 -> 37,1]" } ] }, diff --git a/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json index 8ac0682b508..b1de25a5907 100644 --- a/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json @@ -13,8 +13,8 @@ "modifiedRange": "[6,11)", "innerChanges": [ { - "originalRange": "[6,2 -> 11,49]", - "modifiedRange": "[6,2 -> 6,91]" + "originalRange": "[6,1 -> 11,49]", + "modifiedRange": "[6,1 -> 6,91]" }, { "originalRange": "[12,76 -> 12,76]", diff --git a/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json index 5a679831447..20190a83798 100644 --- a/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/noise-1/advanced.expected.diff.json @@ -21,8 +21,8 @@ "modifiedRange": "[53,6 -> 53,45]" }, { - "originalRange": "[52,77 -> 55,53]", - "modifiedRange": "[53,98 -> 65,66]" + "originalRange": "[52,77 -> 56,1]", + "modifiedRange": "[53,98 -> 66,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json index 92f5e20707f..0b00ea98beb 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-class/advanced.expected.diff.json @@ -47,8 +47,8 @@ "modifiedRange": "[8,12)", "innerChanges": [ { - "originalRange": "[11,10 -> 20,25]", - "modifiedRange": "[8,10 -> 11,51]" + "originalRange": "[11,10 -> 21,1]", + "modifiedRange": "[8,10 -> 12,1]" } ] }, diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json index f6817defb49..3835a5ceb3c 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json @@ -43,8 +43,8 @@ "modifiedRange": "[14,18)", "innerChanges": [ { - "originalRange": "[14,120 -> 14,211]", - "modifiedRange": "[14,120 -> 17,1]" + "originalRange": "[14,120 -> 15,1]", + "modifiedRange": "[14,120 -> 18,1]" } ] }, @@ -65,8 +65,8 @@ "modifiedRange": "[21,18 -> 21,43]" }, { - "originalRange": "[17,71 -> 23,4]", - "modifiedRange": "[21,74 -> 21,81]" + "originalRange": "[17,71 -> 24,1]", + "modifiedRange": "[21,74 -> 22,1]" } ] }, @@ -93,8 +93,8 @@ "modifiedRange": "[26,38)", "innerChanges": [ { - "originalRange": "[28,1 -> 30,31]", - "modifiedRange": "[26,1 -> 37,9]" + "originalRange": "[28,1 -> 31,1]", + "modifiedRange": "[26,1 -> 38,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json index d8eac8523e6..c7cd88a788b 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-example1/advanced.expected.diff.json @@ -27,8 +27,8 @@ "modifiedRange": "[17,80)", "innerChanges": [ { - "originalRange": "[13,10 -> 14,43]", - "modifiedRange": "[17,10 -> 79,2]" + "originalRange": "[13,10 -> 15,1]", + "modifiedRange": "[17,10 -> 80,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json index aa65f823a85..7a52e0e84aa 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/advanced.expected.diff.json @@ -13,8 +13,8 @@ "modifiedRange": "[9,15)", "innerChanges": [ { - "originalRange": "[9,124 -> 9,124]", - "modifiedRange": "[9,124 -> 14,143]" + "originalRange": "[9,124 -> 10,1]", + "modifiedRange": "[9,124 -> 15,1]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json index 85a9a2fe928..66e738ab041 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ws-alignment/advanced.expected.diff.json @@ -23,8 +23,8 @@ "modifiedRange": "[7,18)", "innerChanges": [ { - "originalRange": "[7,5 -> 12,17]", - "modifiedRange": "[7,5 -> 16,7]" + "originalRange": "[7,1 -> 13,1]", + "modifiedRange": "[7,1 -> 17,1]" }, { "originalRange": "[13,6 -> 13,11]", diff --git a/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts b/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts index 5cda2c94794..f0d0802912d 100644 --- a/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts +++ b/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { Range } from 'vs/editor/common/core/range'; import { RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -import { getLineRangeMapping } from 'vs/editor/common/diff/standardLinesDiffComputer'; +import { getLineRangeMapping } from 'vs/editor/common/diff/advancedLinesDiffComputer'; suite('lineRangeMapping', () => { test('1', () => { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 8fbfcd493ae..2d030c3fa23 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2374,7 +2374,7 @@ declare namespace monaco.editor { /** * Computes the diff between the text models `original` and `modified`. */ - computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions): Promise; + computeDiff(original: ITextModel, modified: ITextModel, options: IDocumentDiffProviderOptions, cancellationToken: CancellationToken): Promise; /** * Is fired when settings of the diff algorithm change that could alter the result of the diffing computation. * Any user of this provider should recompute the diff when this event is fired. @@ -2460,6 +2460,7 @@ declare namespace monaco.editor { * Moves this line range by the given offset of line numbers. */ delta(offset: number): LineRange; + deltaLength(offset: number): LineRange; /** * The number of lines this line range spans. */ @@ -2545,6 +2546,7 @@ declare namespace monaco.editor { constructor(original: LineRange, modified: LineRange); toString(): string; flip(): SimpleLineRangeMapping; + join(other: SimpleLineRangeMapping): SimpleLineRangeMapping; } export interface IDimension { width: number; @@ -7891,6 +7893,30 @@ declare namespace monaco.languages { provideDocumentRangeSemanticTokens(model: editor.ITextModel, range: Range, token: CancellationToken): ProviderResult; } + export interface RelatedContextItem { + readonly uri: Uri; + readonly range: IRange; + } + + export interface MappedEditsContext { + selections: ISelection[]; + related: RelatedContextItem[]; + } + + export interface MappedEditsProvider { + /** + * Provider maps code blocks from the chat into a workspace edit. + * + * @param document The document to provide mapped edits for. + * @param codeBlocks Code blocks that come from an LLM's reply. + * "Insert at cursor" in the panel chat only sends one edit that the user clicks on, but inline chat can send multiple blocks and let the lang server decide what to do with them. + * @param context The context for providing mapped edits. + * @param token A cancellation token. + * @returns A provider result of text edits. + */ + provideMappedEdits(document: editor.ITextModel, codeBlocks: string[], context: MappedEditsContext, token: CancellationToken): Promise; + } + export interface ILanguageExtensionPoint { id: string; extensions?: string[]; diff --git a/src/vs/platform/actionWidget/browser/actionWidget.css b/src/vs/platform/actionWidget/browser/actionWidget.css index 1384b5f5e74..539af6ca265 100644 --- a/src/vs/platform/actionWidget/browser/actionWidget.css +++ b/src/vs/platform/actionWidget/browser/actionWidget.css @@ -94,7 +94,8 @@ .action-widget .monaco-list-row.action.option-disabled, .action-widget .monaco-list:focus .monaco-list-row.focused.action.option-disabled, -.action-widget .monaco-list-row.action.option-disabled .codicon { +.action-widget .monaco-list-row.action.option-disabled .codicon, +.action-widget .monaco-list:not(.drop-target):not(.dragging) .monaco-list-row:hover:not(.selected):not(.focused).option-disabled { color: var(--vscode-disabledForeground); } diff --git a/src/vs/platform/actions/browser/buttonbar.ts b/src/vs/platform/actions/browser/buttonbar.ts index cb6ab4c31df..4965d6bb5cd 100644 --- a/src/vs/platform/actions/browser/buttonbar.ts +++ b/src/vs/platform/actions/browser/buttonbar.ts @@ -55,7 +55,7 @@ export class MenuWorkbenchButtonBar extends ButtonBar { 'workbenchActionExecuted', { id: e.action.id, from: options.telemetrySource! } ); - }, this._store); + }, undefined, this._store); } const conifgProvider: IButtonConfigProvider = options?.buttonConfigProvider ?? (() => ({ showLabel: true })); diff --git a/src/vs/platform/environment/common/argv.ts b/src/vs/platform/environment/common/argv.ts index 17476d94187..b63a262137f 100644 --- a/src/vs/platform/environment/common/argv.ts +++ b/src/vs/platform/environment/common/argv.ts @@ -3,15 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +export interface INativeCliOptions { + 'cli-data-dir'?: string; + 'disable-telemetry'?: boolean; + 'telemetry-level'?: string; +} + /** * A list of command line arguments we support natively. */ export interface NativeParsedArgs { // subcommands - tunnel?: { - 'cli-data-dir'?: string; - 'disable-telemetry'?: boolean; - 'telemetry-level'?: string; + tunnel?: INativeCliOptions & { user: { login: { 'access-token'?: string; @@ -19,6 +22,7 @@ export interface NativeParsedArgs { }; }; }; + 'serve-web'?: INativeCliOptions; _: string[]; 'folder-uri'?: string[]; // undefined or array of 1 or more 'file-uri'?: string[]; // undefined or array of 1 or more diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index b3e423e20f9..63243fcf3a0 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -44,6 +44,8 @@ export type OptionDescriptions = { Subcommand }; +export const NATIVE_CLI_COMMANDS = ['tunnel', 'serve-web'] as const; + export const OPTIONS: OptionDescriptions> = { 'tunnel': { type: 'subcommand', @@ -66,6 +68,15 @@ export const OPTIONS: OptionDescriptions> = { } } }, + 'serve-web': { + type: 'subcommand', + description: 'Make the current machine accessible from vscode.dev or other machines through a secure tunnel', + options: { + 'cli-data-dir': { type: 'string', args: 'dir', description: localize('cliDataDir', "Directory where CLI metadata should be stored.") }, + 'disable-telemetry': { type: 'boolean' }, + 'telemetry-level': { type: 'string' }, + } + }, 'diff': { type: 'boolean', cat: 'o', alias: 'd', args: ['file', 'file'], description: localize('diff', "Compare two files with each other.") }, 'merge': { type: 'boolean', cat: 'o', alias: 'm', args: ['path1', 'path2', 'base', 'result'], description: localize('merge', "Perform a three-way merge by providing paths for two modified versions of a file, the common origin of both modified versions and the output file to save merge results.") }, diff --git a/src/vs/platform/environment/node/argvHelper.ts b/src/vs/platform/environment/node/argvHelper.ts index 74a7369225d..d8cefb6df67 100644 --- a/src/vs/platform/environment/node/argvHelper.ts +++ b/src/vs/platform/environment/node/argvHelper.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { localize } from 'vs/nls'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; -import { ErrorReporter, OPTIONS, parseArgs } from 'vs/platform/environment/node/argv'; +import { ErrorReporter, NATIVE_CLI_COMMANDS, OPTIONS, parseArgs } from 'vs/platform/environment/node/argv'; function parseAndValidate(cmdLineArgs: string[], reportWarnings: boolean): NativeParsedArgs { const onMultipleValues = (id: string, val: string) => { @@ -21,14 +21,14 @@ function parseAndValidate(cmdLineArgs: string[], reportWarnings: boolean): Nativ }; const getSubcommandReporter = (command: string) => ({ onUnknownOption: (id: string) => { - if (command !== 'tunnel') { + if (!(NATIVE_CLI_COMMANDS as readonly string[]).includes(command)) { console.warn(localize('unknownSubCommandOption', "Warning: '{0}' is not in the list of known options for subcommand '{1}'", id, command)); } }, onMultipleValues, onEmptyValue, onDeprecatedOption, - getSubcommandReporter: command !== 'tunnel' ? getSubcommandReporter : undefined + getSubcommandReporter: (NATIVE_CLI_COMMANDS as readonly string[]).includes(command) ? getSubcommandReporter : undefined }); const errorReporter: ErrorReporter = { onUnknownOption: (id) => { diff --git a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts index 23f3a635495..bcbc16146d7 100644 --- a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts +++ b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts @@ -16,7 +16,7 @@ import * as nls from 'vs/nls'; import { ExtensionManagementError, IExtensionGalleryService, IExtensionIdentifier, IExtensionManagementParticipant, IGalleryExtension, ILocalExtension, InstallOperation, IExtensionsControlManifest, StatisticType, isTargetPlatformCompatible, TargetPlatformToString, ExtensionManagementErrorCode, - InstallOptions, InstallVSIXOptions, UninstallOptions, Metadata, InstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionResult, UninstallExtensionEvent, IExtensionManagementService, InstallExtensionInfo, EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT + InstallOptions, InstallVSIXOptions, UninstallOptions, Metadata, InstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionResult, UninstallExtensionEvent, IExtensionManagementService, InstallExtensionInfo, EXTENSION_INSTALL_DEP_PACK_CONTEXT } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions, ExtensionKey, getGalleryExtensionId, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionType, IExtensionManifest, isApplicationScopedExtension, TargetPlatform } from 'vs/platform/extensions/common/extensions'; @@ -35,6 +35,7 @@ export interface IInstallExtensionTask { readonly source: IGalleryExtension | URI; readonly operation: InstallOperation; readonly profileLocation: URI; + readonly options: InstallExtensionTaskOptions; readonly verificationStatus?: ExtensionVerificationStatus; run(): Promise; waitUntilTaskIsFinished(): Promise; @@ -153,7 +154,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } async toggleAppliationScope(extension: ILocalExtension, fromProfileLocation: URI): Promise { - if (isApplicationScopedExtension(extension.manifest)) { + if (isApplicationScopedExtension(extension.manifest) || extension.isBuiltin) { return extension; } @@ -248,7 +249,6 @@ export abstract class AbstractExtensionManagementService extends Disposable impl allInstallExtensionTasks.push({ task: installExtensionTask, manifest }); let installExtensionHasDependents: boolean = false; - const hasPackExtensions = manifest.extensionPack && manifest.extensionPack.length > 0; try { if (installExtensionTaskOptions.donotIncludePackAndDependencies) { this.logService.info('Installing the extension without checking dependencies and pack', installExtensionTask.identifier.id); @@ -256,6 +256,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl try { const allDepsAndPackExtensionsToInstall = await this.getAllDepsAndPackExtensions(installExtensionTask.identifier, manifest, !!installExtensionTaskOptions.installOnlyNewlyAddedFromExtensionPack, !!installExtensionTaskOptions.installPreReleaseVersion, installExtensionTaskOptions.profileLocation); const installed = await this.getInstalled(undefined, installExtensionTaskOptions.profileLocation); + const options: InstallExtensionTaskOptions = { ...installExtensionTaskOptions, donotIncludePackAndDependencies: true, context: { ...installExtensionTaskOptions.context, [EXTENSION_INSTALL_DEP_PACK_CONTEXT]: true } }; for (const { gallery, manifest } of distinct(allDepsAndPackExtensionsToInstall, ({ gallery }) => gallery.identifier.id)) { installExtensionHasDependents = installExtensionHasDependents || !!manifest.extensionDependencies?.some(id => areSameExtensions({ id }, installExtensionTask.identifier)); const key = getInstallExtensionTaskKey(gallery); @@ -279,7 +280,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl })); } } else if (!installed.some(({ identifier }) => areSameExtensions(identifier, gallery.identifier))) { - const task = this.createInstallExtensionTask(manifest, gallery, { ...installExtensionTaskOptions, donotIncludePackAndDependencies: true }); + const task = this.createInstallExtensionTask(manifest, gallery, options); this.installingExtensions.set(key, { task, waitingTasks: [installExtensionTask] }); this._onInstallExtension.fire({ identifier: task.identifier, source: gallery, profileLocation: installExtensionTaskOptions.profileLocation }); this.logService.info('Installing extension:', task.identifier.id, installExtensionTask.identifier.id); @@ -343,12 +344,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } } - const context = installExtensionTaskOptions.context ?? {}; - if (hasPackExtensions && task.identifier.id !== installExtensionTask.identifier.id) { - context[EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT] = true; - } - - installResults.push({ local, identifier: task.identifier, operation: task.operation, source: task.source, context: context, profileLocation: task.profileLocation, applicationScoped: local.isApplicationScoped }); + installResults.push({ local, identifier: task.identifier, operation: task.operation, source: task.source, context: task.options.context, profileLocation: task.profileLocation, applicationScoped: local.isApplicationScoped }); } catch (error) { if (!URI.isUri(task.source)) { reportTelemetry(this.telemetryService, task.operation === InstallOperation.Update ? 'extensionGallery:update' : 'extensionGallery:install', { diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 9a9abb281fc..dc4c1ccc02c 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -18,6 +18,7 @@ export const EXTENSION_IDENTIFIER_REGEX = new RegExp(EXTENSION_IDENTIFIER_PATTER export const WEB_EXTENSION_TAG = '__web_extension'; export const EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT = 'skipWalkthrough'; export const EXTENSION_INSTALL_SYNC_CONTEXT = 'extensionsSync'; +export const EXTENSION_INSTALL_DEP_PACK_CONTEXT = 'dependecyOrPackExtensionInstall'; export function TargetPlatformToString(targetPlatform: TargetPlatform) { switch (targetPlatform) { diff --git a/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts b/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts index 30e749ac312..40eb2584305 100644 --- a/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts +++ b/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts @@ -124,22 +124,24 @@ export abstract class AbstractExtensionsProfileScannerService extends Disposable const extensionsToRemove: IScannedProfileExtension[] = []; const extensionsToAdd: IScannedProfileExtension[] = []; try { - await this.withProfileExtensions(profileLocation, profileExtensions => { + await this.withProfileExtensions(profileLocation, existingExtensions => { const result: IScannedProfileExtension[] = []; - for (const extension of profileExtensions) { - if (extensions.some(([e]) => areSameExtensions(e.identifier, extension.identifier) && e.manifest.version !== extension.version)) { + for (const existing of existingExtensions) { + if (extensions.some(([e]) => areSameExtensions(e.identifier, existing.identifier) && e.manifest.version !== existing.version)) { // Remove the existing extension with different version - extensionsToRemove.push(extension); + extensionsToRemove.push(existing); } else { - result.push(extension); + result.push(existing); } } for (const [extension, metadata] of extensions) { - if (!result.some(e => areSameExtensions(e.identifier, extension.identifier) && e.version === extension.manifest.version)) { - // Add only if the same version of the extension is not already added - const extensionToAdd = { identifier: extension.identifier, version: extension.manifest.version, location: extension.location, metadata }; + const index = result.findIndex(e => areSameExtensions(e.identifier, extension.identifier) && e.version === extension.manifest.version); + const extensionToAdd = { identifier: extension.identifier, version: extension.manifest.version, location: extension.location, metadata }; + if (index === -1) { extensionsToAdd.push(extensionToAdd); result.push(extensionToAdd); + } else { + result.splice(index, 1, extensionToAdd); } } if (extensionsToAdd.length) { @@ -189,7 +191,6 @@ export abstract class AbstractExtensionsProfileScannerService extends Disposable async removeExtensionFromProfile(extension: IExtension, profileLocation: URI): Promise { const extensionsToRemove: IScannedProfileExtension[] = []; - this._onRemoveExtensions.fire({ extensions: extensionsToRemove, profileLocation }); try { await this.withProfileExtensions(profileLocation, profileExtensions => { const result: IScannedProfileExtension[] = []; diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 6c7b92de0ef..677149f937b 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -782,7 +782,7 @@ abstract class InstallExtensionTask extends AbstractExtensionTask { instantiationService.stub(IUserDataProfilesService, userDataProfilesService); }); + teardown(() => disposables.clear()); + + suiteTeardown(() => sinon.restore()); + test('write extensions located in the same extensions folder', async () => { const testObject = instantiationService.createInstance(TestObject, extensionsLocation); @@ -442,7 +447,247 @@ suite('ExtensionsProfileScannerService', () => { assert.deepStrictEqual(manifestContent, [{ identifier: extension.identifier, location: extension.location.toJSON(), relativeLocation: 'pub.a-1.0.0', version: extension.manifest.version }]); }); - function aExtension(id: string, location: URI, e?: Partial): IExtension { + test('add extension trigger events', async () => { + const testObject = instantiationService.createInstance(TestObject, extensionsLocation); + const target1 = sinon.stub(); + const target2 = sinon.stub(); + testObject.onAddExtensions(target1); + testObject.onDidAddExtensions(target2); + + const extensionsManifest = joinPath(extensionsLocation, 'extensions.json'); + const extension = aExtension('pub.a', joinPath(ROOT, 'foo', 'pub.a-1.0.0')); + await testObject.addExtensionsToProfile([[extension, undefined]], extensionsManifest); + + const actual = await testObject.scanProfileExtensions(extensionsManifest); + assert.deepStrictEqual(actual.map(a => ({ ...a, location: a.location.toJSON() })), [{ identifier: extension.identifier, location: extension.location.toJSON(), version: extension.manifest.version, metadata: undefined }]); + + assert.ok(target1.calledOnce); + assert.deepStrictEqual(((target1.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target1.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].identifier, extension.identifier); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].version, extension.manifest.version); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].location.toString(), extension.location.toString()); + + assert.ok(target2.calledOnce); + assert.deepStrictEqual(((target2.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target2.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].identifier, extension.identifier); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].version, extension.manifest.version); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].location.toString(), extension.location.toString()); + }); + + test('remove extension trigger events', async () => { + const testObject = instantiationService.createInstance(TestObject, extensionsLocation); + const target1 = sinon.stub(); + const target2 = sinon.stub(); + testObject.onRemoveExtensions(target1); + testObject.onDidRemoveExtensions(target2); + + const extensionsManifest = joinPath(extensionsLocation, 'extensions.json'); + const extension = aExtension('pub.a', joinPath(ROOT, 'foo', 'pub.a-1.0.0')); + await testObject.addExtensionsToProfile([[extension, undefined]], extensionsManifest); + await testObject.removeExtensionFromProfile(extension, extensionsManifest); + + const actual = await testObject.scanProfileExtensions(extensionsManifest); + assert.deepStrictEqual(actual.length, 0); + + assert.ok(target1.calledOnce); + assert.deepStrictEqual(((target1.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target1.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].identifier, extension.identifier); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].version, extension.manifest.version); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].location.toString(), extension.location.toString()); + + assert.ok(target2.calledOnce); + assert.deepStrictEqual(((target2.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target2.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].identifier, extension.identifier); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].version, extension.manifest.version); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].location.toString(), extension.location.toString()); + }); + + test('add extension with same id but different version', async () => { + const testObject = instantiationService.createInstance(TestObject, extensionsLocation); + + const extensionsManifest = joinPath(extensionsLocation, 'extensions.json'); + + const extension1 = aExtension('pub.a', joinPath(ROOT, 'pub.a-1.0.0')); + await testObject.addExtensionsToProfile([[extension1, undefined]], extensionsManifest); + + const target1 = sinon.stub(); + const target2 = sinon.stub(); + const target3 = sinon.stub(); + const target4 = sinon.stub(); + testObject.onAddExtensions(target1); + testObject.onRemoveExtensions(target2); + testObject.onDidAddExtensions(target3); + testObject.onDidRemoveExtensions(target4); + const extension2 = aExtension('pub.a', joinPath(ROOT, 'pub.a-2.0.0'), undefined, { version: '2.0.0' }); + await testObject.addExtensionsToProfile([[extension2, undefined]], extensionsManifest); + + const actual = await testObject.scanProfileExtensions(extensionsManifest); + assert.deepStrictEqual(actual.map(a => ({ ...a, location: a.location.toJSON() })), [{ identifier: extension2.identifier, location: extension2.location.toJSON(), version: extension2.manifest.version, metadata: undefined }]); + + assert.ok(target1.calledOnce); + assert.deepStrictEqual(((target1.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target1.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].identifier, extension2.identifier); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].version, extension2.manifest.version); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].location.toString(), extension2.location.toString()); + + assert.ok(target2.calledOnce); + assert.deepStrictEqual(((target2.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target2.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].identifier, extension1.identifier); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].version, extension1.manifest.version); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].location.toString(), extension1.location.toString()); + + assert.ok(target3.calledOnce); + assert.deepStrictEqual(((target1.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target1.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].identifier, extension2.identifier); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].version, extension2.manifest.version); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].location.toString(), extension2.location.toString()); + + assert.ok(target4.calledOnce); + assert.deepStrictEqual(((target2.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target2.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].identifier, extension1.identifier); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].version, extension1.manifest.version); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].location.toString(), extension1.location.toString()); + }); + + test('add same extension', async () => { + const testObject = instantiationService.createInstance(TestObject, extensionsLocation); + + const extensionsManifest = joinPath(extensionsLocation, 'extensions.json'); + + const extension = aExtension('pub.a', joinPath(ROOT, 'pub.a-1.0.0')); + await testObject.addExtensionsToProfile([[extension, undefined]], extensionsManifest); + + const target1 = sinon.stub(); + const target2 = sinon.stub(); + const target3 = sinon.stub(); + const target4 = sinon.stub(); + testObject.onAddExtensions(target1); + testObject.onRemoveExtensions(target2); + testObject.onDidAddExtensions(target3); + testObject.onDidRemoveExtensions(target4); + await testObject.addExtensionsToProfile([[extension, undefined]], extensionsManifest); + + const actual = await testObject.scanProfileExtensions(extensionsManifest); + assert.deepStrictEqual(actual.map(a => ({ ...a, location: a.location.toJSON() })), [{ identifier: extension.identifier, location: extension.location.toJSON(), version: extension.manifest.version, metadata: undefined }]); + assert.ok(target1.notCalled); + assert.ok(target2.notCalled); + assert.ok(target3.notCalled); + assert.ok(target4.notCalled); + }); + + test('add same extension with different metadata', async () => { + const testObject = instantiationService.createInstance(TestObject, extensionsLocation); + + const extensionsManifest = joinPath(extensionsLocation, 'extensions.json'); + + const extension = aExtension('pub.a', joinPath(ROOT, 'pub.a-1.0.0')); + await testObject.addExtensionsToProfile([[extension, undefined]], extensionsManifest); + + const target1 = sinon.stub(); + const target2 = sinon.stub(); + const target3 = sinon.stub(); + const target4 = sinon.stub(); + testObject.onAddExtensions(target1); + testObject.onRemoveExtensions(target2); + testObject.onDidAddExtensions(target3); + testObject.onDidRemoveExtensions(target4); + await testObject.addExtensionsToProfile([[extension, { isApplicationScoped: true }]], extensionsManifest); + + const actual = await testObject.scanProfileExtensions(extensionsManifest); + assert.deepStrictEqual(actual.map(a => ({ ...a, location: a.location.toJSON(), metadata: a.metadata })), [{ identifier: extension.identifier, location: extension.location.toJSON(), version: extension.manifest.version, metadata: { isApplicationScoped: true } }]); + assert.ok(target1.notCalled); + assert.ok(target2.notCalled); + assert.ok(target3.notCalled); + assert.ok(target4.notCalled); + }); + + test('add extension with different version and metadata', async () => { + const testObject = instantiationService.createInstance(TestObject, extensionsLocation); + + const extensionsManifest = joinPath(extensionsLocation, 'extensions.json'); + + const extension1 = aExtension('pub.a', joinPath(ROOT, 'pub.a-1.0.0')); + await testObject.addExtensionsToProfile([[extension1, undefined]], extensionsManifest); + const extension2 = aExtension('pub.a', joinPath(ROOT, 'pub.a-2.0.0'), undefined, { version: '2.0.0' }); + + const target1 = sinon.stub(); + const target2 = sinon.stub(); + const target3 = sinon.stub(); + const target4 = sinon.stub(); + testObject.onAddExtensions(target1); + testObject.onRemoveExtensions(target2); + testObject.onDidAddExtensions(target3); + testObject.onDidRemoveExtensions(target4); + await testObject.addExtensionsToProfile([[extension2, { isApplicationScoped: true }]], extensionsManifest); + + const actual = await testObject.scanProfileExtensions(extensionsManifest); + assert.deepStrictEqual(actual.map(a => ({ ...a, location: a.location.toJSON(), metadata: a.metadata })), [{ identifier: extension2.identifier, location: extension2.location.toJSON(), version: extension2.manifest.version, metadata: { isApplicationScoped: true } }]); + + assert.ok(target1.calledOnce); + assert.deepStrictEqual(((target1.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target1.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].identifier, extension2.identifier); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].version, extension2.manifest.version); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].location.toString(), extension2.location.toString()); + + assert.ok(target2.calledOnce); + assert.deepStrictEqual(((target2.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target2.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].identifier, extension1.identifier); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].version, extension1.manifest.version); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].location.toString(), extension1.location.toString()); + + assert.ok(target3.calledOnce); + assert.deepStrictEqual(((target1.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target1.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].identifier, extension2.identifier); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].version, extension2.manifest.version); + assert.deepStrictEqual(((target1.args[0][0])).extensions[0].location.toString(), extension2.location.toString()); + + assert.ok(target4.calledOnce); + assert.deepStrictEqual(((target2.args[0][0])).profileLocation.toString(), extensionsManifest.toString()); + assert.deepStrictEqual(((target2.args[0][0])).extensions.length, 1); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].identifier, extension1.identifier); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].version, extension1.manifest.version); + assert.deepStrictEqual(((target2.args[0][0])).extensions[0].location.toString(), extension1.location.toString()); + }); + + test('add extension with same id and version located in the different folder', async () => { + const testObject = instantiationService.createInstance(TestObject, extensionsLocation); + + const extensionsManifest = joinPath(extensionsLocation, 'extensions.json'); + + let extension = aExtension('pub.a', joinPath(ROOT, 'foo', 'pub.a-1.0.0')); + await testObject.addExtensionsToProfile([[extension, undefined]], extensionsManifest); + + const target1 = sinon.stub(); + const target2 = sinon.stub(); + const target3 = sinon.stub(); + const target4 = sinon.stub(); + testObject.onAddExtensions(target1); + testObject.onRemoveExtensions(target2); + testObject.onDidAddExtensions(target3); + testObject.onDidRemoveExtensions(target4); + extension = aExtension('pub.a', joinPath(ROOT, 'pub.a-1.0.0')); + await testObject.addExtensionsToProfile([[extension, undefined]], extensionsManifest); + + const actual = await testObject.scanProfileExtensions(extensionsManifest); + assert.deepStrictEqual(actual.map(a => ({ ...a, location: a.location.toJSON() })), [{ identifier: extension.identifier, location: extension.location.toJSON(), version: extension.manifest.version, metadata: undefined }]); + assert.ok(target1.notCalled); + assert.ok(target2.notCalled); + assert.ok(target3.notCalled); + assert.ok(target4.notCalled); + }); + + function aExtension(id: string, location: URI, e?: Partial, manifest?: Partial): IExtension { return { identifier: { id }, location, @@ -454,6 +699,7 @@ suite('ExtensionsProfileScannerService', () => { publisher: 'publisher', version: '1.0.0', engines: { vscode: '1.0.0' }, + ...manifest, }, isValid: true, validations: [], diff --git a/src/vs/platform/ipc/electron-sandbox/services.ts b/src/vs/platform/ipc/electron-sandbox/services.ts index 36921e83ef5..060ef30d96d 100644 --- a/src/vs/platform/ipc/electron-sandbox/services.ts +++ b/src/vs/platform/ipc/electron-sandbox/services.ts @@ -63,6 +63,20 @@ export function registerMainProcessRemoteService(id: ServiceIdentifier, ch export const ISharedProcessService = createDecorator('sharedProcessService'); export interface ISharedProcessService extends IRemoteService { + + /** + * Allows to create a `MessagePort` connection between the + * shared process and the renderer process. + * + * Use this only when you need raw IPC to the shared process + * via `postMessage` and `on('message')` of special data structures + * like typed arrays. + * + * Callers have to call `port.start()` after having installed + * listeners to enable the data flow. + */ + createRawConnection(): Promise; + notifyRestored(): void; } diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 7c5a1eb9cd6..6b698bc17f6 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -1145,7 +1145,7 @@ function workbenchTreeDataPreamble(treeRenderIndentGuidesKey); return { @@ -1162,7 +1162,7 @@ function workbenchTreeDataPreamble(treeExpandMode) === 'doubleClick'), contextViewProvider: contextViewService as IContextViewProvider, diff --git a/src/vs/platform/quickinput/browser/media/quickInput.css b/src/vs/platform/quickinput/browser/media/quickInput.css index 9bb877f9991..f6c76ccd9b5 100644 --- a/src/vs/platform/quickinput/browser/media/quickInput.css +++ b/src/vs/platform/quickinput/browser/media/quickInput.css @@ -318,3 +318,9 @@ .quick-input-list .monaco-list-row.focused .monaco-keybinding-key { background: none; } + +/* Quick input separators as full-row item */ +.quick-input-list .quick-input-list-separator-as-item { + font-weight: 600; + font-size: 12px; +} diff --git a/src/vs/platform/quickinput/browser/quickInputController.ts b/src/vs/platform/quickinput/browser/quickInputController.ts index 0328a6a6ded..f42e1ff78d1 100644 --- a/src/vs/platform/quickinput/browser/quickInputController.ts +++ b/src/vs/platform/quickinput/browser/quickInputController.ts @@ -683,7 +683,7 @@ export class QuickInputController extends Disposable { content.push(`.quick-input-list .quick-input-list-separator { color: ${this.styles.pickerGroup.pickerGroupForeground}; }`); } if (this.styles.pickerGroup.pickerGroupForeground) { - content.push(`.quick-input-list .quick-input-list-separator-as-item { color: ${this.styles.pickerGroup.pickerGroupForeground}; }`); + content.push(`.quick-input-list .quick-input-list-separator-as-item { color: var(--vscode-descriptionForeground); }`); } if (this.styles.keybindingLabel.keybindingLabelBackground || diff --git a/src/vs/platform/remote/common/managedSocket.ts b/src/vs/platform/remote/common/managedSocket.ts index 9cbf5f326e8..0f55617264d 100644 --- a/src/vs/platform/remote/common/managedSocket.ts +++ b/src/vs/platform/remote/common/managedSocket.ts @@ -4,6 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { VSBuffer, encodeBase64 } from 'vs/base/common/buffer'; +import { Emitter, Event, PauseableEmitter } from 'vs/base/common/event'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { ISocket, SocketCloseEvent, SocketDiagnostics, SocketDiagnosticsEventType } from 'vs/base/parts/ipc/common/ipc.net'; export const makeRawSocketHeaders = (path: string, query: string, deubgLabel: string) => { // https://tools.ietf.org/html/rfc6455#section-4 @@ -24,3 +27,119 @@ export const makeRawSocketHeaders = (path: string, query: string, deubgLabel: st }; export const socketRawEndHeaderSequence = VSBuffer.fromString('\r\n\r\n'); + +export interface RemoteSocketHalf { + onData: Emitter; + onClose: Emitter; + onEnd: Emitter; +} + +/** Should be called immediately after making a ManagedSocket to make it ready for data flow. */ +export async function connectManagedSocket( + socket: T, + path: string, query: string, debugLabel: string, + half: RemoteSocketHalf +): Promise { + socket.write(VSBuffer.fromString(makeRawSocketHeaders(path, query, debugLabel))); + + const d = new DisposableStore(); + try { + return await new Promise((resolve, reject) => { + let dataSoFar: VSBuffer | undefined; + d.add(socket.onData(d_1 => { + if (!dataSoFar) { + dataSoFar = d_1; + } else { + dataSoFar = VSBuffer.concat([dataSoFar, d_1], dataSoFar.byteLength + d_1.byteLength); + } + + const index = dataSoFar.indexOf(socketRawEndHeaderSequence); + if (index === -1) { + return; + } + + resolve(socket); + // pause data events until the socket consumer is hooked up. We may + // immediately emit remaining data, but if not there may still be + // microtasks queued which would fire data into the abyss. + socket.pauseData(); + + const rest = dataSoFar.slice(index + socketRawEndHeaderSequence.byteLength); + if (rest.byteLength) { + half.onData.fire(rest); + } + })); + + d.add(socket.onClose(err => reject(err ?? new Error('socket closed')))); + d.add(socket.onEnd(() => reject(new Error('socket ended')))); + }); + } catch (e) { + socket.dispose(); + throw e; + } finally { + d.dispose(); + } +} + +export abstract class ManagedSocket extends Disposable implements ISocket { + private readonly pausableDataEmitter = this._register(new PauseableEmitter()); + + public onData: Event = (...args) => { + if (this.pausableDataEmitter.isPaused) { + queueMicrotask(() => this.pausableDataEmitter.resume()); + } + return this.pausableDataEmitter.event(...args); + }; + public onClose: Event; + public onEnd: Event; + + private readonly didDisposeEmitter = this._register(new Emitter()); + public onDidDispose = this.didDisposeEmitter.event; + + private ended = false; + + protected constructor( + private readonly debugLabel: string, + half: RemoteSocketHalf, + ) { + super(); + + this._register(half.onData); + this._register(half.onData.event(data => this.pausableDataEmitter.fire(data))); + + this.onClose = this._register(half.onClose).event; + this.onEnd = this._register(half.onEnd).event; + } + + /** Pauses data events until a new listener comes in onData() */ + public pauseData() { + this.pausableDataEmitter.pause(); + } + + /** Flushes data to the socket. */ + public drain(): Promise { + return Promise.resolve(); + } + + /** Ends the remote socket. */ + public end(): void { + this.ended = true; + this.closeRemote(); + } + + public abstract write(buffer: VSBuffer): void; + protected abstract closeRemote(): void; + + traceSocketEvent(type: SocketDiagnosticsEventType, data?: any): void { + SocketDiagnostics.traceSocketEvent(this, this.debugLabel, type, data); + } + + override dispose(): void { + if (!this.ended) { + this.closeRemote(); + } + + this.didDisposeEmitter.fire(); + super.dispose(); + } +} diff --git a/src/vs/platform/sharedProcess/common/sharedProcess.ts b/src/vs/platform/sharedProcess/common/sharedProcess.ts new file mode 100644 index 00000000000..5b7e60efc80 --- /dev/null +++ b/src/vs/platform/sharedProcess/common/sharedProcess.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export const SharedProcessLifecycle = { + exit: 'vscode:electron-main->shared-process=exit', + ipcReady: 'vscode:shared-process->electron-main=ipc-ready', + initDone: 'vscode:shared-process->electron-main=init-done' +}; + +export const SharedProcessChannelConnection = { + request: 'vscode:createSharedProcessChannelConnection', + response: 'vscode:createSharedProcessChannelConnectionResult' +}; + +export const SharedProcessRawConnection = { + request: 'vscode:createSharedProcessRawConnection', + response: 'vscode:createSharedProcessRawConnectionResult' +}; diff --git a/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts b/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts index 51dd9d611a3..70059e1d7fc 100644 --- a/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts +++ b/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts @@ -18,6 +18,8 @@ import { UtilityProcess } from 'vs/platform/utilityProcess/electron-main/utility import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { parseSharedProcessDebugPort } from 'vs/platform/environment/node/environmentService'; import { assertIsDefined } from 'vs/base/common/types'; +import { SharedProcessChannelConnection, SharedProcessRawConnection, SharedProcessLifecycle } from 'vs/platform/sharedProcess/common/sharedProcess'; +import { IProductService } from 'vs/platform/product/common/productService'; export class SharedProcess extends Disposable { @@ -33,6 +35,7 @@ export class SharedProcess extends Disposable { @ILogService private readonly logService: ILogService, @ILoggerMainService private readonly loggerMainService: ILoggerMainService, @IPolicyService private readonly policyService: IPolicyService, + @IProductService private readonly productService: IProductService ) { super(); @@ -41,15 +44,18 @@ export class SharedProcess extends Disposable { private registerListeners(): void { - // Shared process connections from workbench windows - validatedIpcMain.on('vscode:createSharedProcessMessageChannel', (e, nonce: string) => this.onWindowConnection(e, nonce)); + // Shared process channel connections from workbench windows + validatedIpcMain.on(SharedProcessChannelConnection.request, (e, nonce: string) => this.onWindowConnection(e, nonce, SharedProcessChannelConnection.response)); + + // Shared process raw connections from workbench windows + validatedIpcMain.on(SharedProcessRawConnection.request, (e, nonce: string) => this.onWindowConnection(e, nonce, SharedProcessRawConnection.response)); // Lifecycle this._register(this.lifecycleMainService.onWillShutdown(() => this.onWillShutdown())); } - private async onWindowConnection(e: IpcMainEvent, nonce: string): Promise { - this.logService.trace('[SharedProcess] on vscode:createSharedProcessMessageChannel'); + private async onWindowConnection(e: IpcMainEvent, nonce: string, responseChannel: string): Promise { + this.logService.trace(`[SharedProcess] onWindowConnection for: ${responseChannel}`); // release barrier if this is the first window connection if (!this.firstWindowConnectionBarrier.isOpen()) { @@ -62,8 +68,10 @@ export class SharedProcess extends Disposable { await this.whenReady(); - // connect to the shared process - const port = await this.connect(); + // connect to the shared process passing the responseChannel + // as payload to give a hint what the connection is about + + const port = await this.connect(responseChannel); // Check back if the requesting window meanwhile closed // Since shared process is delayed on startup there is @@ -75,13 +83,13 @@ export class SharedProcess extends Disposable { } // send the port back to the requesting window - e.sender.postMessage('vscode:createSharedProcessMessageChannelResult', nonce, [port]); + e.sender.postMessage(responseChannel, nonce, [port]); } private onWillShutdown(): void { this.logService.trace('[SharedProcess] onWillShutdown'); - this.utilityProcess?.postMessage('vscode:electron-main->shared-process=exit'); + this.utilityProcess?.postMessage(SharedProcessLifecycle.exit); this.utilityProcess = undefined; } @@ -98,9 +106,9 @@ export class SharedProcess extends Disposable { const whenReady = new DeferredPromise(); if (this.utilityProcess) { - this.utilityProcess.once('vscode:shared-process->electron-main=init-done', () => whenReady.complete()); + this.utilityProcess.once(SharedProcessLifecycle.initDone, () => whenReady.complete()); } else { - validatedIpcMain.once('vscode:shared-process->electron-main=init-done', () => whenReady.complete()); + validatedIpcMain.once(SharedProcessLifecycle.initDone, () => whenReady.complete()); } await whenReady.p; @@ -125,9 +133,9 @@ export class SharedProcess extends Disposable { // Wait for shared process indicating that IPC connections are accepted const sharedProcessIpcReady = new DeferredPromise(); if (this.utilityProcess) { - this.utilityProcess.once('vscode:shared-process->electron-main=ipc-ready', () => sharedProcessIpcReady.complete()); + this.utilityProcess.once(SharedProcessLifecycle.ipcReady, () => sharedProcessIpcReady.complete()); } else { - validatedIpcMain.once('vscode:shared-process->electron-main=ipc-ready', () => sharedProcessIpcReady.complete()); + validatedIpcMain.once(SharedProcessLifecycle.ipcReady, () => sharedProcessIpcReady.complete()); } await sharedProcessIpcReady.p; @@ -156,7 +164,8 @@ export class SharedProcess extends Disposable { type: 'shared-process', entryPoint: 'vs/code/node/sharedProcess/sharedProcessMain', payload: this.createSharedProcessConfiguration(), - execArgv + execArgv, + allowLoadingUnsignedLibraries: !!process.env.VSCODE_VOICE_MODULE_PATH && this.productService.quality !== 'stable' // TODO@bpasero package }); } @@ -175,13 +184,13 @@ export class SharedProcess extends Disposable { }; } - async connect(): Promise { + async connect(payload?: unknown): Promise { // Wait for shared process being ready to accept connection await this.whenIpcReady; // Connect and return message port const utilityProcess = assertIsDefined(this.utilityProcess); - return utilityProcess.connect(); + return utilityProcess.connect(payload); } } diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 9dee3d5b41a..235d8efdbe8 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -966,6 +966,7 @@ export interface ITerminalCommandSelector { outputMatcher?: ITerminalOutputMatcher; exitStatus: boolean; commandExitResult: 'success' | 'error'; + kind?: 'fix' | 'explain'; } export interface ITerminalBackend { diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 7e017ab5ccd..31977e91c8c 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -161,9 +161,9 @@ export class PtyService extends Disposable implements IPtyService { resolve(stdout); }); }); - const processesForPort = stdout.split('\n'); + const processesForPort = stdout.split(/\r?\n/).filter(s => !!s.trim()); if (processesForPort.length >= 1) { - const capturePid = /\s+(\d+)\s+/; + const capturePid = /\s+(\d+)(?:\s+|$)/; const processId = processesForPort[0].match(capturePid)?.[1]; if (processId) { try { diff --git a/src/vs/platform/tunnel/node/tunnelService.ts b/src/vs/platform/tunnel/node/tunnelService.ts index 50eb82abc61..f28dc9e2271 100644 --- a/src/vs/platform/tunnel/node/tunnelService.ts +++ b/src/vs/platform/tunnel/node/tunnelService.ts @@ -10,14 +10,16 @@ import { NodeSocket } from 'vs/base/parts/ipc/node/ipc.net'; import { Barrier } from 'vs/base/common/async'; import { Disposable } from 'vs/base/common/lifecycle'; +import { OS } from 'vs/base/common/platform'; +import { ISocket } from 'vs/base/parts/ipc/common/ipc.net'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; -import { connectRemoteAgentTunnel, IAddressProvider, IConnectionOptions } from 'vs/platform/remote/common/remoteAgentConnection'; -import { AbstractTunnelService, isAllInterfaces, ISharedTunnelsService as ISharedTunnelsService, isLocalhost, isPortPrivileged, isTunnelProvider, ITunnelProvider, ITunnelService, RemoteTunnel, TunnelPrivacyId } from 'vs/platform/tunnel/common/tunnel'; -import { ISignService } from 'vs/platform/sign/common/sign'; -import { OS } from 'vs/base/common/platform'; +import { IAddressProvider, IConnectionOptions, connectRemoteAgentTunnel } from 'vs/platform/remote/common/remoteAgentConnection'; import { IRemoteSocketFactoryService } from 'vs/platform/remote/common/remoteSocketFactoryService'; +import { ISignService } from 'vs/platform/sign/common/sign'; +import { AbstractTunnelService, ISharedTunnelsService, ITunnelProvider, ITunnelService, RemoteTunnel, TunnelPrivacyId, isAllInterfaces, isLocalhost, isPortPrivileged, isTunnelProvider } from 'vs/platform/tunnel/common/tunnel'; +import { VSBuffer } from 'vs/base/common/buffer'; async function createRemoteTunnel(options: IConnectionOptions, defaultTunnelHost: string, tunnelRemoteHost: string, tunnelRemotePort: number, tunnelLocalPort?: number): Promise { let readyTunnel: NodeRemoteTunnel | undefined; @@ -32,7 +34,7 @@ async function createRemoteTunnel(options: IConnectionOptions, defaultTunnelHost return readyTunnel!; } -class NodeRemoteTunnel extends Disposable implements RemoteTunnel { +export class NodeRemoteTunnel extends Disposable implements RemoteTunnel { public readonly tunnelRemotePort: number; public tunnelLocalPort!: number; @@ -113,7 +115,7 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel { const tunnelRemoteHost = (isLocalhost(this.tunnelRemoteHost) || isAllInterfaces(this.tunnelRemoteHost)) ? 'localhost' : this.tunnelRemoteHost; const protocol = await connectRemoteAgentTunnel(this._options, tunnelRemoteHost, this.tunnelRemotePort); - const remoteSocket = (protocol.getSocket()).socket; + const remoteSocket = protocol.getSocket(); const dataChunk = protocol.readEntireBuffer(); protocol.dispose(); @@ -132,17 +134,19 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel { if (localSocket.localAddress) { this._socketsDispose.delete(localSocket.localAddress); } - remoteSocket.destroy(); + if (remoteSocket instanceof NodeSocket) { + remoteSocket.socket.destroy(); + } else { + remoteSocket.end(); + } }); - remoteSocket.on('end', () => localSocket.end()); - remoteSocket.on('close', () => localSocket.end()); - remoteSocket.on('error', () => { - localSocket.destroy(); - }); + if (remoteSocket instanceof NodeSocket) { + this._mirrorNodeSocket(localSocket, remoteSocket); + } else { + this._mirrorGenericSocket(localSocket, remoteSocket); + } - localSocket.pipe(remoteSocket); - remoteSocket.pipe(localSocket); if (localSocket.localAddress) { this._socketsDispose.set(localSocket.localAddress, () => { // Need to end instead of unpipe, otherwise whatever is connected locally could end up "stuck" with whatever state it had until manually exited. @@ -151,6 +155,26 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel { }); } } + + private _mirrorGenericSocket(localSocket: net.Socket, remoteSocket: ISocket) { + remoteSocket.onClose(() => localSocket.destroy()); + remoteSocket.onEnd(() => localSocket.end()); + remoteSocket.onData(d => localSocket.write(d.buffer)); + localSocket.on('data', d => remoteSocket.write(VSBuffer.wrap(d))); + localSocket.resume(); + } + + private _mirrorNodeSocket(localSocket: net.Socket, remoteNodeSocket: NodeSocket) { + const remoteSocket = remoteNodeSocket.socket; + remoteSocket.on('end', () => localSocket.end()); + remoteSocket.on('close', () => localSocket.end()); + remoteSocket.on('error', () => { + localSocket.destroy(); + }); + + remoteSocket.pipe(localSocket); + localSocket.pipe(remoteSocket); + } } export class BaseTunnelService extends AbstractTunnelService { diff --git a/src/vs/platform/voiceRecognition/node/voiceRecognitionService.ts b/src/vs/platform/voiceRecognition/node/voiceRecognitionService.ts new file mode 100644 index 00000000000..a63b58f6224 --- /dev/null +++ b/src/vs/platform/voiceRecognition/node/voiceRecognitionService.ts @@ -0,0 +1,87 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationToken } from 'vs/base/common/cancellation'; +import { ILogService } from 'vs/platform/log/common/log'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IProductService } from 'vs/platform/product/common/productService'; + +export const IVoiceRecognitionService = createDecorator('voiceRecognitionService'); + +export interface IVoiceRecognitionService { + + readonly _serviceBrand: undefined; + + /** + * Given a buffer of audio data, attempts to + * transcribe the spoken words into text. + * + * @param channelData the raw audio data obtained + * from the microphone as uncompressed PCM data: + * - 1 channel (mono) + * - 16khz sampling rate + * - 16bit sample size + */ + transcribe(channelData: Float32Array, cancellation: CancellationToken): Promise; +} + +export class VoiceRecognitionService implements IVoiceRecognitionService { + + declare readonly _serviceBrand: undefined; + + constructor( + @ILogService private readonly logService: ILogService, + @IProductService private readonly productService: IProductService + ) { } + + async transcribe(channelData: Float32Array, cancellation: CancellationToken): Promise { + this.logService.info(`[voice] transcribe(${channelData.length}): Begin`); + + const modulePath = process.env.VSCODE_VOICE_MODULE_PATH; // TODO@bpasero package + if (!modulePath || this.productService.quality === 'stable') { + this.logService.error(`[voice] transcribe(${channelData.length}): Voice recognition not yet supported`); + throw new Error('Voice recognition not yet supported!'); + } + + const now = Date.now(); + + this.logService.info(`[voice] transcribe(${channelData.length}): Getting module from ${modulePath}`); + + try { + const voiceModule: { + transcribe: ( + audioBuffer: { channelCount: 1; samplingRate: 16000; bitDepth: 16; channelData: Float32Array }, + options: { + language: string | 'auto'; + suppressNonSpeechTokens: boolean; + signal: AbortSignal; + } + ) => Promise; + } = require.__$__nodeRequire(modulePath); + + const abortController = new AbortController(); + cancellation.onCancellationRequested(() => abortController.abort()); + + const text = await voiceModule.transcribe({ + samplingRate: 16000, + bitDepth: 16, + channelCount: 1, + channelData + }, { + language: 'en', + suppressNonSpeechTokens: true, + signal: abortController.signal + }); + + this.logService.info(`[voice] transcribe(${channelData.length}): End (text: "${text}", took: ${Date.now() - now}ms)`); + + return text; + } catch (error) { + this.logService.error(`[voice] transcribe(${channelData.length}): Failed (error: "${error}", took: ${Date.now() - now}ms)`); + + throw error; + } + } +} diff --git a/src/vs/workbench/api/browser/extensionHost.contribution.ts b/src/vs/workbench/api/browser/extensionHost.contribution.ts index 774cc0cc158..8a71fe97ce1 100644 --- a/src/vs/workbench/api/browser/extensionHost.contribution.ts +++ b/src/vs/workbench/api/browser/extensionHost.contribution.ts @@ -88,6 +88,8 @@ import './mainThreadSecretState'; import './mainThreadShare'; import './mainThreadProfilContentHandlers'; import './mainThreadSemanticSimilarity'; +import './mainThreadAiRelatedInformation'; +import './mainThreadAiEmbeddingVector'; import './mainThreadIssueReporter'; export class ExtensionPoints implements IWorkbenchContribution { diff --git a/src/vs/workbench/api/browser/mainThreadAiEmbeddingVector.ts b/src/vs/workbench/api/browser/mainThreadAiEmbeddingVector.ts new file mode 100644 index 00000000000..954679e2c52 --- /dev/null +++ b/src/vs/workbench/api/browser/mainThreadAiEmbeddingVector.ts @@ -0,0 +1,41 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationToken } from 'vs/base/common/cancellation'; +import { Disposable, DisposableMap } from 'vs/base/common/lifecycle'; +import { ExtHostAiEmbeddingVectorShape, ExtHostContext, MainContext, MainThreadAiEmbeddingVectorShape } from 'vs/workbench/api/common/extHost.protocol'; +import { IAiEmbeddingVectorProvider, IAiEmbeddingVectorService } from 'vs/workbench/services/aiEmbeddingVector/common/aiEmbeddingVectorService'; +import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers'; + +@extHostNamedCustomer(MainContext.MainThreadAiEmbeddingVector) +export class MainThreadAiEmbeddingVector extends Disposable implements MainThreadAiEmbeddingVectorShape { + private readonly _proxy: ExtHostAiEmbeddingVectorShape; + private readonly _registrations = this._register(new DisposableMap()); + + constructor( + context: IExtHostContext, + @IAiEmbeddingVectorService private readonly _AiEmbeddingVectorService: IAiEmbeddingVectorService, + ) { + super(); + this._proxy = context.getProxy(ExtHostContext.ExtHostAiEmbeddingVector); + } + + $registerAiEmbeddingVectorProvider(model: string, handle: number): void { + const provider: IAiEmbeddingVectorProvider = { + provideAiEmbeddingVector: (strings: string[], token: CancellationToken) => { + return this._proxy.$provideAiEmbeddingVector( + handle, + strings, + token + ); + }, + }; + this._registrations.set(handle, this._AiEmbeddingVectorService.registerAiEmbeddingVectorProvider(model, provider)); + } + + $unregisterAiEmbeddingVectorProvider(handle: number): void { + this._registrations.deleteAndDispose(handle); + } +} diff --git a/src/vs/workbench/api/browser/mainThreadAiRelatedInformation.ts b/src/vs/workbench/api/browser/mainThreadAiRelatedInformation.ts new file mode 100644 index 00000000000..e254b5f4149 --- /dev/null +++ b/src/vs/workbench/api/browser/mainThreadAiRelatedInformation.ts @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationToken } from 'vs/base/common/cancellation'; +import { Disposable, DisposableMap } from 'vs/base/common/lifecycle'; +import { ExtHostAiRelatedInformationShape, ExtHostContext, MainContext, MainThreadAiRelatedInformationShape } from 'vs/workbench/api/common/extHost.protocol'; +import { RelatedInformationType } from 'vs/workbench/api/common/extHostTypes'; +import { IAiRelatedInformationProvider, IAiRelatedInformationService, RelatedInformationResult } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation'; +import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers'; + +@extHostNamedCustomer(MainContext.MainThreadAiRelatedInformation) +export class MainThreadAiRelatedInformation extends Disposable implements MainThreadAiRelatedInformationShape { + private readonly _proxy: ExtHostAiRelatedInformationShape; + private readonly _registrations = this._register(new DisposableMap()); + + constructor( + context: IExtHostContext, + @IAiRelatedInformationService private readonly _aiRelatedInformationService: IAiRelatedInformationService, + ) { + super(); + this._proxy = context.getProxy(ExtHostContext.ExtHostAiRelatedInformation); + } + + $getAiRelatedInformation(query: string, types: RelatedInformationType[]): Promise { + // TODO: use a real cancellation token + return this._aiRelatedInformationService.getRelatedInformation(query, types, CancellationToken.None); + } + + $registerAiRelatedInformationProvider(handle: number, type: RelatedInformationType): void { + const provider: IAiRelatedInformationProvider = { + provideAiRelatedInformation: (query, token) => { + return this._proxy.$provideAiRelatedInformation(handle, query, token); + }, + }; + this._registrations.set(handle, this._aiRelatedInformationService.registerAiRelatedInformationProvider(type, provider)); + } + + $unregisterAiRelatedInformationProvider(handle: number): void { + this._registrations.deleteAndDispose(handle); + } +} diff --git a/src/vs/workbench/api/browser/mainThreadChat.ts b/src/vs/workbench/api/browser/mainThreadChat.ts index b0621471f66..6b45f162796 100644 --- a/src/vs/workbench/api/browser/mainThreadChat.ts +++ b/src/vs/workbench/api/browser/mainThreadChat.ts @@ -5,12 +5,14 @@ import { DeferredPromise } from 'vs/base/common/async'; import { Emitter } from 'vs/base/common/event'; +import { IMarkdownString } from 'vs/base/common/htmlContent'; import { Disposable, DisposableMap } from 'vs/base/common/lifecycle'; import { revive } from 'vs/base/common/marshalling'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ExtHostChatShape, ExtHostContext, IChatRequestDto, IChatResponseProgressDto, MainContext, MainThreadChatShape } from 'vs/workbench/api/common/extHost.protocol'; import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; import { IChatContributionService } from 'vs/workbench/contrib/chat/common/chatContributionService'; +import { isCompleteInteractiveProgressTreeData } from 'vs/workbench/contrib/chat/common/chatModel'; import { IChat, IChatDynamicRequest, IChatProgress, IChatRequest, IChatResponse, IChatResponseProgressFileTreeData, IChatService } from 'vs/workbench/contrib/chat/common/chatService'; import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers'; @@ -18,13 +20,13 @@ import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/ext export class MainThreadChat extends Disposable implements MainThreadChatShape { private readonly _providerRegistrations = this._register(new DisposableMap()); - private readonly _activeRequestProgressCallbacks = new Map (DeferredPromise | void)>(); + private readonly _activeRequestProgressCallbacks = new Map (DeferredPromise | void)>(); private readonly _stateEmitters = new Map>(); private readonly _proxy: ExtHostChatShape; private _responsePartHandlePool = 0; - private readonly _activeResponsePartPromises = new Map>(); + private readonly _activeResponsePartPromises = new Map>(); constructor( extHostContext: IExtHostContext, @@ -133,7 +135,7 @@ export class MainThreadChat extends Disposable implements MainThreadChatShape { if ('placeholder' in progress) { const responsePartId = `${id}_${++this._responsePartHandlePool}`; - const deferredContentPromise = new DeferredPromise(); + const deferredContentPromise = new DeferredPromise(); this._activeResponsePartPromises.set(responsePartId, deferredContentPromise); this._activeRequestProgressCallbacks.get(id)?.({ ...progress, resolvedContent: deferredContentPromise.p }); return this._responsePartHandlePool; @@ -141,7 +143,7 @@ export class MainThreadChat extends Disposable implements MainThreadChatShape { // Complete an existing deferred promise with resolved content const responsePartId = `${id}_${responsePartHandle}`; const deferredContentPromise = this._activeResponsePartPromises.get(responsePartId); - if (deferredContentPromise && 'treeData' in progress) { + if (deferredContentPromise && isCompleteInteractiveProgressTreeData(progress)) { const withRevivedUris = revive<{ treeData: IChatResponseProgressFileTreeData }>(progress); deferredContentPromise.complete(withRevivedUris); this._activeResponsePartPromises.delete(responsePartId); @@ -152,8 +154,8 @@ export class MainThreadChat extends Disposable implements MainThreadChatShape { return; } - // No need to support standalone tree data that's not attached to a placeholder - if ('treeData' in progress) { + // No need to support standalone tree data that's not attached to a placeholder in API + if (isCompleteInteractiveProgressTreeData(progress)) { return; } diff --git a/src/vs/workbench/api/browser/mainThreadEditors.ts b/src/vs/workbench/api/browser/mainThreadEditors.ts index 552241c27d7..b5e8bb0ef56 100644 --- a/src/vs/workbench/api/browser/mainThreadEditors.ts +++ b/src/vs/workbench/api/browser/mainThreadEditors.ts @@ -23,7 +23,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editor import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; import { IEditorControl } from 'vs/workbench/common/editor'; import { getCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; diff --git a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts index 84247a03e27..fb79323e683 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts @@ -931,6 +931,13 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread } return provider.resolveDocumentOnDropFileData(requestId, dataId); } + + // --- mapped edits + + $registerMappedEditsProvider(handle: number, selector: IDocumentFilterDto[]): void { + const provider = new MainThreadMappedEditsProvider(handle, this._proxy, this._uriIdentService); + this._registrations.set(handle, this._languageFeaturesService.mappedEditsProvider.register(selector, provider)); + } } class MainThreadPasteEditProvider implements languages.DocumentPasteEditProvider { @@ -1124,3 +1131,17 @@ export class MainThreadDocumentRangeSemanticTokensProvider implements languages. throw new Error(`Unexpected`); } } + +export class MainThreadMappedEditsProvider implements languages.MappedEditsProvider { + + constructor( + private readonly _handle: number, + private readonly _proxy: ExtHostLanguageFeaturesShape, + private readonly _uriService: IUriIdentityService, + ) { } + + async provideMappedEdits(document: ITextModel, codeBlocks: string[], context: languages.MappedEditsContext, token: CancellationToken): Promise { + const res = await this._proxy.$provideMappedEdits(this._handle, document.uri, codeBlocks, context, token); + return res ? reviveWorkspaceEditDto(res, this._uriService) : null; + } +} diff --git a/src/vs/workbench/api/browser/mainThreadManagedSockets.ts b/src/vs/workbench/api/browser/mainThreadManagedSockets.ts index dbd5c34ac3e..5cae557028c 100644 --- a/src/vs/workbench/api/browser/mainThreadManagedSockets.ts +++ b/src/vs/workbench/api/browser/mainThreadManagedSockets.ts @@ -3,15 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { MainContext, ExtHostContext, MainThreadManagedSocketsShape, ExtHostManagedSocketsShape } from 'vs/workbench/api/common/extHost.protocol'; -import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; -import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; -import { ManagedRemoteConnection, RemoteConnectionType } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { VSBuffer } from 'vs/base/common/buffer'; +import { Emitter } from 'vs/base/common/event'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { ISocket, SocketCloseEventType } from 'vs/base/parts/ipc/common/ipc.net'; +import { ManagedSocket, RemoteSocketHalf, connectManagedSocket } from 'vs/platform/remote/common/managedSocket'; +import { ManagedRemoteConnection, RemoteConnectionType } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IRemoteSocketFactoryService, ISocketFactory } from 'vs/platform/remote/common/remoteSocketFactoryService'; -import { ISocket, SocketCloseEvent, SocketCloseEventType, SocketDiagnostics, SocketDiagnosticsEventType } from 'vs/base/parts/ipc/common/ipc.net'; -import { Emitter, Event, PauseableEmitter } from 'vs/base/common/event'; -import { makeRawSocketHeaders, socketRawEndHeaderSequence } from 'vs/platform/remote/common/managedSocket'; +import { ExtHostContext, ExtHostManagedSocketsShape, MainContext, MainThreadManagedSocketsShape } from 'vs/workbench/api/common/extHost.protocol'; +import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers'; @extHostNamedCustomer(MainContext.MainThreadManagedSockets) export class MainThreadManagedSockets extends Disposable implements MainThreadManagedSocketsShape { @@ -51,7 +51,7 @@ export class MainThreadManagedSockets extends Disposable implements MainThreadMa }; that._remoteSockets.set(socketId, half); - ManagedSocket.connect(socketId, that._proxy, path, query, debugLabel, half) + MainThreadManagedSocket.connect(socketId, that._proxy, path, query, debugLabel, half) .then( socket => { socket.onDidDispose(() => that._remoteSockets.delete(socketId)); @@ -91,117 +91,35 @@ export class MainThreadManagedSockets extends Disposable implements MainThreadMa } } -export interface RemoteSocketHalf { - onData: Emitter; - onClose: Emitter; - onEnd: Emitter; -} - -export class ManagedSocket extends Disposable implements ISocket { +export class MainThreadManagedSocket extends ManagedSocket { public static connect( socketId: number, proxy: ExtHostManagedSocketsShape, path: string, query: string, debugLabel: string, - half: RemoteSocketHalf - ): Promise { - const socket = new ManagedSocket(socketId, proxy, debugLabel, half.onClose, half.onData, half.onEnd); - - socket.write(VSBuffer.fromString(makeRawSocketHeaders(path, query, debugLabel))); - - const d = new DisposableStore(); - return new Promise((resolve, reject) => { - let dataSoFar: VSBuffer | undefined; - d.add(socket.onData(d => { - if (!dataSoFar) { - dataSoFar = d; - } else { - dataSoFar = VSBuffer.concat([dataSoFar, d], dataSoFar.byteLength + d.byteLength); - } - - const index = dataSoFar.indexOf(socketRawEndHeaderSequence); - if (index === -1) { - return; - } - - resolve(socket); - // pause data events until the socket consumer is hooked up. We may - // immediately emit remaining data, but if not there may still be - // microtasks queued which would fire data into the abyss. - socket.pauseData(); - - const rest = dataSoFar.slice(index + socketRawEndHeaderSequence.byteLength); - if (rest.byteLength) { - half.onData.fire(rest); - } - })); - - d.add(socket.onClose(err => reject(err ?? new Error('socket closed')))); - d.add(socket.onEnd(() => reject(new Error('socket ended')))); - }).finally(() => d.dispose()); + ): Promise { + const socket = new MainThreadManagedSocket(socketId, proxy, debugLabel, half); + return connectManagedSocket(socket, path, query, debugLabel, half); } - private readonly pausableDataEmitter = this._register(new PauseableEmitter()); - - public onData: Event = (...args) => { - if (this.pausableDataEmitter.isPaused) { - queueMicrotask(() => this.pausableDataEmitter.resume()); - } - return this.pausableDataEmitter.event(...args); - }; - public onClose: Event; - public onEnd: Event; - - private readonly didDisposeEmitter = this._register(new Emitter()); - public onDidDispose = this.didDisposeEmitter.event; - - private ended = false; - private constructor( private readonly socketId: number, private readonly proxy: ExtHostManagedSocketsShape, - private readonly debugLabel: string, - onCloseEmitter: Emitter, - onDataEmitter: Emitter, - onEndEmitter: Emitter, + debugLabel: string, + half: RemoteSocketHalf, ) { - super(); - - this._register(onDataEmitter); - this._register(onDataEmitter.event(data => this.pausableDataEmitter.fire(data))); - - this.onClose = this._register(onCloseEmitter).event; - this.onEnd = this._register(onEndEmitter).event; + super(debugLabel, half); } - /** Pauses data events until a new listener comes in onData() */ - pauseData() { - this.pausableDataEmitter.pause(); - } - - write(buffer: VSBuffer): void { + public override write(buffer: VSBuffer): void { this.proxy.$remoteSocketWrite(this.socketId, buffer); } - end(): void { - this.ended = true; + protected override closeRemote(): void { this.proxy.$remoteSocketEnd(this.socketId); } - drain(): Promise { + public override drain(): Promise { return this.proxy.$remoteSocketDrain(this.socketId); } - - traceSocketEvent(type: SocketDiagnosticsEventType, data?: any): void { - SocketDiagnostics.traceSocketEvent(this, this.debugLabel, type, data); - } - - override dispose(): void { - if (!this.ended) { - this.proxy.$remoteSocketEnd(this.socketId); - } - - this.didDisposeEmitter.fire(); - super.dispose(); - } } diff --git a/src/vs/workbench/api/browser/mainThreadStatusBar.ts b/src/vs/workbench/api/browser/mainThreadStatusBar.ts index 4e561ae88bb..00eb17f4982 100644 --- a/src/vs/workbench/api/browser/mainThreadStatusBar.ts +++ b/src/vs/workbench/api/browser/mainThreadStatusBar.ts @@ -56,7 +56,7 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape { this._store.dispose(); } - $setEntry(entryId: string, id: string, extensionId: string | undefined, name: string, text: string, tooltip: IMarkdownString | string | undefined, command: Command | undefined, color: string | ThemeColor | undefined, backgroundColor: string | ThemeColor | undefined, alignLeft: boolean, priority: number | undefined, accessibilityInformation: IAccessibilityInformation | undefined): void { + $setEntry(entryId: string, id: string, extensionId: string | undefined, name: string, text: string, tooltip: IMarkdownString | string | undefined, command: Command | undefined, color: string | ThemeColor | undefined, backgroundColor: ThemeColor | undefined, alignLeft: boolean, priority: number | undefined, accessibilityInformation: IAccessibilityInformation | undefined): void { const kind = this.statusbarService.setOrUpdateEntry(entryId, id, extensionId, name, text, tooltip, command, color, backgroundColor, alignLeft, priority, accessibilityInformation); if (kind === StatusBarUpdateKind.DidDefine) { this._store.add(toDisposable(() => this.statusbarService.unsetEntry(entryId))); diff --git a/src/vs/workbench/api/browser/mainThreadTunnelService.ts b/src/vs/workbench/api/browser/mainThreadTunnelService.ts index d41e861572b..678285a11c5 100644 --- a/src/vs/workbench/api/browser/mainThreadTunnelService.ts +++ b/src/vs/workbench/api/browser/mainThreadTunnelService.ts @@ -195,10 +195,10 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun }); } }; - this.tunnelService.setTunnelProvider(tunnelProvider); if (features) { this.tunnelService.setTunnelFeatures(features); } + this.tunnelService.setTunnelProvider(tunnelProvider); // At this point we clearly want the ports view/features since we have a tunnel factory this.contextKeyService.createKey(forwardedPortsViewEnabled.key, true); } diff --git a/src/vs/workbench/api/browser/statusBarExtensionPoint.ts b/src/vs/workbench/api/browser/statusBarExtensionPoint.ts index cd2e439f8f6..99dd3279fe8 100644 --- a/src/vs/workbench/api/browser/statusBarExtensionPoint.ts +++ b/src/vs/workbench/api/browser/statusBarExtensionPoint.ts @@ -9,7 +9,7 @@ import { localize } from 'vs/nls'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { IStatusbarService, StatusbarAlignment as MainThreadStatusBarAlignment, IStatusbarEntryAccessor, IStatusbarEntry, StatusbarAlignment, IStatusbarEntryPriority } from 'vs/workbench/services/statusbar/browser/statusbar'; +import { IStatusbarService, StatusbarAlignment as MainThreadStatusBarAlignment, IStatusbarEntryAccessor, IStatusbarEntry, StatusbarAlignment, IStatusbarEntryPriority, StatusbarEntryKind } from 'vs/workbench/services/statusbar/browser/statusbar'; import { ThemeColor } from 'vs/base/common/themables'; import { Command } from 'vs/editor/common/languages'; import { IAccessibilityInformation, isAccessibilityInformation } from 'vs/platform/accessibility/common/accessibility'; @@ -21,6 +21,7 @@ import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/ import { Iterable } from 'vs/base/common/iterator'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { asStatusBarItemIdentifier } from 'vs/workbench/api/common/extHostTypes'; +import { STATUS_BAR_ERROR_ITEM_BACKGROUND, STATUS_BAR_WARNING_ITEM_BACKGROUND } from 'vs/workbench/common/theme'; // --- service @@ -48,7 +49,7 @@ export interface IExtensionStatusBarItemService { onDidChange: Event; - setOrUpdateEntry(id: string, statusId: string, extensionId: string | undefined, name: string, text: string, tooltip: IMarkdownString | string | undefined, command: Command | undefined, color: string | ThemeColor | undefined, backgroundColor: string | ThemeColor | undefined, alignLeft: boolean, priority: number | undefined, accessibilityInformation: IAccessibilityInformation | undefined): StatusBarUpdateKind; + setOrUpdateEntry(id: string, statusId: string, extensionId: string | undefined, name: string, text: string, tooltip: IMarkdownString | string | undefined, command: Command | undefined, color: string | ThemeColor | undefined, backgroundColor: ThemeColor | undefined, alignLeft: boolean, priority: number | undefined, accessibilityInformation: IAccessibilityInformation | undefined): StatusBarUpdateKind; unsetEntry(id: string): void; @@ -75,7 +76,7 @@ class ExtensionStatusBarItemService implements IExtensionStatusBarItemService { setOrUpdateEntry(entryId: string, id: string, extensionId: string | undefined, name: string, text: string, tooltip: IMarkdownString | string | undefined, - command: Command | undefined, color: string | ThemeColor | undefined, backgroundColor: string | ThemeColor | undefined, + command: Command | undefined, color: string | ThemeColor | undefined, backgroundColor: ThemeColor | undefined, alignLeft: boolean, priority: number | undefined, accessibilityInformation: IAccessibilityInformation | undefined ): StatusBarUpdateKind { // if there are icons in the text use the tooltip for the aria label @@ -91,7 +92,16 @@ class ExtensionStatusBarItemService implements IExtensionStatusBarItemService { ariaLabel += `, ${tooltipString}`; } } - const entry: IStatusbarEntry = { name, text, tooltip, command, color, backgroundColor, ariaLabel, role }; + let kind: StatusbarEntryKind | undefined = undefined; + switch (backgroundColor?.id) { + case STATUS_BAR_ERROR_ITEM_BACKGROUND: + case STATUS_BAR_WARNING_ITEM_BACKGROUND: + // override well known colors that map to status entry kinds to support associated themable hover colors + kind = backgroundColor.id === STATUS_BAR_ERROR_ITEM_BACKGROUND ? 'error' : 'warning'; + color = undefined; + backgroundColor = undefined; + } + const entry: IStatusbarEntry = { name, text, tooltip, command, color, backgroundColor, ariaLabel, role, kind }; if (typeof priority === 'undefined') { priority = 0; diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 291edaf4e33..acdb35b1b1e 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -107,6 +107,8 @@ import { ExtHostShare } from 'vs/workbench/api/common/extHostShare'; import { ExtHostChatProvider } from 'vs/workbench/api/common/extHostChatProvider'; import { ExtHostChatSlashCommands } from 'vs/workbench/api/common/extHostChatSlashCommand'; import { ExtHostChatVariables } from 'vs/workbench/api/common/extHostChatVariables'; +import { ExtHostRelatedInformation } from 'vs/workbench/api/common/extHostAiRelatedInformation'; +import { ExtHostAiEmbeddingVector } from 'vs/workbench/api/common/extHostEmbeddingVector'; export interface IExtensionRegistries { mine: ExtensionDescriptionRegistry; @@ -211,6 +213,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I const extHostChatVariables = rpcProtocol.set(ExtHostContext.ExtHostChatVariables, new ExtHostChatVariables(rpcProtocol)); const extHostChat = rpcProtocol.set(ExtHostContext.ExtHostChat, new ExtHostChat(rpcProtocol, extHostLogService)); const extHostSemanticSimilarity = rpcProtocol.set(ExtHostContext.ExtHostSemanticSimilarity, new ExtHostSemanticSimilarity(rpcProtocol)); + const extHostAiRelatedInformation = rpcProtocol.set(ExtHostContext.ExtHostAiRelatedInformation, new ExtHostRelatedInformation(rpcProtocol)); + const extHostAiEmbeddingVector = rpcProtocol.set(ExtHostContext.ExtHostAiEmbeddingVector, new ExtHostAiEmbeddingVector(rpcProtocol)); const extHostIssueReporter = rpcProtocol.set(ExtHostContext.ExtHostIssueReporter, new ExtHostIssueReporter(rpcProtocol)); const extHostStatusBar = rpcProtocol.set(ExtHostContext.ExtHostStatusBar, new ExtHostStatusBar(rpcProtocol, extHostCommands.converter)); @@ -1323,6 +1327,18 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I registerSemanticSimilarityProvider(provider: vscode.SemanticSimilarityProvider) { checkProposedApiEnabled(extension, 'semanticSimilarity'); return extHostSemanticSimilarity.registerSemanticSimilarityProvider(extension, provider); + }, + getRelatedInformation(query: string, types: vscode.RelatedInformationType[]): Thenable { + checkProposedApiEnabled(extension, 'aiRelatedInformation'); + return extHostAiRelatedInformation.getRelatedInformation(extension, query, types); + }, + registerRelatedInformationProvider(type: vscode.RelatedInformationType, provider: vscode.RelatedInformationProvider) { + checkProposedApiEnabled(extension, 'aiRelatedInformation'); + return extHostAiRelatedInformation.registerRelatedInformationProvider(extension, type, provider); + }, + registerEmbeddingVectorProvider(model: string, provider: vscode.EmbeddingVectorProvider) { + checkProposedApiEnabled(extension, 'aiRelatedInformation'); + return extHostAiEmbeddingVector.registerEmbeddingVectorProvider(extension, model, provider); } }; @@ -1340,9 +1356,13 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I checkProposedApiEnabled(extension, 'chatRequestAccess'); return extHostChatProvider.requestChatResponseProvider(extension.identifier, id); }, - registerVariable(name, description, resolver) { + registerVariable(name: string, description: string, resolver: vscode.ChatVariableResolver) { checkProposedApiEnabled(extension, 'chatVariables'); return extHostChatVariables.registerVariableResolver(extension, name, description, resolver); + }, + registerMappedEditsProvider(selector: vscode.DocumentSelector, provider: vscode.MappedEditsProvider) { + checkProposedApiEnabled(extension, 'mappedEditsProvider'); + return extHostLanguageFeatures.registerMappedEditsProvider(extension, selector, provider); } }; @@ -1560,7 +1580,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I InteractiveEditorResponseFeedbackKind: extHostTypes.InteractiveEditorResponseFeedbackKind, StackFrameFocus: extHostTypes.StackFrameFocus, ThreadFocus: extHostTypes.ThreadFocus, - NotebookCodeActionKind: extHostTypes.NotebookCodeActionKind + NotebookCodeActionKind: extHostTypes.NotebookCodeActionKind, + RelatedInformationType: extHostTypes.RelatedInformationType }; }; } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 6886d86e0a9..82646f45cac 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -19,7 +19,7 @@ import { ISingleEditOperation } from 'vs/editor/common/core/editOperation'; import { IPosition } from 'vs/editor/common/core/position'; import { IRange } from 'vs/editor/common/core/range'; import { ISelection, Selection } from 'vs/editor/common/core/selection'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; import * as languages from 'vs/editor/common/languages'; @@ -76,6 +76,7 @@ import { ISaveProfileResult } from 'vs/workbench/services/userDataProfile/common import { IChatMessage, IChatResponseFragment, IChatResponseProviderMetadata } from 'vs/workbench/contrib/chat/common/chatProvider'; import { IChatSlashFragment } from 'vs/workbench/contrib/chat/common/chatSlashCommands'; import { IChatRequestVariableValue, IChatVariableData } from 'vs/workbench/contrib/chat/common/chatVariables'; +import { RelatedInformationResult, RelatedInformationType } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation'; export interface IWorkspaceData extends IStaticWorkspaceData { folders: { uri: UriComponents; name: string; index: number }[]; @@ -371,6 +372,16 @@ export interface IShareableItemDto { selection?: IRange; } +export interface IRelatedContextItemDto { + readonly uri: UriComponents; + readonly range: IRange; +} + +export interface IMappedEditsContextDto { + selections: ISelection[]; + related: IRelatedContextItemDto[]; +} + export interface ISignatureHelpProviderMetadataDto { readonly triggerCharacters: readonly string[]; readonly retriggerCharacters: readonly string[]; @@ -426,6 +437,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable { $resolvePasteFileData(handle: number, requestId: number, dataId: string): Promise; $resolveDocumentOnDropFileData(handle: number, requestId: number, dataId: string): Promise; $setLanguageConfiguration(handle: number, languageId: string, configuration: ILanguageConfigurationDto): void; + $registerMappedEditsProvider(handle: number, selector: IDocumentFilterDto[]): void; } export interface MainThreadLanguagesShape extends IDisposable { @@ -1204,7 +1216,7 @@ export interface IChatResponseProgressFileTreeData { children?: IChatResponseProgressFileTreeData[]; } -export type IChatResponseProgressDto = { content: string } | { requestId: string } | { placeholder: string } | { treeData: IChatResponseProgressFileTreeData }; +export type IChatResponseProgressDto = { content: string | IMarkdownString } | { requestId: string } | { placeholder: string } | { treeData: IChatResponseProgressFileTreeData }; export interface MainThreadChatShape extends IDisposable { $registerChatProvider(handle: number, id: string): Promise; @@ -1662,6 +1674,25 @@ export interface MainThreadSemanticSimilarityShape extends IDisposable { $unregisterSemanticSimilarityProvider(handle: number): void; } +export interface ExtHostAiRelatedInformationShape { + $provideAiRelatedInformation(handle: number, query: string, token: CancellationToken): Promise; +} + +export interface MainThreadAiRelatedInformationShape { + $getAiRelatedInformation(query: string, types: RelatedInformationType[]): Promise; + $registerAiRelatedInformationProvider(handle: number, type: RelatedInformationType): void; + $unregisterAiRelatedInformationProvider(handle: number): void; +} + +export interface ExtHostAiEmbeddingVectorShape { + $provideAiEmbeddingVector(handle: number, strings: string[], token: CancellationToken): Promise; +} + +export interface MainThreadAiEmbeddingVectorShape { + $registerAiEmbeddingVectorProvider(model: string, handle: number): void; + $unregisterAiEmbeddingVectorProvider(handle: number): void; +} + export interface ExtHostSecretStateShape { $onDidChangePassword(e: { extensionId: string; key: string }): Promise; } @@ -1999,6 +2030,7 @@ export interface ExtHostLanguageFeaturesShape { $provideTypeHierarchySubtypes(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise; $releaseTypeHierarchy(handle: number, sessionId: string): void; $provideDocumentOnDropEdits(handle: number, requestId: number, resource: UriComponents, position: IPosition, dataTransferDto: DataTransferDTO, token: CancellationToken): Promise; + $provideMappedEdits(handle: number, document: UriComponents, codeBlocks: string[], context: IMappedEditsContextDto, token: CancellationToken): Promise; } export interface ExtHostQuickOpenShape { @@ -2641,6 +2673,8 @@ export const MainContext = { MainThreadTesting: createProxyIdentifier('MainThreadTesting'), MainThreadLocalization: createProxyIdentifier('MainThreadLocalizationShape'), MainThreadSemanticSimilarity: createProxyIdentifier('MainThreadSemanticSimilarity'), + MainThreadAiRelatedInformation: createProxyIdentifier('MainThreadAiRelatedInformation'), + MainThreadAiEmbeddingVector: createProxyIdentifier('MainThreadAiEmbeddingVector'), MainThreadIssueReporter: createProxyIdentifier('MainThreadIssueReporter'), }; @@ -2701,6 +2735,8 @@ export const ExtHostContext = { ExtHostChatVariables: createProxyIdentifier('ExtHostChatVariables'), ExtHostChatProvider: createProxyIdentifier('ExtHostChatProvider'), ExtHostSemanticSimilarity: createProxyIdentifier('ExtHostSemanticSimilarity'), + ExtHostAiRelatedInformation: createProxyIdentifier('ExtHostAiRelatedInformation'), + ExtHostAiEmbeddingVector: createProxyIdentifier('ExtHostAiEmbeddingVector'), ExtHostTheming: createProxyIdentifier('ExtHostTheming'), ExtHostTunnelService: createProxyIdentifier('ExtHostTunnelService'), ExtHostManagedSockets: createProxyIdentifier('ExtHostManagedSockets'), diff --git a/src/vs/workbench/api/common/extHostAiRelatedInformation.ts b/src/vs/workbench/api/common/extHostAiRelatedInformation.ts new file mode 100644 index 00000000000..4cb934e1b1e --- /dev/null +++ b/src/vs/workbench/api/common/extHostAiRelatedInformation.ts @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { ExtHostAiRelatedInformationShape, IMainContext, MainContext, MainThreadAiRelatedInformationShape } from 'vs/workbench/api/common/extHost.protocol'; +import type { CancellationToken, RelatedInformationProvider, RelatedInformationType, RelatedInformationResult } from 'vscode'; +import { Disposable } from 'vs/workbench/api/common/extHostTypes'; + +export class ExtHostRelatedInformation implements ExtHostAiRelatedInformationShape { + private _relatedInformationProviders: Map = new Map(); + private _nextHandle = 0; + + private readonly _proxy: MainThreadAiRelatedInformationShape; + + constructor(mainContext: IMainContext) { + this._proxy = mainContext.getProxy(MainContext.MainThreadAiRelatedInformation); + } + + async $provideAiRelatedInformation(handle: number, query: string, token: CancellationToken): Promise { + if (this._relatedInformationProviders.size === 0) { + throw new Error('No semantic similarity providers registered'); + } + + const provider = this._relatedInformationProviders.get(handle); + if (!provider) { + throw new Error('Semantic similarity provider not found'); + } + + const result = await provider.provideRelatedInformation(query, token) ?? []; + return result; + } + + getRelatedInformation(extension: IExtensionDescription, query: string, types: RelatedInformationType[]): Promise { + return this._proxy.$getAiRelatedInformation(query, types); + } + + registerRelatedInformationProvider(extension: IExtensionDescription, type: RelatedInformationType, provider: RelatedInformationProvider): Disposable { + const handle = this._nextHandle; + this._nextHandle++; + this._relatedInformationProviders.set(handle, provider); + this._proxy.$registerAiRelatedInformationProvider(handle, type); + return new Disposable(() => { + this._proxy.$unregisterAiRelatedInformationProvider(handle); + this._relatedInformationProviders.delete(handle); + }); + } +} diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index 68db008d1b1..84545808c0f 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -464,7 +464,26 @@ const newCommands: ApiCommand[] = [ new ApiCommandArgument('value', 'The context key value', () => true, v => v), ], ApiCommandResult.Void - ) + ), + // --- mapped edits + new ApiCommand( + 'vscode.executeMappedEditsProvider', '_executeMappedEditsProvider', 'Execute Mapped Edits Provider', + [ + ApiCommandArgument.Uri, + ApiCommandArgument.StringArray, + new ApiCommandArgument( + 'MappedEditsContext', + 'Mapped Edits Context', + (v: unknown) => typeConverters.MappedEditsContext.is(v), + (v: vscode.MappedEditsContext) => typeConverters.MappedEditsContext.from(v) + ) + ], + new ApiCommandResult( + 'A promise that resolves to a workspace edit or null', + (value) => { + return value ? typeConverters.WorkspaceEdit.to(value) : null; + }) + ), ]; //#endregion diff --git a/src/vs/workbench/api/common/extHostChat.ts b/src/vs/workbench/api/common/extHostChat.ts index db4f90727ba..9aa2c625cc9 100644 --- a/src/vs/workbench/api/common/extHostChat.ts +++ b/src/vs/workbench/api/common/extHostChat.ts @@ -232,6 +232,10 @@ export class ExtHostChat implements ExtHostChatShape { const [progressHandle, progressContent] = res; this._proxy.$acceptResponseProgress(handle, sessionId, progressContent, progressHandle ?? undefined); }); + } else if ('content' in progress) { + this._proxy.$acceptResponseProgress(handle, sessionId, { + content: typeof progress.content === 'string' ? progress.content : typeConvert.MarkdownString.from(progress.content) + }); } else { this._proxy.$acceptResponseProgress(handle, sessionId, progress); } diff --git a/src/vs/workbench/api/common/extHostCommands.ts b/src/vs/workbench/api/common/extHostCommands.ts index e8fc48765c7..fd3ba6c52b9 100644 --- a/src/vs/workbench/api/common/extHostCommands.ts +++ b/src/vs/workbench/api/common/extHostCommands.ts @@ -444,6 +444,16 @@ export class ApiCommandArgument { static readonly Selection = new ApiCommandArgument('selection', 'A selection in a text document', v => extHostTypes.Selection.isSelection(v), extHostTypeConverter.Selection.from); static readonly Number = new ApiCommandArgument('number', '', v => typeof v === 'number', v => v); static readonly String = new ApiCommandArgument('string', '', v => typeof v === 'string', v => v); + static readonly StringArray = ApiCommandArgument.Arr(ApiCommandArgument.String); + + static Arr(element: ApiCommandArgument) { + return new ApiCommandArgument( + `${element.name}_array`, + `Array of ${element.name}, ${element.description}`, + (v: unknown) => Array.isArray(v) && v.every(e => element.validate(e)), + (v: T[]) => v.map(e => element.convert(e)) + ); + } static readonly CallHierarchyItem = new ApiCommandArgument('item', 'A call hierarchy item', v => v instanceof extHostTypes.CallHierarchyItem, extHostTypeConverter.CallHierarchyItem.from); static readonly TypeHierarchyItem = new ApiCommandArgument('item', 'A type hierarchy item', v => v instanceof extHostTypes.TypeHierarchyItem, extHostTypeConverter.TypeHierarchyItem.from); diff --git a/src/vs/workbench/api/common/extHostEmbeddingVector.ts b/src/vs/workbench/api/common/extHostEmbeddingVector.ts new file mode 100644 index 00000000000..20b3bcb266b --- /dev/null +++ b/src/vs/workbench/api/common/extHostEmbeddingVector.ts @@ -0,0 +1,50 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { ExtHostAiEmbeddingVectorShape, IMainContext, MainContext, MainThreadAiEmbeddingVectorShape } from 'vs/workbench/api/common/extHost.protocol'; +import type { CancellationToken, EmbeddingVectorProvider } from 'vscode'; +import { Disposable } from 'vs/workbench/api/common/extHostTypes'; + +export class ExtHostAiEmbeddingVector implements ExtHostAiEmbeddingVectorShape { + private _AiEmbeddingVectorProviders: Map = new Map(); + private _nextHandle = 0; + + private readonly _proxy: MainThreadAiEmbeddingVectorShape; + + constructor( + mainContext: IMainContext + ) { + this._proxy = mainContext.getProxy(MainContext.MainThreadAiEmbeddingVector); + } + + async $provideAiEmbeddingVector(handle: number, strings: string[], token: CancellationToken): Promise { + if (this._AiEmbeddingVectorProviders.size === 0) { + throw new Error('No embedding vector providers registered'); + } + + const provider = this._AiEmbeddingVectorProviders.get(handle); + if (!provider) { + throw new Error('Embedding vector provider not found'); + } + + const result = await provider.provideEmbeddingVector(strings, token); + if (!result) { + throw new Error('Embedding vector provider returned undefined'); + } + return result; + } + + registerEmbeddingVectorProvider(extension: IExtensionDescription, model: string, provider: EmbeddingVectorProvider): Disposable { + const handle = this._nextHandle; + this._nextHandle++; + this._AiEmbeddingVectorProviders.set(handle, provider); + this._proxy.$registerAiEmbeddingVectorProvider(model, handle); + return new Disposable(() => { + this._proxy.$unregisterAiEmbeddingVectorProvider(handle); + this._AiEmbeddingVectorProviders.delete(handle); + }); + } +} diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 34e70b79107..0a0eebdd8a5 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -532,7 +532,6 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme return that.extensionRuntime; }, get environmentVariableCollection() { return that._extHostTerminalService.getEnvironmentVariableCollection(extensionDescription); }, - getEnvironmentVariableCollection(scope?: vscode.EnvironmentVariableScope) { return that._extHostTerminalService.getEnvironmentVariableCollection(extensionDescription, scope); }, get messagePassingProtocol() { if (!messagePassingProtocol) { if (!messagePort) { @@ -862,9 +861,11 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme performance.mark(`code/extHost/willResolveAuthority/${authorityPrefix}`); result = await resolver.resolve(remoteAuthority, { resolveAttempt, execServer }); performance.mark(`code/extHost/didResolveAuthorityOK/${authorityPrefix}`); - // todo@connor4312: we probably need to chain tunnels too, how does this work with 'public' tunnels? logInfo(`setting tunnel factory...`); - this._register(await this._extHostTunnelService.setTunnelFactory(resolver)); + this._register(await this._extHostTunnelService.setTunnelFactory( + resolver, + ExtHostManagedResolvedAuthority.isManagedResolvedAuthority(result) ? result : undefined + )); } else { logInfo(`invoking resolveExecServer() for ${remoteAuthority}`); performance.mark(`code/extHost/willResolveExecServer/${authorityPrefix}`); diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index cd8b2c1de2c..ec2fbcebeef 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -1817,6 +1817,34 @@ class DocumentOnDropEditAdapter { } } +class MappedEditsAdapter { + + constructor( + private readonly _documents: ExtHostDocuments, + private readonly _provider: vscode.MappedEditsProvider, + ) { } + + async provideMappedEdits( + resource: UriComponents, + codeBlocks: string[], + context: extHostProtocol.IMappedEditsContextDto, + token: CancellationToken + ): Promise { + + const uri = URI.revive(resource); + const doc = this._documents.getDocument(uri); + + const ctx = { + selections: context.selections.map(s => typeConvert.Selection.to(s)), + related: context.related.map(r => ({ uri: URI.revive(r.uri), range: typeConvert.Range.to(r.range) })), + }; + + const mappedEdits = await this._provider.provideMappedEdits(doc, codeBlocks, ctx, token); + + return mappedEdits ? typeConvert.WorkspaceEdit.from(mappedEdits) : null; + } +} + type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter | DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentPasteEditProvider | DocumentFormattingAdapter | RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter @@ -1826,7 +1854,7 @@ type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | Hov | DocumentSemanticTokensAdapter | DocumentRangeSemanticTokensAdapter | EvaluatableExpressionAdapter | InlineValuesAdapter | LinkedEditingRangeAdapter | InlayHintsAdapter | InlineCompletionAdapter - | DocumentOnDropEditAdapter; + | DocumentOnDropEditAdapter | MappedEditsAdapter; class AdapterData { constructor( @@ -2383,7 +2411,14 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF } $provideFoldingRanges(handle: number, resource: UriComponents, context: vscode.FoldingContext, token: CancellationToken): Promise { - return this._withAdapter(handle, FoldingProviderAdapter, adapter => adapter.provideFoldingRanges(URI.revive(resource), context, token), undefined, token); + return this._withAdapter( + handle, + FoldingProviderAdapter, + (adapter) => + adapter.provideFoldingRanges(URI.revive(resource), context, token), + undefined, + token + ); } // --- smart select @@ -2462,6 +2497,19 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF Promise.resolve(adapter.provideDocumentOnDropEdits(requestId, URI.revive(resource), position, dataTransferDto, token)), undefined, undefined); } + // --- mapped edits + + registerMappedEditsProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.MappedEditsProvider): vscode.Disposable { + const handle = this._addNewAdapter(new MappedEditsAdapter(this._documents, provider), extension); + this._proxy.$registerMappedEditsProvider(handle, this._transformDocumentSelector(selector, extension)); + return this._createDisposable(handle); + } + + $provideMappedEdits(handle: number, document: UriComponents, codeBlocks: string[], context: extHostProtocol.IMappedEditsContextDto, token: CancellationToken): Promise { + return this._withAdapter(handle, MappedEditsAdapter, adapter => + Promise.resolve(adapter.provideMappedEdits(document, codeBlocks, context, token)), null, token); + } + // --- copy/paste actions registerDocumentPasteEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentPasteEditProvider, metadata: vscode.DocumentPasteProviderMetadata): vscode.Disposable { diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index d91e8fe990f..58bc387e600 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -24,7 +24,6 @@ import { ThemeColor } from 'vs/base/common/themables'; import { Promises } from 'vs/base/common/async'; import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { TerminalQuickFix, ViewColumn } from 'vs/workbench/api/common/extHostTypeConverters'; -import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; export interface IExtHostTerminalService extends ExtHostTerminalServiceShape, IDisposable { @@ -51,8 +50,13 @@ export interface IExtHostTerminalService extends ExtHostTerminalServiceShape, ID registerLinkProvider(provider: vscode.TerminalLinkProvider): vscode.Disposable; registerProfileProvider(extension: IExtensionDescription, id: string, provider: vscode.TerminalProfileProvider): vscode.Disposable; registerTerminalQuickFixProvider(id: string, extensionId: string, provider: vscode.TerminalQuickFixProvider): vscode.Disposable; - getEnvironmentVariableCollection(extension: IExtensionDescription, scope?: vscode.EnvironmentVariableScope): vscode.EnvironmentVariableCollection; + getEnvironmentVariableCollection(extension: IExtensionDescription): IEnvironmentVariableCollection; } + +interface IEnvironmentVariableCollection extends vscode.EnvironmentVariableCollection { + getScoped(scope: vscode.EnvironmentVariableScope): vscode.EnvironmentVariableCollection; +} + export interface ITerminalInternalOptions { isFeatureTerminal?: boolean; useShellEnvironment?: boolean; @@ -850,13 +854,13 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I return index; } - public getEnvironmentVariableCollection(extension: IExtensionDescription, scope?: vscode.EnvironmentVariableScope): vscode.EnvironmentVariableCollection { + public getEnvironmentVariableCollection(extension: IExtensionDescription): IEnvironmentVariableCollection { let collection = this._environmentVariableCollections.get(extension.identifier.value); if (!collection) { - collection = new UnifiedEnvironmentVariableCollection(extension); + collection = new UnifiedEnvironmentVariableCollection(); this._setEnvironmentVariableCollection(extension.identifier.value, collection); } - return collection.getScopedEnvironmentVariableCollection(scope); + return collection.getScopedEnvironmentVariableCollection(undefined); } private _syncEnvironmentVariableCollection(extensionIdentifier: string, collection: UnifiedEnvironmentVariableCollection): void { @@ -868,7 +872,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I public $initEnvironmentVariableCollections(collections: [string, ISerializableEnvironmentVariableCollection][]): void { collections.forEach(entry => { const extensionIdentifier = entry[0]; - const collection = new UnifiedEnvironmentVariableCollection(undefined, entry[1]); + const collection = new UnifiedEnvironmentVariableCollection(entry[1]); this._setEnvironmentVariableCollection(extensionIdentifier, collection); }); } @@ -913,21 +917,12 @@ class UnifiedEnvironmentVariableCollection { get onDidChangeCollection(): Event { return this._onDidChangeCollection && this._onDidChangeCollection.event; } constructor( - // HACK: Only check proposed options if extension is set (when the collection is not - // restored by serialization). This saves us from getting the extension details and - // shouldn't ever happen since you can only set them initially via the proposed check. - // TODO: This should be removed when the env var extension API(s) are stabilized - private readonly _extension: IExtensionDescription | undefined, serialized?: ISerializableEnvironmentVariableCollection ) { this.map = new Map(serialized); } - getScopedEnvironmentVariableCollection(scope: vscode.EnvironmentVariableScope | undefined): vscode.EnvironmentVariableCollection { - if (this._extension && scope) { - // TODO: This should be removed when the env var extension API(s) are stabilized - checkProposedApiEnabled(this._extension, 'envCollectionWorkspace'); - } + getScopedEnvironmentVariableCollection(scope: vscode.EnvironmentVariableScope | undefined): IEnvironmentVariableCollection { const scopedCollectionKey = this.getScopeKey(scope); let scopedCollection = this.scopedCollections.get(scopedCollectionKey); if (!scopedCollection) { @@ -939,24 +934,15 @@ class UnifiedEnvironmentVariableCollection { } replace(variable: string, value: string, options: vscode.EnvironmentVariableMutatorOptions | undefined, scope: vscode.EnvironmentVariableScope | undefined): void { - if (this._extension && options) { - checkProposedApiEnabled(this._extension, 'envCollectionOptions'); - } - this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Replace, options: options ?? {}, scope }); + this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Replace, options: options ?? { applyAtProcessCreation: true }, scope }); } append(variable: string, value: string, options: vscode.EnvironmentVariableMutatorOptions | undefined, scope: vscode.EnvironmentVariableScope | undefined): void { - if (this._extension && options) { - checkProposedApiEnabled(this._extension, 'envCollectionOptions'); - } - this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Append, options: options ?? {}, scope }); + this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Append, options: options ?? { applyAtProcessCreation: true }, scope }); } prepend(variable: string, value: string, options: vscode.EnvironmentVariableMutatorOptions | undefined, scope: vscode.EnvironmentVariableScope | undefined): void { - if (this._extension && options) { - checkProposedApiEnabled(this._extension, 'envCollectionOptions'); - } - this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Prepend, options: options ?? {}, scope }); + this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Prepend, options: options ?? { applyAtProcessCreation: true }, scope }); } private _setIfDiffers(variable: string, mutator: vscode.EnvironmentVariableMutator & { scope: vscode.EnvironmentVariableScope | undefined }): void { @@ -965,22 +951,25 @@ class UnifiedEnvironmentVariableCollection { } const key = this.getKey(variable, mutator.scope); const current = this.map.get(key); + const newOptions = mutator.options ? { + applyAtProcessCreation: mutator.options.applyAtProcessCreation ?? false, + applyAtShellIntegration: mutator.options.applyAtShellIntegration ?? false, + } : { + applyAtProcessCreation: true + }; if ( !current || current.value !== mutator.value || current.type !== mutator.type || - current.options?.applyAtProcessCreation !== (mutator.options.applyAtProcessCreation ?? true) || - current.options?.applyAtShellIntegration !== (mutator.options.applyAtShellIntegration ?? false) || + current.options?.applyAtProcessCreation !== newOptions.applyAtProcessCreation || + current.options?.applyAtShellIntegration !== newOptions.applyAtShellIntegration || current.scope?.workspaceFolder?.index !== mutator.scope?.workspaceFolder?.index ) { const key = this.getKey(variable, mutator.scope); const value: IEnvironmentVariableMutator = { variable, ...mutator, - options: { - applyAtProcessCreation: mutator.options.applyAtProcessCreation ?? true, - applyAtShellIntegration: mutator.options.applyAtShellIntegration ?? false, - } + options: newOptions }; this.map.set(key, value); this._onDidChangeCollection.fire(); @@ -1066,7 +1055,7 @@ class UnifiedEnvironmentVariableCollection { } } -class ScopedEnvironmentVariableCollection implements vscode.EnvironmentVariableCollection { +class ScopedEnvironmentVariableCollection implements IEnvironmentVariableCollection { public get persistent(): boolean { return this.collection.persistent; } public set persistent(value: boolean) { this.collection.persistent = value; @@ -1081,7 +1070,7 @@ class ScopedEnvironmentVariableCollection implements vscode.EnvironmentVariableC ) { } - getScopedEnvironmentVariableCollection(scope: vscode.EnvironmentVariableScope | undefined) { + getScoped(scope: vscode.EnvironmentVariableScope | undefined) { return this.collection.getScopedEnvironmentVariableCollection(scope); } diff --git a/src/vs/workbench/api/common/extHostTunnelService.ts b/src/vs/workbench/api/common/extHostTunnelService.ts index 34fed87a677..7040aca80d9 100644 --- a/src/vs/workbench/api/common/extHostTunnelService.ts +++ b/src/vs/workbench/api/common/extHostTunnelService.ts @@ -54,7 +54,7 @@ export interface IExtHostTunnelService extends ExtHostTunnelServiceShape { openTunnel(extension: IExtensionDescription, forward: TunnelOptions): Promise; getTunnels(): Promise; onDidChangeTunnels: vscode.Event; - setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined): Promise; + setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined, managedRemoteAuthority: vscode.ManagedResolvedAuthority | undefined): Promise; registerPortsAttributesProvider(portSelector: PortAttributesSelector, provider: vscode.PortAttributesProvider): IDisposable; registerTunnelProvider(provider: vscode.TunnelProvider, information: vscode.TunnelInformation): Promise; } @@ -165,7 +165,15 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe })); } - async setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined): Promise { + /** + * Applies the tunnel metadata and factory found in the remote authority + * resolver to the tunnel system. + * + * `managedRemoteAuthority` should be be passed if the resolver returned on. + * If this is the case, the tunnel cannot be connected to via a websocket from + * the share process, so a synethic tunnel factory is used as a default. + */ + async setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined, managedRemoteAuthority: vscode.ManagedResolvedAuthority | undefined): Promise { // Do not wait for any of the proxy promises here. // It will delay startup and there is nothing that needs to be waited for. if (provider) { @@ -176,8 +184,9 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe this._showCandidatePort = provider.showCandidatePort; this._proxy.$setCandidateFilter(); } - if (provider.tunnelFactory) { - this._forwardPortProvider = provider.tunnelFactory; + const tunnelFactory = provider.tunnelFactory ?? (managedRemoteAuthority ? this.makeManagedTunnelFactory(managedRemoteAuthority) : undefined); + if (tunnelFactory) { + this._forwardPortProvider = tunnelFactory; let privacyOptions = provider.tunnelFeatures?.privacyOptions ?? []; if (provider.tunnelFeatures?.public && (privacyOptions.length === 0)) { privacyOptions = [ @@ -210,6 +219,10 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe }); } + protected makeManagedTunnelFactory(_authority: vscode.ManagedResolvedAuthority): vscode.RemoteAuthorityResolver['tunnelFactory'] { + return undefined; // may be overridden + } + async $closeTunnel(remote: { host: string; port: number }, silent?: boolean): Promise { if (this._extensionTunnels.has(remote.host)) { const hostMap = this._extensionTunnels.get(remote.host)!; diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 9ffb8aa451b..d5939c95e25 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -1563,6 +1563,30 @@ export namespace LanguageSelector { } } +export namespace MappedEditsContext { + + export function is(v: unknown): v is vscode.MappedEditsContext { + return (!!v && + typeof v === 'object' && + 'selections' in v && + Array.isArray(v.selections) && + v.selections.every(s => s instanceof types.Selection) && + 'related' in v && + Array.isArray(v.related) && + v.related.every(e => e && typeof e === 'object' && URI.isUri(e.uri) && e.range instanceof types.Range)); + } + + export function from(extContext: vscode.MappedEditsContext): languages.MappedEditsContext { + return { + selections: extContext.selections.map(s => Selection.from(s)), + related: extContext.related.map(r => ({ + uri: URI.from(r.uri), + range: Range.from(r.range) + })) + }; + } +} + export namespace NotebookRange { export function from(range: vscode.NotebookRange): ICellRange { diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 2f2bba71433..ac36411c043 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -4117,3 +4117,14 @@ export class ChatMessage implements vscode.ChatMessage { } //#endregion + +//#region ai + +export enum RelatedInformationType { + SymbolInformation = 1, + CommandInformation = 2, + SearchInformation = 3, + SettingInformation = 4 +} + +//#endregion diff --git a/src/vs/workbench/api/node/extHost.node.services.ts b/src/vs/workbench/api/node/extHost.node.services.ts index 9a4ffa8b033..582cea087ee 100644 --- a/src/vs/workbench/api/node/extHost.node.services.ts +++ b/src/vs/workbench/api/node/extHost.node.services.ts @@ -24,6 +24,8 @@ import { NodeExtHostVariableResolverProviderService } from 'vs/workbench/api/nod import { IExtHostVariableResolverProvider } from 'vs/workbench/api/common/extHostVariableResolverService'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; +import { ISignService } from 'vs/platform/sign/common/sign'; +import { SignService } from 'vs/platform/sign/node/signService'; // ######################################################################### // ### ### @@ -34,6 +36,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; registerSingleton(IExtHostExtensionService, ExtHostExtensionService, InstantiationType.Eager); registerSingleton(ILoggerService, ExtHostLoggerService, InstantiationType.Delayed); registerSingleton(ILogService, new SyncDescriptor(ExtHostLogService, [false], true)); +registerSingleton(ISignService, SignService, InstantiationType.Delayed); registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths, InstantiationType.Eager); registerSingleton(IExtHostDebugService, ExtHostDebugService, InstantiationType.Eager); diff --git a/src/vs/workbench/api/node/extHostTunnelService.ts b/src/vs/workbench/api/node/extHostTunnelService.ts index 56e0de8c855..561f731654d 100644 --- a/src/vs/workbench/api/node/extHostTunnelService.ts +++ b/src/vs/workbench/api/node/extHostTunnelService.ts @@ -4,17 +4,26 @@ *--------------------------------------------------------------------------------------------*/ import { exec } from 'child_process'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { Emitter } from 'vs/base/common/event'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { MovingAverage } from 'vs/base/common/numbers'; import { isLinux } from 'vs/base/common/platform'; import * as resources from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import * as pfs from 'vs/base/node/pfs'; +import { ISocket, SocketCloseEventType } from 'vs/base/parts/ipc/common/ipc.net'; import { ILogService } from 'vs/platform/log/common/log'; +import { ManagedSocket, RemoteSocketHalf, connectManagedSocket } from 'vs/platform/remote/common/managedSocket'; +import { ManagedRemoteConnection } from 'vs/platform/remote/common/remoteAuthorityResolver'; +import { ISignService } from 'vs/platform/sign/common/sign'; import { isAllInterfaces, isLocalhost } from 'vs/platform/tunnel/common/tunnel'; +import { NodeRemoteTunnel } from 'vs/platform/tunnel/node/tunnelService'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { ExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelService'; import { CandidatePort } from 'vs/workbench/services/remote/common/tunnelModel'; +import * as vscode from 'vscode'; export function getSockets(stdout: string): Record { const lines = stdout.trim().split('\n'); @@ -171,8 +180,9 @@ export class NodeExtHostTunnelService extends ExtHostTunnelService { constructor( @IExtHostRpcService extHostRpc: IExtHostRpcService, - @IExtHostInitDataService initData: IExtHostInitDataService, - @ILogService logService: ILogService + @IExtHostInitDataService private readonly initData: IExtHostInitDataService, + @ILogService logService: ILogService, + @ISignService private readonly signService: ISignService, ) { super(extHostRpc, initData, logService); if (isLinux && initData.remote.isRemote && initData.remote.authority) { @@ -297,4 +307,102 @@ export class NodeExtHostTunnelService extends ExtHostTunnelService { } }); } + + protected override makeManagedTunnelFactory(authority: vscode.ManagedResolvedAuthority): vscode.RemoteAuthorityResolver['tunnelFactory'] { + return async (tunnelOptions) => { + const t = new NodeRemoteTunnel( + { + commit: this.initData.commit, + quality: this.initData.quality, + logService: this.logService, + ipcLogger: null, + // services and address providers have stubs since we don't need + // the connection identification that the renderer process uses + remoteSocketFactoryService: { + _serviceBrand: undefined, + async connect(_connectTo: ManagedRemoteConnection, path: string, query: string, debugLabel: string): Promise { + const result = await authority.makeConnection(); + return ExtHostManagedSocket.connect(result, path, query, debugLabel); + }, + register() { + throw new Error('not implemented'); + }, + }, + addressProvider: { + getAddress() { + return Promise.resolve({ + connectTo: new ManagedRemoteConnection(0), + connectionToken: authority.connectionToken, + }); + }, + }, + signService: this.signService, + }, + 'localhost', + tunnelOptions.remoteAddress.host || 'localhost', + tunnelOptions.remoteAddress.port, + tunnelOptions.localAddressPort, + ); + + await t.waitForReady(); + + const disposeEmitter = new Emitter(); + + return { + localAddress: t.localAddress, + remoteAddress: { port: t.tunnelRemotePort, host: t.tunnelRemoteHost }, + onDidDispose: disposeEmitter.event, + dispose: () => { + t.dispose(); + disposeEmitter.fire(); + disposeEmitter.dispose(); + }, + }; + }; + } +} + +class ExtHostManagedSocket extends ManagedSocket { + public static connect( + passing: vscode.ManagedMessagePassing, + path: string, query: string, debugLabel: string, + ): Promise { + const d = new DisposableStore(); + const half: RemoteSocketHalf = { + onClose: d.add(new Emitter()), + onData: d.add(new Emitter()), + onEnd: d.add(new Emitter()), + }; + + d.add(passing.onDidReceiveMessage(d => half.onData.fire(VSBuffer.wrap(d)))); + d.add(passing.onDidEnd(() => half.onEnd.fire())); + d.add(passing.onDidClose(error => half.onClose.fire({ + type: SocketCloseEventType.NodeSocketCloseEvent, + error, + hadError: !!error + }))); + + const socket = new ExtHostManagedSocket(passing, debugLabel, half); + socket._register(d); + return connectManagedSocket(socket, path, query, debugLabel, half); + } + + constructor( + private readonly passing: vscode.ManagedMessagePassing, + debugLabel: string, + half: RemoteSocketHalf, + ) { + super(debugLabel, half); + } + + public override write(buffer: VSBuffer): void { + this.passing.send(buffer.buffer); + } + protected override closeRemote(): void { + this.passing.end(); + } + + public override async drain(): Promise { + await this.passing.drain?.(); + } } diff --git a/src/vs/workbench/api/test/browser/mainThreadManagedSockets.test.ts b/src/vs/workbench/api/test/browser/mainThreadManagedSockets.test.ts index 611ec9727c0..6eb1c08ad65 100644 --- a/src/vs/workbench/api/test/browser/mainThreadManagedSockets.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadManagedSockets.test.ts @@ -10,7 +10,8 @@ import { Emitter } from 'vs/base/common/event'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { SocketCloseEvent } from 'vs/base/parts/ipc/common/ipc.net'; import { mock } from 'vs/base/test/common/mock'; -import { ManagedSocket, RemoteSocketHalf } from 'vs/workbench/api/browser/mainThreadManagedSockets'; +import { RemoteSocketHalf } from 'vs/platform/remote/common/managedSocket'; +import { MainThreadManagedSocket } from 'vs/workbench/api/browser/mainThreadManagedSockets'; import { ExtHostManagedSocketsShape } from 'vs/workbench/api/common/extHost.protocol'; suite('MainThreadManagedSockets', () => { @@ -68,7 +69,7 @@ suite('MainThreadManagedSockets', () => { }); async function doConnect() { - const socket = ManagedSocket.connect(1, extHost, '/hello', 'world=true', '', half); + const socket = MainThreadManagedSocket.connect(1, extHost, '/hello', 'world=true', '', half); await extHost.expectEvent(evt => evt.data && evt.data.startsWith('GET ws://localhost/hello?world=true&skipWebSocketFrames=true HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key:'), 'websocket open event'); half.onData.fire(VSBuffer.fromString('Opened successfully ;)\r\n\r\n')); return await socket; @@ -79,7 +80,7 @@ suite('MainThreadManagedSockets', () => { }); test('includes trailing connection data', async () => { - const socketProm = ManagedSocket.connect(1, extHost, '/hello', 'world=true', '', half); + const socketProm = MainThreadManagedSocket.connect(1, extHost, '/hello', 'world=true', '', half); await extHost.expectEvent(evt => evt.data && evt.data.includes('GET ws://localhost'), 'websocket open event'); half.onData.fire(VSBuffer.fromString('Opened successfully ;)\r\n\r\nSome trailing data')); const socket = await socketProm; diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index c196ac2132e..52afb8083d8 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -12,7 +12,7 @@ import { ITreeDragOverReaction } from 'vs/base/browser/ui/tree/tree'; import { coalesce } from 'vs/base/common/arrays'; import { UriList, VSDataTransfer } from 'vs/base/common/dataTransfer'; import { Emitter } from 'vs/base/common/event'; -import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, IDisposable, markAsSingleton } from 'vs/base/common/lifecycle'; import { stringify } from 'vs/base/common/marshalling'; import { Mimes } from 'vs/base/common/mime'; import { FileAccess, Schemas } from 'vs/base/common/network'; @@ -427,6 +427,7 @@ export class CompositeDragAndDropObserver extends Disposable { static get INSTANCE(): CompositeDragAndDropObserver { if (!CompositeDragAndDropObserver.instance) { CompositeDragAndDropObserver.instance = new CompositeDragAndDropObserver(); + markAsSingleton(CompositeDragAndDropObserver.instance); } return CompositeDragAndDropObserver.instance; @@ -523,7 +524,7 @@ export class CompositeDragAndDropObserver extends Disposable { if (callbacks.onDragEnd) { this.onDragEnd.event(e => { callbacks.onDragEnd!(e); - }); + }, this, disposableStore); } return this._register(disposableStore); diff --git a/src/vs/workbench/browser/parts/editor/accessibilityStatus.ts b/src/vs/workbench/browser/parts/editor/accessibilityStatus.ts index de65eca21f0..5160d1e2791 100644 --- a/src/vs/workbench/browser/parts/editor/accessibilityStatus.ts +++ b/src/vs/workbench/browser/parts/editor/accessibilityStatus.ts @@ -13,8 +13,6 @@ import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configur import { INotificationHandle, INotificationService, NotificationPriority } from 'vs/platform/notification/common/notification'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/workbench/services/statusbar/browser/statusbar'; -import { themeColorFromId } from 'vs/platform/theme/common/themeService'; -import { STATUS_BAR_PROMINENT_ITEM_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_FOREGROUND } from 'vs/workbench/common/theme'; export class AccessibilityStatus extends Disposable implements IWorkbenchContribution { private screenReaderNotification: INotificationHandle | null = null; @@ -71,8 +69,7 @@ export class AccessibilityStatus extends Disposable implements IWorkbenchContrib text, ariaLabel: text, command: 'showEditorScreenReaderNotification', - backgroundColor: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_BACKGROUND), - color: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_FOREGROUND) + kind: 'prominent' }, 'status.editor.screenReaderMode', StatusbarAlignment.RIGHT, 100.6); } } else { diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index 044bd29da9e..77c8985611a 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -361,6 +361,13 @@ function registerDiffEditorCommands(): void { handler: accessor => navigateInDiffEditor(accessor, true) }); + MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: GOTO_NEXT_CHANGE, + title: { value: localize('compare.nextChange', "Go to Next Change"), original: 'Go to Next Change' }, + } + }); + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: GOTO_PREVIOUS_CHANGE, weight: KeybindingWeight.WorkbenchContrib, @@ -369,6 +376,13 @@ function registerDiffEditorCommands(): void { handler: accessor => navigateInDiffEditor(accessor, false) }); + MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: GOTO_PREVIOUS_CHANGE, + title: { value: localize('compare.previousChange', "Go to Previous Change"), original: 'Go to Previous Change' }, + } + }); + function getActiveTextDiffEditor(accessor: ServicesAccessor): TextDiffEditor | undefined { const editorService = accessor.get(IEditorService); diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index c80fa632d3e..01b92a4b7e2 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -244,7 +244,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { const groupEditorsCountContext = EditorGroupEditorsCountContext.bindTo(this.scopedContextKeyService); const groupLockedContext = ActiveEditorGroupLockedContext.bindTo(this.scopedContextKeyService); - const activeEditorListener = new MutableDisposable(); + const activeEditorListener = this._register(new MutableDisposable()); const observeActiveEditor = () => { activeEditorListener.clear(); diff --git a/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts b/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts index 55d6506abab..ff8a2778c7c 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts @@ -90,7 +90,7 @@ export class EditorGroupWatermark extends Disposable { } private registerListeners(): void { - this.lifecycleService.onDidShutdown(() => this.dispose()); + this._register(this.lifecycleService.onDidShutdown(() => this.dispose())); this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('workbench.tips.enabled')) { diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index d18e4fc12f7..dcb7c46f57a 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -47,8 +47,6 @@ import { Event } from 'vs/base/common/event'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment, IStatusbarEntry } from 'vs/workbench/services/statusbar/browser/statusbar'; import { IMarker, IMarkerService, MarkerSeverity, IMarkerData } from 'vs/platform/markers/common/markers'; -import { STATUS_BAR_PROMINENT_ITEM_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_FOREGROUND } from 'vs/workbench/common/theme'; -import { themeColorFromId } from 'vs/platform/theme/common/themeService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput'; import { AutomaticLanguageDetectionLikelyWrongClassification, AutomaticLanguageDetectionLikelyWrongId, IAutomaticLanguageDetectionLikelyWrongData, ILanguageDetectionService } from 'vs/workbench/services/languageDetection/common/languageDetectionWorkerService'; @@ -381,8 +379,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { ariaLabel: text, tooltip: localize('disableTabMode', "Disable Accessibility Mode"), command: 'editor.action.toggleTabFocusMode', - backgroundColor: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_BACKGROUND), - color: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_FOREGROUND) + kind: 'prominent' }, 'status.editor.tabFocusMode', StatusbarAlignment.RIGHT, 100.7); } } else { @@ -400,8 +397,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { ariaLabel: text, tooltip: localize('disableColumnSelectionMode', "Disable Column Selection Mode"), command: 'editor.action.toggleColumnSelection', - backgroundColor: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_BACKGROUND), - color: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_FOREGROUND) + kind: 'prominent' }, 'status.editor.columnSelectionMode', StatusbarAlignment.RIGHT, 100.8); } } else { diff --git a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css index 398e3058b2e..17e17c1a758 100644 --- a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css @@ -297,6 +297,10 @@ padding-right: 5px; /* with tab sizing shrink/fixed and badges, we want a right-padding because the close button is hidden */ } +.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.tab-actions-left):not(.tab-actions-off) .tab-label { + padding-right: 5px; /* ensure that the gradient does not show when tab actions show https://github.com/microsoft/vscode/issues/189625*/ +} + .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sticky-compact:not(.has-icon) .monaco-icon-label { text-align: center; /* ensure that sticky-compact tabs without icon have label centered */ } diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index d712b1a146b..3272b3e4839 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -184,7 +184,7 @@ export class TabsTitleControl extends TitleControl { this.updateTabSizing(false); // Tabs Scrollbar - this.tabsScrollbar = this._register(this.createTabsScrollbar(this.tabsContainer)); + this.tabsScrollbar = this.createTabsScrollbar(this.tabsContainer); this.tabsAndActionsContainer.appendChild(this.tabsScrollbar.getDomNode()); // Tabs Container listeners @@ -206,19 +206,19 @@ export class TabsTitleControl extends TitleControl { } private createTabsScrollbar(scrollable: HTMLElement): ScrollableElement { - const tabsScrollbar = new ScrollableElement(scrollable, { + const tabsScrollbar = this._register(new ScrollableElement(scrollable, { horizontal: ScrollbarVisibility.Auto, horizontalScrollbarSize: this.getTabsScrollbarSizing(), vertical: ScrollbarVisibility.Hidden, scrollYToX: true, useShadows: false - }); + })); - tabsScrollbar.onScroll(e => { + this._register(tabsScrollbar.onScroll(e => { if (e.scrollLeftChanged) { scrollable.scrollLeft = e.scrollLeft; } - }); + })); return tabsScrollbar; } diff --git a/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css b/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css index 52662d0cb2e..d6897bf02d7 100644 --- a/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css +++ b/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css @@ -155,15 +155,6 @@ color: inherit; } -.monaco-workbench .part.statusbar > .items-container > .statusbar-item .status-bar-info { - color: var(--vscode-statusBarItem-prominentForeground); - background-color: var(--vscode-statusBarItem-prominentBackground); -} - -.monaco-workbench .part.statusbar > .items-container > .statusbar-item a.status-bar-info:hover:not(.disabled) { - background-color: var(--vscode-statusBarItem-prominentHoverBackground); -} - .monaco-workbench .part.statusbar > .items-container > .statusbar-item a:active:not(.disabled) { outline: 1px solid var(--vscode-contrastActiveBorder) !important; outline-offset: -1px; @@ -181,3 +172,55 @@ .monaco-workbench:not(.hc-light):not(.hc-black) .part.statusbar > .items-container > .statusbar-item a:hover:not(.disabled) { background-color: var(--vscode-statusBarItem-hoverBackground); } + +/** Status bar entry item kinds */ + +.monaco-workbench .part.statusbar > .items-container > .statusbar-item.warning-kind { + color: var(--vscode-statusBarItem-warningForeground); + background-color: var(--vscode-statusBarItem-warningBackground); +} + +.monaco-workbench .part.statusbar > .items-container > .statusbar-item.warning-kind a:hover:not(.disabled) { + color: var(--vscode-statusBarItem-warningHoverForeground); + background-color: var(--vscode-statusBarItem-warningHoverBackground) !important; +} + +.monaco-workbench .part.statusbar > .items-container > .statusbar-item.error-kind { + color: var(--vscode-statusBarItem-errorForeground); + background-color: var(--vscode-statusBarItem-errorBackground); +} + +.monaco-workbench .part.statusbar > .items-container > .statusbar-item.error-kind a:hover:not(.disabled) { + color: var(--vscode-statusBarItem-errorHoverForeground); + background-color: var(--vscode-statusBarItem-errorHoverBackground) !important; +} + +.monaco-workbench .part.statusbar > .items-container > .statusbar-item.prominent-kind { + color: var(--vscode-statusBarItem-prominentForeground); + background-color: var(--vscode-statusBarItem-prominentBackground); +} + +.monaco-workbench .part.statusbar > .items-container > .statusbar-item.prominent-kind a:hover:not(.disabled) { + color: var(--vscode-statusBarItem-prominentHoverForeground); + background-color: var(--vscode-statusBarItem-prominentHoverBackground) !important; +} + +.monaco-workbench .part.statusbar > .items-container > .statusbar-item.remote-kind { + color: var(--vscode-statusBarItem-remoteForeground); + background-color: var(--vscode-statusBarItem-remoteBackground); +} + +.monaco-workbench .part.statusbar > .items-container > .statusbar-item.remote-kind a:hover:not(.disabled) { + color: var(--vscode-statusBarItem-remoteHoverForeground); + background-color: var(--vscode-statusBarItem-remoteHoverBackground) !important; +} + +.monaco-workbench .part.statusbar > .items-container > .statusbar-item.offline-kind { + color: var(--vscode-statusBarItem-offlineForeground); + background-color: var(--vscode-statusBarItem-offlineBackground); +} + +.monaco-workbench .part.statusbar > .items-container > .statusbar-item.offline-kind a:hover:not(.disabled) { + color: var(--vscode-statusBarItem-offlineHoverForeground); + background-color: var(--vscode-statusBarItem-offlineHoverBackground) !important; +} diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts b/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts index b1988505d95..39fd753e3d6 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts @@ -8,7 +8,7 @@ import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { SimpleIconLabel } from 'vs/base/browser/ui/iconLabel/simpleIconLabel'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IStatusbarEntry, ShowTooltipCommand } from 'vs/workbench/services/statusbar/browser/statusbar'; +import { IStatusbarEntry, ShowTooltipCommand, StatusbarEntryKinds } from 'vs/workbench/services/statusbar/browser/statusbar'; import { WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { ThemeColor } from 'vs/base/common/themables'; @@ -156,6 +156,21 @@ export class StatusbarEntryItem extends Disposable { } } + const hasBackgroundColor = !!entry.backgroundColor || (entry.kind && entry.kind !== 'standard'); + + // Update: Kind + if (!this.entry || entry.kind !== this.entry.kind) { + for (const kind of StatusbarEntryKinds) { + this.container.classList.remove(`${kind}-kind`); + } + + if (entry.kind && entry.kind !== 'standard') { + this.container.classList.add(`${entry.kind}-kind`); + } + + this.container.classList.toggle('has-background-color', hasBackgroundColor); + } + // Update: Foreground if (!this.entry || entry.color !== this.entry.color) { this.applyColor(this.labelContainer, entry.color); @@ -163,7 +178,7 @@ export class StatusbarEntryItem extends Disposable { // Update: Background if (!this.entry || entry.backgroundColor !== this.entry.backgroundColor) { - this.container.classList.toggle('has-background-color', !!entry.backgroundColor); + this.container.classList.toggle('has-background-color', hasBackgroundColor); this.applyColor(this.container, entry.backgroundColor, true); } diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index 1c949d44a00..a2938f04e10 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -20,7 +20,7 @@ import { EventHelper, createStyleSheet, addDisposableListener, EventType, clearN import { IStorageService } from 'vs/platform/storage/common/storage'; import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { coalesce, equals } from 'vs/base/common/arrays'; +import { equals } from 'vs/base/common/arrays'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { ToggleStatusbarVisibilityAction } from 'vs/workbench/browser/actions/layoutActions'; import { assertIsDefined } from 'vs/base/common/types'; @@ -176,7 +176,7 @@ export class StatusbarPart extends Part implements IStatusbarService { private doAddEntry(entry: IStatusbarEntry, id: string, alignment: StatusbarAlignment, priority: IStatusbarEntryPriority): IStatusbarEntryAccessor { // View model item - const itemContainer = this.doCreateStatusItem(id, alignment, ...coalesce([entry.showBeak ? 'has-beak' : undefined])); + const itemContainer = this.doCreateStatusItem(id, alignment); const item = this.instantiationService.createInstance(StatusbarEntryItem, itemContainer, entry, this.hoverDelegate); // View model entry diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index e96e773a916..ec47bd48bca 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -32,7 +32,7 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la import { isFullscreen } from 'vs/base/browser/browser'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { BrowserFeatures } from 'vs/base/browser/canIUse'; -import { KeyCode } from 'vs/base/common/keyCodes'; +import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IsMacNativeContext, IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -440,7 +440,7 @@ export class CustomMenubarControl extends MenubarControl { id: `workbench.actions.menubar.focus`, title: { value: localize('focusMenu', "Focus Application Menu"), original: 'Focus Application Menu' }, keybinding: { - primary: KeyCode.F10, + primary: KeyMod.Alt | KeyCode.F10, weight: KeybindingWeight.WorkbenchContrib, when: IsWebContext }, diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index aedd476a89d..62ca965951c 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -613,7 +613,7 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { // Pass Focus to Viewer this.tree.domFocus(); - } else if (this.tree) { + } else if (this.tree && this.treeContainer && !this.treeContainer.classList.contains('hide')) { this.tree.domFocus(); } else { this.domNode.focus(); @@ -1017,6 +1017,9 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { this.domNode.setAttribute('tabindex', '0'); } else if (this.treeContainer) { this.treeContainer.classList.remove('hide'); + if (this.domNode === DOM.getActiveElement()) { + this.focus(); + } this.domNode.removeAttribute('tabindex'); } } @@ -1217,7 +1220,8 @@ class TreeRenderer extends Disposable implements ITreeRenderer(); + private locked = false; private preview: EditorInput | null = null; // editor in preview state @@ -405,6 +407,7 @@ export class EditorGroupModel extends Disposable { private registerEditorListeners(editor: EditorInput): void { const listeners = new DisposableStore(); + this.editorListeners.add(listeners); // Re-emit disposal of editor input as our own event listeners.add(Event.once(editor.onWillDispose)(() => { @@ -453,6 +456,7 @@ export class EditorGroupModel extends Disposable { listeners.add(this.onDidModelChange(event => { if (event.kind === GroupModelChangeKind.EDITOR_CLOSE && event.editor?.matches(editor)) { dispose(listeners); + this.editorListeners.delete(listeners); } })); } @@ -1077,4 +1081,11 @@ export class EditorGroupModel extends Disposable { return this._id; } + + override dispose(): void { + dispose(Array.from(this.editorListeners)); + this.editorListeners.clear(); + + super.dispose(); + } } diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index bc3da309318..a4a46546750 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -515,28 +515,28 @@ export const STATUS_BAR_PROMINENT_ITEM_FOREGROUND = registerColor('statusBarItem light: STATUS_BAR_FOREGROUND, hcDark: STATUS_BAR_FOREGROUND, hcLight: STATUS_BAR_FOREGROUND -}, localize('statusBarProminentItemForeground', "Status bar prominent items foreground color. Prominent items stand out from other status bar entries to indicate importance. Change mode `Toggle Tab Key Moves Focus` from command palette to see an example. The status bar is shown in the bottom of the window.")); +}, localize('statusBarProminentItemForeground', "Status bar prominent items foreground color. Prominent items stand out from other status bar entries to indicate importance. The status bar is shown in the bottom of the window.")); export const STATUS_BAR_PROMINENT_ITEM_BACKGROUND = registerColor('statusBarItem.prominentBackground', { dark: Color.black.transparent(0.5), light: Color.black.transparent(0.5), hcDark: Color.black.transparent(0.5), hcLight: Color.black.transparent(0.5), -}, localize('statusBarProminentItemBackground', "Status bar prominent items background color. Prominent items stand out from other status bar entries to indicate importance. Change mode `Toggle Tab Key Moves Focus` from command palette to see an example. The status bar is shown in the bottom of the window.")); +}, localize('statusBarProminentItemBackground', "Status bar prominent items background color. Prominent items stand out from other status bar entries to indicate importance. The status bar is shown in the bottom of the window.")); + +export const STATUS_BAR_PROMINENT_ITEM_HOVER_FOREGROUND = registerColor('statusBarItem.prominentHoverForeground', { + dark: STATUS_BAR_ITEM_HOVER_FOREGROUND, + light: STATUS_BAR_ITEM_HOVER_FOREGROUND, + hcDark: STATUS_BAR_ITEM_HOVER_FOREGROUND, + hcLight: STATUS_BAR_ITEM_HOVER_FOREGROUND +}, localize('statusBarProminentItemHoverForeground', "Status bar prominent items foreground color when hovering. Prominent items stand out from other status bar entries to indicate importance. The status bar is shown in the bottom of the window.")); export const STATUS_BAR_PROMINENT_ITEM_HOVER_BACKGROUND = registerColor('statusBarItem.prominentHoverBackground', { dark: Color.black.transparent(0.3), light: Color.black.transparent(0.3), hcDark: Color.black.transparent(0.3), hcLight: null -}, localize('statusBarProminentItemHoverBackground', "Status bar prominent items background color when hovering. Prominent items stand out from other status bar entries to indicate importance. Change mode `Toggle Tab Key Moves Focus` from command palette to see an example. The status bar is shown in the bottom of the window.")); - -export const STATUS_BAR_PROMINENT_ITEM_HOVER_FOREGROUND = registerColor('statusBarItem.prominentHoverForeground', { - dark: STATUS_BAR_FOREGROUND, - light: STATUS_BAR_FOREGROUND, - hcDark: STATUS_BAR_FOREGROUND, - hcLight: STATUS_BAR_FOREGROUND -}, localize('statusBarProminentItemHoverForeground', "Status bar prominent items foreground color when hovering. Prominent items stand out from other status bar entries to indicate importance. Change mode `Toggle Tab Key Moves Focus` from command palette to see an example. The status bar is shown in the bottom of the window.")); +}, localize('statusBarProminentItemHoverBackground', "Status bar prominent items background color when hovering. Prominent items stand out from other status bar entries to indicate importance. The status bar is shown in the bottom of the window.")); export const STATUS_BAR_ERROR_ITEM_BACKGROUND = registerColor('statusBarItem.errorBackground', { dark: darken(errorForeground, .4), @@ -552,6 +552,20 @@ export const STATUS_BAR_ERROR_ITEM_FOREGROUND = registerColor('statusBarItem.err hcLight: Color.white }, localize('statusBarErrorItemForeground', "Status bar error items foreground color. Error items stand out from other status bar entries to indicate error conditions. The status bar is shown in the bottom of the window.")); +export const STATUS_BAR_ERROR_ITEM_HOVER_FOREGROUND = registerColor('statusBarItem.errorHoverForeground', { + dark: STATUS_BAR_ITEM_HOVER_FOREGROUND, + light: STATUS_BAR_ITEM_HOVER_FOREGROUND, + hcDark: STATUS_BAR_ITEM_HOVER_FOREGROUND, + hcLight: STATUS_BAR_ITEM_HOVER_FOREGROUND +}, localize('statusBarErrorItemHoverForeground', "Status bar error items foreground color when hovering. Error items stand out from other status bar entries to indicate error conditions. The status bar is shown in the bottom of the window.")); + +export const STATUS_BAR_ERROR_ITEM_HOVER_BACKGROUND = registerColor('statusBarItem.errorHoverBackground', { + dark: STATUS_BAR_ITEM_HOVER_BACKGROUND, + light: STATUS_BAR_ITEM_HOVER_BACKGROUND, + hcDark: STATUS_BAR_ITEM_HOVER_BACKGROUND, + hcLight: STATUS_BAR_ITEM_HOVER_BACKGROUND +}, localize('statusBarErrorItemHoverBackground', "Status bar error items background color when hovering. Error items stand out from other status bar entries to indicate error conditions. The status bar is shown in the bottom of the window.")); + export const STATUS_BAR_WARNING_ITEM_BACKGROUND = registerColor('statusBarItem.warningBackground', { dark: darken(editorWarningForeground, .4), light: darken(editorWarningForeground, .4), @@ -566,6 +580,20 @@ export const STATUS_BAR_WARNING_ITEM_FOREGROUND = registerColor('statusBarItem.w hcLight: Color.white }, localize('statusBarWarningItemForeground', "Status bar warning items foreground color. Warning items stand out from other status bar entries to indicate warning conditions. The status bar is shown in the bottom of the window.")); +export const STATUS_BAR_WARNING_ITEM_HOVER_FOREGROUND = registerColor('statusBarItem.warningHoverForeground', { + dark: STATUS_BAR_ITEM_HOVER_FOREGROUND, + light: STATUS_BAR_ITEM_HOVER_FOREGROUND, + hcDark: STATUS_BAR_ITEM_HOVER_FOREGROUND, + hcLight: STATUS_BAR_ITEM_HOVER_FOREGROUND +}, localize('statusBarWarningItemHoverForeground', "Status bar warning items foreground color when hovering. Warning items stand out from other status bar entries to indicate warning conditions. The status bar is shown in the bottom of the window.")); + +export const STATUS_BAR_WARNING_ITEM_HOVER_BACKGROUND = registerColor('statusBarItem.warningHoverBackground', { + dark: STATUS_BAR_ITEM_HOVER_BACKGROUND, + light: STATUS_BAR_ITEM_HOVER_BACKGROUND, + hcDark: STATUS_BAR_ITEM_HOVER_BACKGROUND, + hcLight: STATUS_BAR_ITEM_HOVER_BACKGROUND +}, localize('statusBarWarningItemHoverBackground', "Status bar warning items background color when hovering. Warning items stand out from other status bar entries to indicate warning conditions. The status bar is shown in the bottom of the window.")); + // < --- Activity Bar --- > @@ -657,20 +685,62 @@ export const PROFILE_BADGE_FOREGROUND = registerColor('profileBadge.foreground', // < --- Remote --- > -export const STATUS_BAR_HOST_NAME_BACKGROUND = registerColor('statusBarItem.remoteBackground', { +export const STATUS_BAR_REMOTE_ITEM_BACKGROUND = registerColor('statusBarItem.remoteBackground', { dark: ACTIVITY_BAR_BADGE_BACKGROUND, light: ACTIVITY_BAR_BADGE_BACKGROUND, hcDark: ACTIVITY_BAR_BADGE_BACKGROUND, hcLight: ACTIVITY_BAR_BADGE_BACKGROUND }, localize('statusBarItemHostBackground', "Background color for the remote indicator on the status bar.")); -export const STATUS_BAR_HOST_NAME_FOREGROUND = registerColor('statusBarItem.remoteForeground', { +export const STATUS_BAR_REMOTE_ITEM_FOREGROUND = registerColor('statusBarItem.remoteForeground', { dark: ACTIVITY_BAR_BADGE_FOREGROUND, light: ACTIVITY_BAR_BADGE_FOREGROUND, hcDark: ACTIVITY_BAR_BADGE_FOREGROUND, hcLight: ACTIVITY_BAR_BADGE_FOREGROUND }, localize('statusBarItemHostForeground', "Foreground color for the remote indicator on the status bar.")); +export const STATUS_BAR_REMOTE_ITEM_HOVER_FOREGROUND = registerColor('statusBarItem.remoteHoverForeground', { + dark: STATUS_BAR_ITEM_HOVER_FOREGROUND, + light: STATUS_BAR_ITEM_HOVER_FOREGROUND, + hcDark: STATUS_BAR_ITEM_HOVER_FOREGROUND, + hcLight: STATUS_BAR_ITEM_HOVER_FOREGROUND +}, localize('statusBarRemoteItemHoverForeground', "Foreground color for the remote indicator on the status bar when hovering.")); + +export const STATUS_BAR_REMOTE_ITEM_HOVER_BACKGROUND = registerColor('statusBarItem.remoteHoverBackground', { + dark: STATUS_BAR_ITEM_HOVER_BACKGROUND, + light: STATUS_BAR_ITEM_HOVER_BACKGROUND, + hcDark: STATUS_BAR_ITEM_HOVER_BACKGROUND, + hcLight: null +}, localize('statusBarRemoteItemHoverBackground', "Background color for the remote indicator on the status bar when hovering.")); + +export const STATUS_BAR_OFFLINE_ITEM_BACKGROUND = registerColor('statusBarItem.offlineBackground', { + dark: '#6c1717', + light: '#6c1717', + hcDark: '#6c1717', + hcLight: '#6c1717' +}, localize('statusBarItemOfflineBackground', "Status bar item background color when the workbench is offline.")); + +export const STATUS_BAR_OFFLINE_ITEM_FOREGROUND = registerColor('statusBarItem.offlineForeground', { + dark: STATUS_BAR_REMOTE_ITEM_FOREGROUND, + light: STATUS_BAR_REMOTE_ITEM_FOREGROUND, + hcDark: STATUS_BAR_REMOTE_ITEM_FOREGROUND, + hcLight: STATUS_BAR_REMOTE_ITEM_FOREGROUND +}, localize('statusBarItemOfflineForeground', "Status bar item foreground color when the workbench is offline.")); + +export const STATUS_BAR_OFFLINE_ITEM_HOVER_FOREGROUND = registerColor('statusBarItem.offlineHoverForeground', { + dark: STATUS_BAR_ITEM_HOVER_FOREGROUND, + light: STATUS_BAR_ITEM_HOVER_FOREGROUND, + hcDark: STATUS_BAR_ITEM_HOVER_FOREGROUND, + hcLight: STATUS_BAR_ITEM_HOVER_FOREGROUND +}, localize('statusBarOfflineItemHoverForeground', "Status bar item foreground hover color when the workbench is offline.")); + +export const STATUS_BAR_OFFLINE_ITEM_HOVER_BACKGROUND = registerColor('statusBarItem.offlineHoverBackground', { + dark: STATUS_BAR_ITEM_HOVER_BACKGROUND, + light: STATUS_BAR_ITEM_HOVER_BACKGROUND, + hcDark: STATUS_BAR_ITEM_HOVER_BACKGROUND, + hcLight: null +}, localize('statusBarOfflineItemHoverBackground', "Status bar item background hover color when the workbench is offline.")); + export const EXTENSION_BADGE_REMOTE_BACKGROUND = registerColor('extensionBadge.remoteBackground', { dark: ACTIVITY_BAR_BADGE_BACKGROUND, light: ACTIVITY_BAR_BADGE_BACKGROUND, diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts b/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts index 80cdebaab8e..cfab22c7cc3 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts @@ -101,7 +101,7 @@ class AccessibilityHelpProvider implements IAccessibleContentProvider { } else { content.push(this._descriptionForCommand(ToggleTabFocusModeAction.ID, AccessibilityHelpNLS.tabFocusModeOffMsg, AccessibilityHelpNLS.tabFocusModeOffMsgNoKb)); } - return content.join('\n'); + return content.join('\n\n'); } } @@ -282,7 +282,6 @@ export class InlineCompletionsAccessibleViewContribution extends Disposable { this._register(AccessibleViewAction.addImplementation(95, 'inline-completions', accessor => { const accessibleViewService = accessor.get(IAccessibleViewService); const codeEditorService = accessor.get(ICodeEditorService); - const contextViewService = accessor.get(IContextViewService); const show = () => { const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); if (!editor) { @@ -311,12 +310,12 @@ export class InlineCompletionsAccessibleViewContribution extends Disposable { editor.focus(); }, next() { - contextViewService.hideContextView(); - setTimeout(() => model.next().then(() => show()), 50); + model.next(); + setTimeout(() => show(), 50); }, previous() { - contextViewService.hideContextView(); - setTimeout(() => model.previous().then(() => show()), 50); + model.previous(); + setTimeout(() => show(), 50); }, options: this._options }); diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 16095809d8c..02c1f17b6f6 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -3,13 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { EventType, addDisposableListener } from 'vs/base/browser/dom'; +import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar'; import { alert } from 'vs/base/browser/ui/aria/aria'; +import { IAction } from 'vs/base/common/actions'; +import { Codicon } from 'vs/base/common/codicons'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { marked } from 'vs/base/common/marked/marked'; import { isMacintosh } from 'vs/base/common/platform'; +import { ThemeIcon } from 'vs/base/common/themables'; import { URI } from 'vs/base/common/uri'; import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration'; import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions'; @@ -20,6 +24,7 @@ import { AccessibilityHelpNLS } from 'vs/editor/common/standaloneStrings'; import { CodeActionController } from 'vs/editor/contrib/codeAction/browser/codeActionController'; import { localize } from 'vs/nls'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { WorkbenchToolBar } from 'vs/platform/actions/browser/toolbar'; import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -31,13 +36,9 @@ import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IPickerQuickAccessItem } from 'vs/platform/quickinput/browser/pickerQuickAccess'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; -import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands'; import { AccessibilityVerbositySettingId, accessibilityHelpIsShown, accessibleViewCurrentProviderId, accessibleViewGoToSymbolSupported, accessibleViewIsShown, accessibleViewSupportsNavigation, accessibleViewVerbosityEnabled } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; +import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands'; import { getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions'; -import { IAction } from 'vs/base/common/actions'; -import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; -import { Codicon } from 'vs/base/common/codicons'; -import { ThemeIcon } from 'vs/base/common/themables'; const enum DIMENSIONS { MAX_WIDTH = 600 @@ -53,7 +54,7 @@ export interface IAccessibleContentProvider { actions?: IAction[]; provideContent(): string; onClose(): void; - onKeyDown?(e: IKeyboardEvent): void; + onKeyUp?(e: IKeyboardEvent): void; previous?(): void; next?(): void; /** @@ -107,6 +108,7 @@ class AccessibleView extends Disposable { private _editorContainer: HTMLElement; private _currentProvider: IAccessibleContentProvider | undefined; private readonly _toolbar: WorkbenchToolBar; + private _currentContent: string | undefined; constructor( @IOpenerService private readonly _openerService: IOpenerService, @@ -168,6 +170,16 @@ class AccessibleView extends Disposable { this._updateToolbar(this._currentProvider.actions, this._currentProvider.options.type); } })); + this._register(this._editorWidget.onDidDispose(() => this._resetContextKeys())); + } + + private _resetContextKeys(): void { + this._accessiblityHelpIsShown.reset(); + this._accessibleViewIsShown.reset(); + this._accessibleViewSupportsNavigation.reset(); + this._accessibleViewVerbosityEnabled.reset(); + this._accessibleViewGoToSymbolSupported.reset(); + this._accessibleViewCurrentProviderId.reset(); } show(provider?: IAccessibleContentProvider, symbol?: IAccessibleViewSymbol, showAccessibleViewHelp?: boolean): void { @@ -184,7 +196,7 @@ class AccessibleView extends Disposable { onHide: () => { if (!showAccessibleViewHelp) { this._currentProvider = undefined; - this._accessibleViewCurrentProviderId.reset(); + this._resetContextKeys(); } } }; @@ -216,10 +228,10 @@ class AccessibleView extends Disposable { } getSymbols(): IAccessibleViewSymbol[] | undefined { - if (!this._currentProvider) { + if (!this._currentProvider || !this._currentContent) { return; } - const tokens = this._currentProvider.options.language && this._currentProvider.options.language !== 'markdown' ? this._currentProvider.getSymbols?.() : marked.lexer(this._currentProvider.provideContent()); + const tokens = this._currentProvider.options.language && this._currentProvider.options.language !== 'markdown' ? this._currentProvider.getSymbols?.() : marked.lexer(this._currentContent); if (!tokens) { return; } @@ -256,12 +268,16 @@ class AccessibleView extends Disposable { } showSymbol(provider: IAccessibleContentProvider, symbol: IAccessibleViewSymbol): void { - const index = provider.provideContent().split('\n').findIndex(line => line.includes(symbol.info.split('\n')[0]) || (symbol.firstListItem && line.includes(symbol.firstListItem))) ?? -1; + if (!this._currentContent) { + return; + } + const index = this._currentContent.split('\n').findIndex(line => line.includes(symbol.info.split('\n')[0]) || (symbol.firstListItem && line.includes(symbol.firstListItem))) ?? -1; if (index >= 0) { this.show(provider); this._editorWidget.revealLine(index + 1); this._editorWidget.setSelection({ startLineNumber: index + 1, startColumn: 1, endLineNumber: index + 1, endColumn: 1 }); } + this._updateContextKeys(provider, true); } disableHint(): void { @@ -275,10 +291,10 @@ class AccessibleView extends Disposable { private _updateContextKeys(provider: IAccessibleContentProvider, shown: boolean): void { if (provider.options.type === AccessibleViewType.Help) { this._accessiblityHelpIsShown.set(shown); - this._accessibleViewIsShown.set(!shown); + this._accessibleViewIsShown.reset(); } else { this._accessibleViewIsShown.set(shown); - this._accessiblityHelpIsShown.set(!shown); + this._accessiblityHelpIsShown.reset(); } if (provider.next && provider.previous) { this._accessibleViewSupportsNavigation.set(true); @@ -296,9 +312,8 @@ class AccessibleView extends Disposable { this._currentProvider = provider; this._accessibleViewCurrentProviderId.set(provider.verbositySettingKey.replaceAll('accessibility.verbosity.', '')); } - this._updateContextKeys(provider, true); const value = this._configurationService.getValue(provider.verbositySettingKey); - const readMoreLink = provider.options.readMoreUrl ? localize("openDoc", "\nPress H now to open a browser window with more information related to accessibility.\n") : ''; + const readMoreLink = provider.options.readMoreUrl ? localize("openDoc", "\n\nPress H now to open a browser window with more information related to accessibility.\n\n") : ''; let disableHelpHint = ''; if (provider.options.type === AccessibleViewType.Help && !!value) { disableHelpHint = this._getDisableVerbosityHint(provider.verbositySettingKey); @@ -320,9 +335,10 @@ class AccessibleView extends Disposable { } } - const fragment = message + provider.provideContent() + readMoreLink + disableHelpHint + localize('exit-tip', '\nExit this dialog via the Escape key.'); + this._currentContent = message + provider.provideContent() + readMoreLink + disableHelpHint + localize('exit-tip', '\n\nExit this dialog via the Escape key.'); + this._updateContextKeys(provider, true); - this._getTextModel(URI.from({ path: `accessible-view-${provider.verbositySettingKey}`, scheme: 'accessible-view', fragment })).then((model) => { + this._getTextModel(URI.from({ path: `accessible-view-${provider.verbositySettingKey}`, scheme: 'accessible-view', fragment: this._currentContent })).then((model) => { if (!model) { return; } @@ -350,15 +366,18 @@ class AccessibleView extends Disposable { }); this._updateToolbar(provider.actions, provider.options.type); + const handleEscape = (e: KeyboardEvent | IKeyboardEvent): void => { + e.stopPropagation(); + this._contextViewService.hideContextView(); + this._updateContextKeys(provider, false); + // HACK: Delay to allow the context view to hide #186514 + setTimeout(() => provider.onClose(), 100); + }; const disposableStore = new DisposableStore(); - disposableStore.add(this._editorWidget.onKeyUp((e) => provider.onKeyDown?.(e))); + disposableStore.add(this._editorWidget.onKeyUp((e) => provider.onKeyUp?.(e))); disposableStore.add(this._editorWidget.onKeyDown((e) => { if (e.keyCode === KeyCode.Escape) { - e.stopPropagation(); - this._contextViewService.hideContextView(); - this._updateContextKeys(provider, false); - // HACK: Delay to allow the context view to hide #186514 - setTimeout(() => provider.onClose(), 100); + handleEscape(e); } else if (e.keyCode === KeyCode.KeyH && provider.options.readMoreUrl) { const url: string = provider.options.readMoreUrl!; alert(AccessibilityHelpNLS.openingDocs); @@ -367,6 +386,12 @@ class AccessibleView extends Disposable { e.stopPropagation(); } })); + disposableStore.add(addDisposableListener(this._toolbar.getElement(), EventType.KEY_DOWN, (e: KeyboardEvent) => { + const keyboardEvent = new StandardKeyboardEvent(e); + if (keyboardEvent.equals(KeyCode.Escape)) { + handleEscape(e); + } + })); disposableStore.add(this._editorWidget.onDidBlurEditorWidget(() => { if (document.activeElement !== this._toolbar.getElement()) { this._contextViewService.hideContextView(); @@ -414,7 +439,7 @@ class AccessibleView extends Disposable { if (!this._currentProvider) { return false; } - return this._currentProvider.options.language === 'markdown' || this._currentProvider.options.language === undefined || !!this._currentProvider.getSymbols; + return this._currentProvider.options.type === AccessibleViewType.Help || this._currentProvider.options.language === 'markdown' || this._currentProvider.options.language === undefined || !!this._currentProvider.getSymbols; } public showAccessibleViewHelp(): void { diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts index c62bcf7782b..9133dc3fd82 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts @@ -84,7 +84,7 @@ class AccessibleViewGoToSymbolAction extends Action2 { constructor() { super({ id: AccessibilityCommandId.GoToSymbol, - precondition: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewGoToSymbolSupported), + precondition: ContextKeyExpr.and(ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown), accessibleViewGoToSymbolSupported), keybinding: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyO, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Period], @@ -95,7 +95,7 @@ class AccessibleViewGoToSymbolAction extends Action2 { commandPalette, { ...accessibleViewMenu, - when: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewSupportsNavigation), + when: ContextKeyExpr.and(ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown), accessibleViewGoToSymbolSupported), } ], title: localize('editor.action.accessibleViewGoToSymbol', "Go To Symbol in Accessible View") diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts b/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts index f8c40b935f7..e277b372021 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts @@ -45,7 +45,7 @@ export function getAccessibilityHelpText(accessor: ServicesAccessor, type: 'pane content.push(localize('inlineChat.toolbar', "Use tab to reach conditional parts like commands, status, message responses and more.")); } content.push(localize('chat.audioCues', "Audio cues can be changed via settings with a prefix of audioCues.chat. By default, if a request takes more than 4 seconds, you will hear an audio cue indicating that progress is still occurring.")); - return content.join('\n'); + return content.join('\n\n'); } function descriptionForCommand(commandId: string, msg: string, noKbMsg: string, keybindingService: IKeybindingService): string { diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts index e9c9089baf6..3761e137dc5 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { Codicon } from 'vs/base/common/codicons'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { ICodeEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser'; @@ -30,6 +31,8 @@ import { CellKind, NOTEBOOK_EDITOR_ID } from 'vs/workbench/contrib/notebook/comm import { ITerminalEditorService, ITerminalGroupService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { WorkspaceEdit, RelatedContextItem } from 'vs/editor/common/languages'; export interface IChatCodeBlockActionContext { code: string; @@ -232,17 +235,44 @@ export function registerChatCodeBlockActions() { this.notifyUserAction(accessor, context); } - private async handleTextEditor(accessor: ServicesAccessor, codeEditor: ICodeEditor, activeModel: ITextModel, context: IChatCodeBlockActionContext) { - this.notifyUserAction(accessor, context); + private async handleTextEditor(accessor: ServicesAccessor, codeEditor: ICodeEditor, activeModel: ITextModel, chatCodeBlockActionContext: IChatCodeBlockActionContext) { + this.notifyUserAction(accessor, chatCodeBlockActionContext); + const bulkEditService = accessor.get(IBulkEditService); const codeEditorService = accessor.get(ICodeEditorService); - const activeSelection = codeEditor.getSelection() ?? new Range(activeModel.getLineCount(), 1, activeModel.getLineCount(), 1); - await bulkEditService.apply([new ResourceTextEdit(activeModel.uri, { - range: activeSelection, - text: context.code, - })]); + const mappedEditsProviders = accessor.get(ILanguageFeaturesService).mappedEditsProvider.ordered(activeModel); + // try applying workspace edit that was returned by a MappedEditsProvider, else simply insert at selection + + let workspaceEdit: WorkspaceEdit | null = null; + + if (mappedEditsProviders.length > 0) { + const mostRelevantProvider = mappedEditsProviders[0]; + + const selections = codeEditor.getSelections() ?? []; + const mappedEditsContext = { + selections, + related: [] as RelatedContextItem[], // TODO@ulugbekna: we do have not yet decided what to populate this with + }; + const cancellationTokenSource = new CancellationTokenSource(); + + workspaceEdit = await mostRelevantProvider.provideMappedEdits( + activeModel, + [chatCodeBlockActionContext.code], + mappedEditsContext, + cancellationTokenSource.token); + } + + if (workspaceEdit) { + await bulkEditService.apply(workspaceEdit); + } else { + const activeSelection = codeEditor.getSelection() ?? new Range(activeModel.getLineCount(), 1, activeModel.getLineCount(), 1); + await bulkEditService.apply([new ResourceTextEdit(activeModel.uri, { + range: activeSelection, + text: chatCodeBlockActionContext.code, + })]); + } codeEditorService.listCodeEditors().find(editor => editor.getModel()?.uri.toString() === activeModel.uri.toString())?.focus(); } diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts index 7f639db3aeb..07776d570a6 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts @@ -17,7 +17,7 @@ export interface IChatExecuteActionContext { inputValue?: string; } -function isExecuteActionContext(thing: unknown): thing is IChatExecuteActionContext { +export function isExecuteActionContext(thing: unknown): thing is IChatExecuteActionContext { return typeof thing === 'object' && thing !== null && 'widget' in thing; } diff --git a/src/vs/workbench/contrib/chat/browser/chat.ts b/src/vs/workbench/contrib/chat/browser/chat.ts index f0587cfbc84..2950dd6579b 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.ts @@ -35,9 +35,11 @@ export interface IChatWidgetService { export interface IQuickChatService { readonly _serviceBrand: undefined; - enabled: boolean; + readonly onDidClose: Event; + readonly enabled: boolean; toggle(providerId?: string, query?: string): void; focus(): void; + open(): void; close(): void; openInChatView(): void; } @@ -79,6 +81,7 @@ export type IChatWidgetViewContext = IChatViewViewContext | IChatResourceViewCon export interface IChatWidget { readonly onDidChangeViewModel: Event; + readonly onDidAcceptInput: Event; readonly viewContext: IChatWidgetViewContext; readonly viewModel: IChatViewModel | undefined; readonly inputEditor: ICodeEditor; @@ -88,9 +91,11 @@ export interface IChatWidget { focus(item: ChatTreeItem): void; moveFocus(item: ChatTreeItem, type: 'next' | 'previous'): void; getFocus(): ChatTreeItem | undefined; + updateInput(query?: string): void; acceptInput(query?: string): void; focusLastMessage(): void; focusInput(): void; + hasInputFocus(): boolean; getSlashCommands(): Promise; getCodeBlockInfoForEditor(uri: URI): IChatCodeBlockInfo | undefined; getCodeBlockInfosForResponse(response: IChatResponseViewModel): IChatCodeBlockInfo[]; diff --git a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts index 7066089148a..97a2b1ee4ea 100644 --- a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts @@ -40,7 +40,7 @@ const $ = dom.$; const INPUT_EDITOR_MAX_HEIGHT = 250; export class ChatInputPart extends Disposable implements IHistoryNavigationWidget { - public static readonly INPUT_SCHEME = 'chatSessionInput'; + static readonly INPUT_SCHEME = 'chatSessionInput'; private static _counter = 0; private _onDidChangeHeight = this._register(new Emitter()); @@ -64,7 +64,9 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge private _inputEditor!: CodeEditorWidget; private _inputEditorElement!: HTMLElement; - public get inputEditor() { + private toolbar!: MenuWorkbenchToolBar; + + get inputEditor() { return this._inputEditor; } @@ -74,7 +76,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge private inputEditorHasText: IContextKey; private providerId: string | undefined; - public readonly inputUri = URI.parse(`${ChatInputPart.INPUT_SCHEME}:input-${ChatInputPart._counter++}`); + readonly inputUri = URI.parse(`${ChatInputPart.INPUT_SCHEME}:input-${ChatInputPart._counter++}`); constructor( // private readonly editorOptions: ChatEditorOptions, // TODO this should be used @@ -138,7 +140,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge this.setHistoryNavigationEnablement(true); } - private setValue(value: string): void { + setValue(value: string): void { this.inputEditor.setValue(value); // always leave cursor at the end this.inputEditor.setPosition({ lineNumber: 1, column: value.length + 1 }); @@ -148,6 +150,10 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge this._inputEditor.focus(); } + hasFocus(): boolean { + return this._inputEditor.hasWidgetFocus(); + } + async acceptInput(query?: string | IChatReplyFollowup): Promise { const editorValue = this._inputEditor.getValue(); if (!query && editorValue) { @@ -233,13 +239,13 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge this._onDidBlur.fire(); })); - const toolbar = this._register(this.instantiationService.createInstance(MenuWorkbenchToolBar, inputContainer, MenuId.ChatExecute, { + this.toolbar = this._register(this.instantiationService.createInstance(MenuWorkbenchToolBar, inputContainer, MenuId.ChatExecute, { menuOptions: { shouldForwardArgs: true } })); - toolbar.getElement().classList.add('interactive-execute-toolbar'); - toolbar.context = { widget }; + this.toolbar.getElement().classList.add('interactive-execute-toolbar'); + this.toolbar.context = { widget }; if (this.options.renderStyle === 'compact') { const toolbarSide = this._register(this.instantiationService.createInstance(MenuWorkbenchToolBar, inputAndSideToolbar, MenuId.ChatInputSide, { @@ -290,7 +296,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge const editorBorder = 2; const editorPadding = 8; - const executeToolbarWidth = 25; + const executeToolbarWidth = this.toolbar.getItemsWidth(); const sideToolbarWidth = this.options.renderStyle === 'compact' ? 20 : 0; const initialEditorScrollWidth = this._inputEditor.getScrollWidth(); diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index 52f971ad1b9..e6ec6bd3ae8 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -72,6 +72,7 @@ import { createFileIconThemableTreeContainerScope } from 'vs/workbench/contrib/f import { IFilesConfiguration } from 'vs/workbench/contrib/files/common/files'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { distinct } from 'vs/base/common/arrays'; +import { IPlaceholderMarkdownString } from 'vs/workbench/contrib/chat/common/chatModel'; const $ = dom.$; @@ -315,12 +316,12 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer, element: ChatTreeItem, index: number, templateData: IChatListItemTemplate) { const fillInIncompleteTokens = isResponseVM(element) && (!element.isComplete || element.isCanceled || element.errorDetails?.responseIsFiltered || element.errorDetails?.responseIsIncomplete); dom.clearNode(templateData.value); let fileTreeIndex = 0; - for (const data of markdownValue) { + for (const data of value) { const result = 'value' in data ? this.renderMarkdown(data, element, templateData.elementDisposables, templateData, fillInIncompleteTokens) : this.renderTreeData(data, element, templateData.elementDisposables, templateData, fileTreeIndex++); @@ -414,7 +415,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer content.dispose() }; + } + private renderMarkdown(markdown: IMarkdownString, element: ChatTreeItem, disposables: DisposableStore, templateData: IChatListItemTemplate, fillInIncompleteTokens = false): IMarkdownRenderResult { const disposablesList: IDisposable[] = []; let codeBlockIndex = 0; @@ -561,8 +577,9 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer): IWordCountResult | undefined { const rate = this.getProgressiveRenderRate(element); const numWordsToRender = renderData.lastRenderTime === 0 ? 1 : @@ -1189,3 +1206,7 @@ class ChatListTreeDataSource implements IAsyncDataSource()); + readonly onDidClose = this._onDidClose.event; + + private _input: IQuickWidget | undefined; + private _currentChat: QuickChat | undefined; constructor( @IQuickInputService private readonly quickInputService: IQuickInputService, @IChatService private readonly chatService: IChatService, @IInstantiationService private readonly instantiationService: IInstantiationService, - ) { } + ) { + super(); + } get enabled(): boolean { return this.chatService.getProviderInfos().length > 0; } get focused(): boolean { - const widget = this._input?.widget as HTMLElement; + const widget = this._input?.widget as HTMLElement | undefined; if (!widget) { return false; } @@ -45,7 +51,13 @@ export class QuickChatService implements IQuickChatService { // If the input is already shown, hide it. This provides a toggle behavior of the quick pick if (this.focused) { this.close(); - return; + } else { + this.open(providerId, query); + } + } + open(providerId?: string, query?: string | undefined): void { + if (this.focused) { + return this.focus(); } // Check if any providers are available. If not, show nothing @@ -78,6 +90,7 @@ export class QuickChatService implements IQuickChatService { disposableStore.add(this._input.onDidHide(() => { disposableStore.dispose(); this._input = undefined; + this._onDidClose.fire(); })); this._currentChat.focus(); @@ -149,7 +162,7 @@ class QuickChat extends Disposable { })); this.widget.render(parent); this.widget.setVisible(true); - this.widget.setDynamicChatTreeItemLayout(2, 600); + this.widget.setDynamicChatTreeItemLayout(2, 900); this.updateModel(); if (this._currentQuery) { this.widget.inputEditor.setSelection({ @@ -185,8 +198,9 @@ class QuickChat extends Disposable { this.chatService.addCompleteRequest(widget.viewModel.sessionId, request.message as string, { - message: request.response.response.asString(), - errorDetails: request.response.errorDetails + message: request.response.response.value, + errorDetails: request.response.errorDetails, + followups: request.response.followups }); } else if (request.message) { diff --git a/src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.css b/src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.css index 6f78c0edda9..d2568dbbfed 100644 --- a/src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.css +++ b/src/vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget.css @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ .chat-slash-command-content-widget { - padding: 1px 3px; - border-radius: 3px; background-color: var(--vscode-chat-slashCommandBackground); color: var(--vscode-chat-slashCommandForeground); + border-radius: 3px; + padding: 1px; } diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index 9f623e3381e..053278d5af6 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -61,6 +61,9 @@ export class ChatWidget extends Disposable implements IChatWidget { private _onDidClear = this._register(new Emitter()); readonly onDidClear = this._onDidClear.event; + private _onDidAcceptInput = this._register(new Emitter()); + readonly onDidAcceptInput = this._onDidAcceptInput.event; + private tree!: WorkbenchObjectTree; private renderer!: ChatListItemRenderer; @@ -179,6 +182,10 @@ export class ChatWidget extends Disposable implements IChatWidget { this.inputPart.focus(); } + hasInputFocus(): boolean { + return this.inputPart.hasFocus(); + } + moveFocus(item: ChatTreeItem, type: 'next' | 'previous'): void { const items = this.viewModel?.getItems(); if (!items) { @@ -432,8 +439,14 @@ export class ChatWidget extends Disposable implements IChatWidget { this.tree.domFocus(); } + updateInput(value = ''): void { + this.inputPart.setValue(value); + } + async acceptInput(query?: string | IChatReplyFollowup): Promise { if (this.viewModel) { + this._onDidAcceptInput.fire(); + const editorValue = this.inputPart.inputEditor.getValue(); this._chatAccessibilityService.acceptRequest(); const input = query ?? editorValue; diff --git a/src/vs/workbench/contrib/chat/browser/media/chat.css b/src/vs/workbench/contrib/chat/browser/media/chat.css index 7e193499146..33b798459ea 100644 --- a/src/vs/workbench/contrib/chat/browser/media/chat.css +++ b/src/vs/workbench/contrib/chat/browser/media/chat.css @@ -228,9 +228,10 @@ margin: 0px 20px; background-color: var(--vscode-input-background); border: 1px solid var(--vscode-input-border, transparent); - border-radius: 2px; + border-radius: 4px; position: relative; - padding: 0 4px; + padding: 0 6px; + margin-bottom: 4px; align-items: center; justify-content: space-between; } @@ -435,10 +436,29 @@ .interactive-response-progress-tree { margin: 16px 0px; - border-radius: 4px; - border: 1px solid var(--vscode-input-border, transparent); } .interactive-response-progress-tree.focused { border-color: var(--vscode-focusBorder, transparent); } + +.interactive-item-container .value .interactive-response-placeholder-codicon .codicon { + color: var(--vscode-editorGhostText-foreground); +} + +.interactive-item-container .value .interactive-response-placeholder-content { + color: var(--vscode-editorGhostText-foreground); + font-size: 12px; +} + +.interactive-response .interactive-response-codicon-details { + display: flex; + align-items: start; + gap: 6px; +} + +.interactive-response-progress-tree .monaco-list .monaco-scrollable-element .monaco-list-rows { + border: 1px solid var(--vscode-input-border,transparent); + border-radius: 4px; + width: auto; +} diff --git a/src/vs/workbench/contrib/chat/common/chatModel.ts b/src/vs/workbench/contrib/chat/common/chatModel.ts index a242829fd92..23fec163a79 100644 --- a/src/vs/workbench/contrib/chat/common/chatModel.ts +++ b/src/vs/workbench/contrib/chat/common/chatModel.ts @@ -5,7 +5,7 @@ import { DeferredPromise } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; -import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent'; +import { IMarkdownString, MarkdownString, isMarkdownString } from 'vs/base/common/htmlContent'; import { Disposable } from 'vs/base/common/lifecycle'; import { URI, UriComponents } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; @@ -23,9 +23,9 @@ export interface IChatRequestModel { } export interface IResponse { - readonly value: (IMarkdownString | IChatResponseProgressFileTreeData)[]; + readonly value: (IMarkdownString | IPlaceholderMarkdownString | IChatResponseProgressFileTreeData)[]; onDidChangeValue: Event; - updateContent(responsePart: string | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean): void; + updateContent(responsePart: string | IMarkdownString | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean): void; asString(): string; } @@ -88,8 +88,11 @@ export class ChatRequestModel implements IChatRequestModel { } } +export interface IPlaceholderMarkdownString extends IMarkdownString { + isPlaceholder: boolean; +} -type ResponsePart = { string: IMarkdownString; resolving?: boolean } | { treeData: IChatResponseProgressFileTreeData; resolving?: boolean }; +type ResponsePart = { string: IMarkdownString; isPlaceholder?: boolean } | { treeData: IChatResponseProgressFileTreeData; isPlaceholder?: undefined }; export class Response implements IResponse { private _onDidChangeValue = new Emitter(); public get onDidChangeValue() { @@ -99,11 +102,11 @@ export class Response implements IResponse { // responseParts internally tracks all the response parts, including strings which are currently resolving, so that they can be updated when they do resolve private _responseParts: ResponsePart[]; // responseData externally presents the response parts with consolidated contiguous strings (including strings which were previously resolving) - private _responseData: (IMarkdownString | IChatResponseProgressFileTreeData)[]; + private _responseData: (IMarkdownString | IPlaceholderMarkdownString | IChatResponseProgressFileTreeData)[]; // responseRepr externally presents the response parts with consolidated contiguous strings (excluding tree data) private _responseRepr: string; - get value(): (IMarkdownString | IChatResponseProgressFileTreeData)[] { + get value(): (IMarkdownString | IPlaceholderMarkdownString | IChatResponseProgressFileTreeData)[] { return this._responseData; } @@ -111,7 +114,7 @@ export class Response implements IResponse { this._responseData = Array.isArray(value) ? value : [value]; this._responseParts = Array.isArray(value) ? value.map((v) => ('value' in v ? { string: v } : { treeData: v })) : [{ string: value }]; this._responseRepr = this._responseParts.map((part) => { - if ('treeData' in part) { + if (isCompleteInteractiveProgressTreeData(part)) { return ''; } return part.string.value; @@ -122,48 +125,56 @@ export class Response implements IResponse { return this._responseRepr; } - updateContent(responsePart: string | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean): void { - if (typeof responsePart === 'string') { + updateContent(responsePart: string | IMarkdownString | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean): void { + if (typeof responsePart === 'string' || isMarkdownString(responsePart)) { const responsePartLength = this._responseParts.length - 1; const lastResponsePart = this._responseParts[responsePartLength]; - if (lastResponsePart.resolving === true || 'treeData' in lastResponsePart) { + if (lastResponsePart.isPlaceholder === true || isCompleteInteractiveProgressTreeData(lastResponsePart)) { // The last part is resolving or a tree data item, start a new part - this._responseParts.push({ string: new MarkdownString(responsePart) }); + this._responseParts.push({ string: typeof responsePart === 'string' ? new MarkdownString(responsePart) : responsePart }); } else { // Combine this part with the last, non-resolving string part - this._responseParts[responsePartLength] = { string: new MarkdownString(lastResponsePart.string.value + responsePart) }; + if (isMarkdownString(responsePart)) { + this._responseParts[responsePartLength] = { string: new MarkdownString(lastResponsePart.string.value + responsePart.value, responsePart) }; + } else { + this._responseParts[responsePartLength] = { string: new MarkdownString(lastResponsePart.string.value + responsePart, lastResponsePart.string) }; + } } this._updateRepr(quiet); } else if ('placeholder' in responsePart) { // Add a new resolving part - const responsePosition = this._responseParts.push({ string: new MarkdownString(responsePart.placeholder), resolving: true }) - 1; + const responsePosition = this._responseParts.push({ string: new MarkdownString(responsePart.placeholder), isPlaceholder: true }) - 1; this._updateRepr(quiet); responsePart.resolvedContent?.then((content) => { // Replace the resolving part's content with the resolved response if (typeof content === 'string') { - this._responseParts[responsePosition] = { string: new MarkdownString(content), resolving: true }; + this._responseParts[responsePosition] = { string: new MarkdownString(content), isPlaceholder: true }; this._updateRepr(quiet); } else if (content.treeData) { - this._responseParts[responsePosition] = { treeData: content.treeData, resolving: true }; + this._responseParts[responsePosition] = { treeData: content.treeData }; this._updateRepr(quiet); } }); + } else if (isCompleteInteractiveProgressTreeData(responsePart)) { + this._responseParts.push(responsePart); } } private _updateRepr(quiet?: boolean) { this._responseData = this._responseParts.map(part => { - if ('treeData' in part) { + if (isCompleteInteractiveProgressTreeData(part)) { return part.treeData; + } else if (part.isPlaceholder) { + return { ...part.string, isPlaceholder: true }; } return part.string; }); this._responseRepr = this._responseParts.map(part => { - if ('treeData' in part) { + if (isCompleteInteractiveProgressTreeData(part)) { return ''; } return part.string.value; @@ -243,7 +254,7 @@ export class ChatResponseModel extends Disposable implements IChatResponseModel this._id = 'response_' + ChatResponseModel.nextId++; } - updateContent(responsePart: string | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean) { + updateContent(responsePart: string | IMarkdownString | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent?: Promise }, quiet?: boolean) { this._response.updateContent(responsePart, quiet); } @@ -547,7 +558,7 @@ export class ChatModel extends Disposable implements IChatModel { if ('content' in progress) { request.response.updateContent(progress.content, quiet); - } else if ('placeholder' in progress) { + } else if ('placeholder' in progress || isCompleteInteractiveProgressTreeData(progress)) { request.response.updateContent(progress, quiet); } else { request.setProviderRequestId(progress.requestId); @@ -692,3 +703,7 @@ export class ChatWelcomeMessageModel implements IChatWelcomeMessageModel { return this.session.responderAvatarIconUri; } } + +export function isCompleteInteractiveProgressTreeData(item: unknown): item is { treeData: IChatResponseProgressFileTreeData } { + return typeof item === 'object' && !!item && 'treeData' in item; +} diff --git a/src/vs/workbench/contrib/chat/common/chatService.ts b/src/vs/workbench/contrib/chat/common/chatService.ts index 4c265f87383..9039dfb5150 100644 --- a/src/vs/workbench/contrib/chat/common/chatService.ts +++ b/src/vs/workbench/contrib/chat/common/chatService.ts @@ -5,6 +5,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Event } from 'vs/base/common/event'; +import { IMarkdownString } from 'vs/base/common/htmlContent'; import { IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { ProviderResult } from 'vs/editor/common/languages'; @@ -51,7 +52,7 @@ export interface IChatResponseProgressFileTreeData { } export type IChatProgress = - { content: string } | { requestId: string } | { placeholder: string; resolvedContent: Promise }; + { content: string | IMarkdownString } | { requestId: string } | { treeData: IChatResponseProgressFileTreeData } | { placeholder: string; resolvedContent: Promise }; export interface IPersistedChatState { } export interface IChatProvider { @@ -177,8 +178,9 @@ export interface IChatDynamicRequest { } export interface IChatCompleteResponse { - message: string; + message: string | (IMarkdownString | IChatResponseProgressFileTreeData)[]; errorDetails?: IChatResponseErrorDetails; + followups?: IChatFollowup[]; } export interface IChatDetail { diff --git a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts index a8663c161df..bd759fd4c94 100644 --- a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts +++ b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts @@ -22,7 +22,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { CONTEXT_PROVIDER_EXISTS } from 'vs/workbench/contrib/chat/common/chatContextKeys'; -import { ChatModel, ChatWelcomeMessageModel, IChatModel, ISerializableChatData, ISerializableChatsData } from 'vs/workbench/contrib/chat/common/chatModel'; +import { ChatModel, ChatWelcomeMessageModel, IChatModel, ISerializableChatData, ISerializableChatsData, isCompleteInteractiveProgressTreeData } from 'vs/workbench/contrib/chat/common/chatModel'; import { ChatMessageRole, IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider'; import { IChat, IChatCompleteResponse, IChatDetail, IChatDynamicRequest, IChatProgress, IChatProvider, IChatProviderInfo, IChatReplyFollowup, IChatRequest, IChatResponse, IChatService, IChatTransferredSessionData, IChatUserActionEvent, ISlashCommand, InteractiveSessionCopyKind, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService'; import { IChatSlashCommandService, IChatSlashFragment } from 'vs/workbench/contrib/chat/common/chatSlashCommands'; @@ -450,9 +450,12 @@ export class ChatService extends Disposable implements IChatService { gotProgress = true; if ('content' in progress) { - this.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${progress.content.length} chars`); + this.trace('sendRequest', `Provider returned progress for session ${model.sessionId}, ${typeof progress.content === 'string' ? progress.content.length : progress.content.value.length} chars`); } else if ('placeholder' in progress) { this.trace('sendRequest', `Provider returned placeholder for session ${model.sessionId}, ${progress.placeholder}`); + } else if (isCompleteInteractiveProgressTreeData(progress)) { + // This isn't exposed in API + this.trace('sendRequest', `Provider returned tree data for session ${model.sessionId}, ${progress.treeData.label}`); } else { this.trace('sendRequest', `Provider returned id for session ${model.sessionId}, ${progress.requestId}`); } @@ -662,13 +665,22 @@ export class ChatService extends Disposable implements IChatService { await model.waitForInitialization(); const request = model.addRequest(message); - model.acceptResponseProgress(request, { - content: response.message, - }, true); + if (typeof response.message === 'string') { + model.acceptResponseProgress(request, { content: response.message }); + } else { + for (const part of response.message) { + const progress = isMarkdownString(part) ? { content: part.value } : { treeData: part }; + model.acceptResponseProgress(request, progress, true); + } + } model.setResponse(request, { session: model.session!, errorDetails: response.errorDetails, }); + if (response.followups !== undefined) { + model.setFollowups(request, response.followups); + } + model.completeResponse(request); } cancelCurrentRequestForSession(sessionId: string): void { diff --git a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts new file mode 100644 index 00000000000..8773eff46d5 --- /dev/null +++ b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts @@ -0,0 +1,385 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from 'vs/base/common/event'; +import { firstOrDefault } from 'vs/base/common/arrays'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { Codicon } from 'vs/base/common/codicons'; +import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { equalsIgnoreCase } from 'vs/base/common/strings'; +import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { localize } from 'vs/nls'; +import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { ContextKeyExpr, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { spinningLoading } from 'vs/platform/theme/common/iconRegistry'; +import { CHAT_CATEGORY } from 'vs/workbench/contrib/chat/browser/actions/chatActions'; +import { IChatWidgetService, IQuickChatService } from 'vs/workbench/contrib/chat/browser/chat'; +import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; +import { IWorkbenchVoiceRecognitionService } from 'vs/workbench/services/voiceRecognition/electron-sandbox/workbenchVoiceRecognitionService'; +import { MENU_INLINE_CHAT_WIDGET } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; +import { CONTEXT_PROVIDER_EXISTS } from 'vs/workbench/contrib/chat/common/chatContextKeys'; +import { InlineChatController } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { getCodeEditor } from 'vs/editor/browser/editorBrowser'; +import { isExecuteActionContext } from 'vs/workbench/contrib/chat/browser/actions/chatExecuteActions'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals'; +import product from 'vs/platform/product/common/product'; +import { ActiveEditorContext } from 'vs/workbench/common/contextkeys'; + +const CONTEXT_VOICE_CHAT_GETTING_READY = new RawContextKey('voiceChatGettingReady', false, { type: 'boolean', description: localize('voiceChatGettingReady', "True when getting ready for receiving voice input from the microphone.") }); +const CONTEXT_VOICE_CHAT_IN_PROGRESS = new RawContextKey('voiceChatInProgress', false, { type: 'boolean', description: localize('voiceChatInProgress', "True when voice recording from microphone is in progress.") }); + +interface IVoiceChatSessionController { + + readonly onDidAcceptInput: Event; + + focusInput(): void; + acceptInput(): void; + updateInput(text: string): void; +} + +function getController(controller: InlineChatController): IVoiceChatSessionController; +function getController(context: unknown): IVoiceChatSessionController | undefined; +function getController(context: unknown): IVoiceChatSessionController | undefined { + if (context instanceof InlineChatController) { + return { + onDidAcceptInput: context.onDidAcceptInput, + focusInput: () => context.focus(), + acceptInput: () => context.acceptInput(), + updateInput: text => context.updateInput(text) + }; + } + + if (isExecuteActionContext(context)) { + return context.widget; + } + + return undefined; +} + +class VoiceChatSession { + + private static instance: VoiceChatSession | undefined = undefined; + static getInstance(instantiationService: IInstantiationService): VoiceChatSession { + if (!VoiceChatSession.instance) { + VoiceChatSession.instance = instantiationService.createInstance(VoiceChatSession); + } + + return VoiceChatSession.instance; + } + + private voiceChatInProgressKey = CONTEXT_VOICE_CHAT_IN_PROGRESS.bindTo(this.contextKeyService); + private voiceChatGettingReadyKey = CONTEXT_VOICE_CHAT_GETTING_READY.bindTo(this.contextKeyService); + + private currentVoiceChatSession: DisposableStore | undefined = undefined; + private voiceChatSessionIds = 0; + + constructor( + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IWorkbenchVoiceRecognitionService private readonly voiceRecognitionService: IWorkbenchVoiceRecognitionService + ) { } + + async start(context: IVoiceChatSessionController): Promise { + this.stop(); + + this.voiceChatGettingReadyKey.set(true); + this.currentVoiceChatSession = new DisposableStore(); + + const cts = new CancellationTokenSource(); + this.currentVoiceChatSession.add(toDisposable(() => cts.dispose(true))); + + context.focusInput(); + + const onDidTranscribe = await this.voiceRecognitionService.transcribe(cts.token, { + onDidCancel: () => this.stop(voiceChatSessionId) + }); + if (cts.token.isCancellationRequested) { + return Disposable.None; + } + + const voiceChatSessionId = ++this.voiceChatSessionIds; + + this.voiceChatGettingReadyKey.set(false); + this.voiceChatInProgressKey.set(true); + + let lastText: string | undefined = undefined; + let lastTextSimilarCount = 0; + + this.currentVoiceChatSession.add(onDidTranscribe(text => { + if (!text && lastText) { + text = lastText; + } + + if (text) { + if (lastText && this.isSimilarTranscription(text, lastText)) { + lastTextSimilarCount++; + } else { + lastTextSimilarCount = 0; + lastText = text; + } + + if (lastTextSimilarCount >= 2) { + context.acceptInput(); + } else { + context.updateInput(text); + } + + } + })); + + this.currentVoiceChatSession.add(context.onDidAcceptInput(() => this.stop(voiceChatSessionId))); + + return toDisposable(() => this.stop(voiceChatSessionId)); + } + + private isSimilarTranscription(textA: string, textB: string): boolean { + + // Attempt to compare the 2 strings in a way to see + // if they are similar or not. As such we: + // - ignore trailing punctuation + // - collapse all whitespace + // - compare case insensitive + + return equalsIgnoreCase( + textA.replace(/[.,;:!?]+$/, '').replace(/\s+/g, ''), + textB.replace(/[.,;:!?]+$/, '').replace(/\s+/g, '') + ); + } + + stop(voiceChatSessionId = this.voiceChatSessionIds): void { + if (!this.currentVoiceChatSession) { + return; + } + + if (this.voiceChatSessionIds !== voiceChatSessionId) { + return; + } + + this.currentVoiceChatSession.dispose(); + this.currentVoiceChatSession = undefined; + + this.voiceChatGettingReadyKey.set(false); + this.voiceChatInProgressKey.set(false); + } +} + +class VoiceChatInChatViewAction extends Action2 { + + static readonly ID = 'workbench.action.chat.voiceChatInChatView'; + + constructor() { + super({ + id: VoiceChatInChatViewAction.ID, + title: { + value: localize('workbench.action.chat.voiceChatInView.label', "Voice Chat in Chat View"), + original: 'Voice Chat in Chat View' + }, + category: CHAT_CATEGORY, + precondition: CONTEXT_PROVIDER_EXISTS, + f1: true + }); + } + + async run(accessor: ServicesAccessor): Promise { + const chatWidgetService = accessor.get(IChatWidgetService); + const chatService = accessor.get(IChatService); + const instantiationService = accessor.get(IInstantiationService); + + const provider = firstOrDefault(chatService.getProviderInfos()); + if (provider) { + const controller = await chatWidgetService.revealViewForProvider(provider.id); + if (controller) { + VoiceChatSession.getInstance(instantiationService).start(controller); + } + } + } +} + +class InlineVoiceChatAction extends Action2 { + + static readonly ID = 'workbench.action.chat.inlineVoiceChat'; + + constructor() { + super({ + id: InlineVoiceChatAction.ID, + title: { + value: localize('workbench.action.chat.inlineVoiceChat', "Inline Voice Chat"), + original: 'Inline Voice Chat' + }, + category: CHAT_CATEGORY, + precondition: ContextKeyExpr.and(CONTEXT_PROVIDER_EXISTS, ActiveEditorContext), + f1: true + }); + } + + async run(accessor: ServicesAccessor): Promise { + const editorService = accessor.get(IEditorService); + const instantiationService = accessor.get(IInstantiationService); + + const activeCodeEditor = getCodeEditor(editorService.activeTextEditorControl); + if (!activeCodeEditor) { + return; + } + + const controller = InlineChatController.get(activeCodeEditor); + if (!controller) { + return; + } + + const inlineChatSession = controller.run(); + + const disposable = await VoiceChatSession.getInstance(instantiationService).start(getController(controller)); + inlineChatSession.finally(() => disposable.dispose()); + } +} + +class QuickVoiceChatAction extends Action2 { + + static readonly ID = 'workbench.action.chat.quickVoiceChat'; + + constructor() { + super({ + id: QuickVoiceChatAction.ID, + title: { + value: localize('workbench.action.chat.quickVoiceChat.label', "Quick Voice Chat"), + original: 'Quick Voice Chat' + }, + category: CHAT_CATEGORY, + precondition: CONTEXT_PROVIDER_EXISTS, + f1: true + }); + } + + async run(accessor: ServicesAccessor): Promise { + const quickChatService = accessor.get(IQuickChatService); + const chatWidgetService = accessor.get(IChatWidgetService); + const instantiationService = accessor.get(IInstantiationService); + + quickChatService.open(); + + const controller = chatWidgetService.lastFocusedWidget; + if (controller) { + const disposable = await VoiceChatSession.getInstance(instantiationService).start(controller); + Event.once(quickChatService.onDidClose)(() => disposable.dispose()); + } + } +} + +class StartVoiceChatAction extends Action2 { + + static readonly ID = 'workbench.action.chat.startVoiceChat'; + + constructor() { + super({ + id: StartVoiceChatAction.ID, + title: { + value: localize('workbench.action.chat.startVoiceChat', "Start Voice Chat"), + original: 'Start Voice Chat' + }, + icon: Codicon.record, + precondition: CONTEXT_VOICE_CHAT_GETTING_READY.negate(), + menu: [{ + id: MenuId.ChatExecute, + when: CONTEXT_VOICE_CHAT_IN_PROGRESS.negate(), + group: 'navigation', + order: -1 + }, { + id: MENU_INLINE_CHAT_WIDGET, + when: CONTEXT_VOICE_CHAT_IN_PROGRESS.negate(), + group: 'main', + order: -1 + }] + }); + } + + async run(accessor: ServicesAccessor, context: unknown): Promise { + const editorService = accessor.get(IEditorService); + const chatWidgetService = accessor.get(IChatWidgetService); + const instantiationService = accessor.get(IInstantiationService); + const commandService = accessor.get(ICommandService); + + let controller = getController(context); + if (!controller) { + + // Without a controller, this action potentially executed from + // a global keybinding, and thus we have to find the chat + // input that is currently focussed, or have a fallback + + // 1.) a chat input widget has focus + if (chatWidgetService.lastFocusedWidget?.hasInputFocus()) { + controller = chatWidgetService.lastFocusedWidget; + } + + // 2.) a inline chat input widget has focus + if (!controller) { + const activeCodeEditor = getCodeEditor(editorService.activeTextEditorControl); + if (activeCodeEditor) { + const chatInput = InlineChatController.get(activeCodeEditor); + if (chatInput?.hasFocus()) { + controller = getController(chatInput); + } + } + } + + // 3.) open a quick chat view + if (!controller) { + return commandService.executeCommand(QuickVoiceChatAction.ID); + } + } + + if (!controller) { + return; + } + + VoiceChatSession.getInstance(instantiationService).start(controller); + } +} + +class StopVoiceChatAction extends Action2 { + + static readonly ID = 'workbench.action.chat.stopVoiceChat'; + + constructor() { + super({ + id: StopVoiceChatAction.ID, + title: { + value: localize('workbench.action.chat.stopVoiceChat.label', "Stop Voice Chat"), + original: 'Stop Voice Chat' + }, + category: CHAT_CATEGORY, + f1: true, + precondition: CONTEXT_VOICE_CHAT_IN_PROGRESS, + icon: spinningLoading, + menu: [{ + id: MenuId.ChatExecute, + when: CONTEXT_VOICE_CHAT_IN_PROGRESS, + group: 'navigation', + order: -1 + }, { + id: MENU_INLINE_CHAT_WIDGET, + when: CONTEXT_VOICE_CHAT_IN_PROGRESS, + group: 'main', + order: -1 + }] + }); + } + + run(accessor: ServicesAccessor): void { + VoiceChatSession.getInstance(accessor.get(IInstantiationService)).stop(); + } +} + +export function registerVoiceChatActions() { + if (typeof process.env.VSCODE_VOICE_MODULE_PATH === 'string' && product.quality !== 'stable') { // TODO@bpasero package + registerAction2(VoiceChatInChatViewAction); + registerAction2(QuickVoiceChatAction); + registerAction2(InlineVoiceChatAction); + + registerAction2(StartVoiceChatAction); + registerAction2(StopVoiceChatAction); + } +} diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.css b/src/vs/workbench/contrib/chat/electron-sandbox/chat.contribution.ts similarity index 71% rename from src/vs/workbench/contrib/chat/browser/chatListRenderer.css rename to src/vs/workbench/contrib/chat/electron-sandbox/chat.contribution.ts index 49c3ab7833c..1bd74f66eff 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.css +++ b/src/vs/workbench/contrib/chat/electron-sandbox/chat.contribution.ts @@ -3,6 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.interactive-response-progress-tree .monaco-tl-row:hover { - background-color: var(--vscode-list-hoverBackground); -} +import { registerVoiceChatActions } from 'vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions'; + +registerVoiceChatActions(); diff --git a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts index 1e0d06ff9b8..22148696b72 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts @@ -107,7 +107,7 @@ function createScreenReaderHelp(): IDisposable { localize('msg1', "You are in a diff editor."), localize('msg2', "Press {0} or {1} to view the next or previous diff in the diff review mode that is optimized for screen readers.", next, previous), localize('msg3', "To control which audio cues should be played, the following settings can be configured: {0}.", keys.join(', ')), - ].join('\n'), + ].join('\n\n'), onClose: () => { codeEditor.focus(); }, diff --git a/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts b/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts index 80e766a2a4f..52ac3a4afb1 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts @@ -44,7 +44,7 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC 'Variable 0 will be a file name.' ] }, - "{0}: tokenization, wrapping and folding have been turned off for this large file in order to reduce memory usage and avoid freezing or crashing.", + "{0}: tokenization, wrapping, folding and sticky scroll have been turned off for this large file in order to reduce memory usage and avoid freezing or crashing.", path.basename(model.uri.path) ); diff --git a/src/vs/workbench/contrib/comments/browser/commentColors.ts b/src/vs/workbench/contrib/comments/browser/commentColors.ts index bfc70a8a247..a300a745a56 100644 --- a/src/vs/workbench/contrib/comments/browser/commentColors.ts +++ b/src/vs/workbench/contrib/comments/browser/commentColors.ts @@ -15,9 +15,7 @@ const unresolvedCommentViewIcon = registerColor('commentsView.unresolvedIcon', { const resolvedCommentBorder = registerColor('editorCommentsWidget.resolvedBorder', { dark: resolvedCommentViewIcon, light: resolvedCommentViewIcon, hcDark: contrastBorder, hcLight: contrastBorder }, nls.localize('resolvedCommentBorder', 'Color of borders and arrow for resolved comments.')); const unresolvedCommentBorder = registerColor('editorCommentsWidget.unresolvedBorder', { dark: unresolvedCommentViewIcon, light: unresolvedCommentViewIcon, hcDark: contrastBorder, hcLight: contrastBorder }, nls.localize('unresolvedCommentBorder', 'Color of borders and arrow for unresolved comments.')); export const commentThreadRangeBackground = registerColor('editorCommentsWidget.rangeBackground', { dark: transparent(unresolvedCommentBorder, .1), light: transparent(unresolvedCommentBorder, .1), hcDark: transparent(unresolvedCommentBorder, .1), hcLight: transparent(unresolvedCommentBorder, .1) }, nls.localize('commentThreadRangeBackground', 'Color of background for comment ranges.')); -export const commentThreadRangeBorder = registerColor('editorCommentsWidget.rangeBorder', { dark: transparent(unresolvedCommentBorder, .4), light: transparent(unresolvedCommentBorder, .4), hcDark: transparent(unresolvedCommentBorder, .4), hcLight: transparent(unresolvedCommentBorder, .4) }, nls.localize('commentThreadRangeBorder', 'Color of border for comment ranges.')); export const commentThreadRangeActiveBackground = registerColor('editorCommentsWidget.rangeActiveBackground', { dark: transparent(unresolvedCommentBorder, .1), light: transparent(unresolvedCommentBorder, .1), hcDark: transparent(unresolvedCommentBorder, .1), hcLight: transparent(unresolvedCommentBorder, .1) }, nls.localize('commentThreadActiveRangeBackground', 'Color of background for currently selected or hovered comment range.')); -export const commentThreadRangeActiveBorder = registerColor('editorCommentsWidget.rangeActiveBorder', { dark: transparent(unresolvedCommentBorder, .4), light: transparent(unresolvedCommentBorder, .4), hcDark: transparent(unresolvedCommentBorder, .4), hcLight: transparent(unresolvedCommentBorder, .2) }, nls.localize('commentThreadActiveRangeBorder', 'Color of border for currently selected or hovered comment range.')); const commentThreadStateBorderColors = new Map([ [languages.CommentThreadState.Unresolved, unresolvedCommentBorder], diff --git a/src/vs/workbench/contrib/comments/browser/commentThreadRangeDecorator.ts b/src/vs/workbench/contrib/comments/browser/commentThreadRangeDecorator.ts index 0c9828613d2..182a5f3b397 100644 --- a/src/vs/workbench/contrib/comments/browser/commentThreadRangeDecorator.ts +++ b/src/vs/workbench/contrib/comments/browser/commentThreadRangeDecorator.ts @@ -44,7 +44,8 @@ export class CommentThreadRangeDecorator extends Disposable { description: CommentThreadRangeDecorator.description, isWholeLine: false, zIndex: 20, - className: 'comment-thread-range' + className: 'comment-thread-range', + shouldFillLineOnLineBreak: true }; this.decorationOptions = ModelDecorationOptions.createDynamic(decorationOptions); @@ -53,7 +54,8 @@ export class CommentThreadRangeDecorator extends Disposable { description: CommentThreadRangeDecorator.description, isWholeLine: false, zIndex: 20, - className: 'comment-thread-range-current' + className: 'comment-thread-range-current', + shouldFillLineOnLineBreak: true }; this.activeDecorationOptions = ModelDecorationOptions.createDynamic(activeDecorationOptions); diff --git a/src/vs/workbench/contrib/comments/browser/media/review.css b/src/vs/workbench/contrib/comments/browser/media/review.css index dc27b9a50ae..87c845189d8 100644 --- a/src/vs/workbench/contrib/comments/browser/media/review.css +++ b/src/vs/workbench/contrib/comments/browser/media/review.css @@ -487,21 +487,12 @@ div.preview.inline .monaco-editor .comment-range-glyph { background: var(--vscode-editorGutter-commentRangeForeground); } -.monaco-editor .comment-thread-range, -.monaco-editor .comment-thread-range-current { - border-width: 1px; - border-style: solid; - box-sizing: border-box; -} - .monaco-editor .comment-thread-range { background-color: var(--vscode-editorCommentsWidget-rangeBackground); - border-color: var(--vscode-editorCommentsWidget-rangeBorder); } .monaco-editor .comment-thread-range-current { background-color: var(--vscode-editorCommentsWidget-rangeActiveBackground); - border-color: var(--vscode-editorCommentsWidget-rangeActiveBorder); } .monaco-editor .margin-view-overlays .comment-range-glyph.line-hover, diff --git a/src/vs/workbench/contrib/debug/browser/debugCommands.ts b/src/vs/workbench/contrib/debug/browser/debugCommands.ts index 9515ab1ad73..1fecc75d4f9 100644 --- a/src/vs/workbench/contrib/debug/browser/debugCommands.ts +++ b/src/vs/workbench/contrib/debug/browser/debugCommands.ts @@ -474,7 +474,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: STEP_OVER_ID, weight: KeybindingWeight.WorkbenchContrib, primary: KeyCode.F10, - secondary: isWeb ? [(KeyMod.Alt | KeyCode.F10)] : undefined, // Keep Alt-F10 for web for backwards-compatibility when: CONTEXT_DEBUG_STATE.isEqualTo('stopped'), handler: async (accessor: ServicesAccessor, _: string, context: CallStackContext | unknown) => { const contextKeyService = accessor.get(IContextKeyService); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 366c4d28382..cbd45d0ebeb 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -803,7 +803,7 @@ export class ExtensionEditor extends EditorPane { #scroll-to-top span.icon::before { content: ""; display: block; - background: var(--vscode-button-foreground); + background: var(--vscode-button-secondaryForeground); /* Chevron up icon */ webkit-mask-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjIuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAxNiAxNiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTYgMTY7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkZGRkZGO30KCS5zdDF7ZmlsbDpub25lO30KPC9zdHlsZT4KPHRpdGxlPnVwY2hldnJvbjwvdGl0bGU+CjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik04LDUuMWwtNy4zLDcuM0wwLDExLjZsOC04bDgsOGwtMC43LDAuN0w4LDUuMXoiLz4KPHJlY3QgY2xhc3M9InN0MSIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ii8+Cjwvc3ZnPgo='); -webkit-mask-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjIuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAxNiAxNiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTYgMTY7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkZGRkZGO30KCS5zdDF7ZmlsbDpub25lO30KPC9zdHlsZT4KPHRpdGxlPnVwY2hldnJvbjwvdGl0bGU+CjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik04LDUuMWwtNy4zLDcuM0wwLDExLjZsOC04bDgsOGwtMC43LDAuN0w4LDUuMXoiLz4KPHJlY3QgY2xhc3M9InN0MSIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ii8+Cjwvc3ZnPgo='); @@ -855,12 +855,10 @@ export class ExtensionEditor extends EditorPane { extensionPackReadme.style.maxWidth = '882px'; const extensionPack = append(extensionPackReadme, $('div', { class: 'extension-pack' })); - if (manifest.extensionPack!.length <= 3) { + if (manifest.extensionPack!.length < 3) { extensionPackReadme.classList.add('one-row'); - } else if (manifest.extensionPack!.length <= 6) { + } else if (manifest.extensionPack!.length < 5) { extensionPackReadme.classList.add('two-rows'); - } else if (manifest.extensionPack!.length <= 9) { - extensionPackReadme.classList.add('three-rows'); } else { extensionPackReadme.classList.add('more-rows'); } diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 78f7de871fa..3d40bfa801d 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -1421,7 +1421,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi menu: { id: MenuId.ExtensionContext, group: '2_configure', - when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('isDefaultApplicationScopedExtension').negate()), + when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('isDefaultApplicationScopedExtension').negate(), ContextKeyExpr.has('isBuiltinExtension').negate()), order: 3 }, run: async (accessor: ServicesAccessor, id: string) => { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index f8d7c21cea7..fc8215dff5b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -1431,7 +1431,7 @@ export function getAriaLabelForExtension(extension: IExtension | null): string { if (!extension) { return ''; } - const publisher = extension.publisherDomain?.verified ? localize('extension.arialabel.verifiedPublihser', "Verified Publisher {0}", extension.publisherDisplayName) : localize('extension.arialabel.publihser', "Publisher {0}", extension.publisherDisplayName); + const publisher = extension.publisherDomain?.verified ? localize('extension.arialabel.verifiedPublisher', "Verified Publisher {0}", extension.publisherDisplayName) : localize('extension.arialabel.publisher', "Publisher {0}", extension.publisherDisplayName); const deprecated = extension?.deprecationInfo ? localize('extension.arialabel.deprecated', "Deprecated") : ''; const rating = extension?.rating ? localize('extension.arialabel.rating', "Rated {0} out of 5 stars by {1} users", extension.rating.toFixed(2), extension.ratingCount) : ''; return `${extension.displayName}, ${deprecated ? `${deprecated}, ` : ''}${extension.version}, ${publisher}, ${extension.description} ${rating ? `, ${rating}` : ''}`; diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 96659a5f228..154696503e3 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -1622,7 +1622,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension } async toggleApplyExtensionToAllProfiles(extension: IExtension): Promise { - if (!extension.local || isApplicationScopedExtension(extension.local.manifest)) { + if (!extension.local || isApplicationScopedExtension(extension.local.manifest) || extension.isBuiltin) { return; } await this.extensionManagementService.toggleAppliationScope(extension.local, this.userDataProfileService.currentProfile.extensionsResource); diff --git a/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts b/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts index b3417372e48..b886e417338 100644 --- a/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts +++ b/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts @@ -281,7 +281,7 @@ export class FileBasedRecommendations extends ExtensionRecommendations { const language = model.getLanguageId(); const languageName = this.languageService.getLanguageName(language); if (importantRecommendations.size && - this.promptRecommendedExtensionForFileType(languageName && isImportantRecommendationForLanguage && language !== PLAINTEXT_LANGUAGE_ID ? localize('languageName', "{0} language", languageName) : basename(uri), language, [...importantRecommendations])) { + this.promptRecommendedExtensionForFileType(languageName && isImportantRecommendationForLanguage && language !== PLAINTEXT_LANGUAGE_ID ? localize('languageName', "the {0} language", languageName) : basename(uri), language, [...importantRecommendations])) { return; } } diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css b/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css index 174b332538b..575e6870b54 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css @@ -517,10 +517,6 @@ height: 224px; } -.extension-editor > .body > .content > .details > .readme-container > .extension-pack-readme.three-rows > .extension-pack { - height: 306px; -} - .extension-editor > .body > .content > .details > .readme-container > .extension-pack-readme.more-rows > .extension-pack { height: 326px; } diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts b/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts index fb876ba670a..afa94056cd5 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts @@ -47,7 +47,7 @@ export class TextFileEditorTracker extends Disposable implements IWorkbenchContr this._register(this.hostService.onDidChangeFocus(hasFocus => hasFocus ? this.reloadVisibleTextFileEditors() : undefined)); // Lifecycle - this.lifecycleService.onDidShutdown(() => this.dispose()); + this._register(this.lifecycleService.onDidShutdown(() => this.dispose())); } //#region Text File: Ensure every dirty text and untitled file is opened in an editor diff --git a/src/vs/workbench/contrib/files/browser/fileImportExport.ts b/src/vs/workbench/contrib/files/browser/fileImportExport.ts index e93695b3c16..56c7149a0ae 100644 --- a/src/vs/workbench/contrib/files/browser/fileImportExport.ts +++ b/src/vs/workbench/contrib/files/browser/fileImportExport.ts @@ -715,7 +715,7 @@ export class FileDownload { reject(canceled()); })); - disposables.add(listenStream(sourceStream, { + listenStream(sourceStream, { onData: data => { target.write(data.buffer); this.reportProgress(contents.name, contents.size, data.byteLength, operation); @@ -728,7 +728,7 @@ export class FileDownload { disposables.dispose(); resolve(); } - })); + }, token); }); } diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 76b81a7ed42..55039bcddd0 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -450,7 +450,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { } return false; }, - additionalScrollHeight: ExplorerDelegate.ITEM_HEIGHT, + paddingBottom: ExplorerDelegate.ITEM_HEIGHT, overrideStyles: { listBackground: SIDE_BAR_BACKGROUND } diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 6560e68e9a5..a25c052188a 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -1391,11 +1391,11 @@ export class FileDragAndDrop implements ITreeDragAndDrop { const resourceEdit = new ResourceFileEdit(resource, newResource, { copy: true, overwrite: allowOverwrite }); resourceFileEdits.push(resourceEdit); } - const labelSufix = getFileOrFolderLabelSufix(sources); + const labelSuffix = getFileOrFolderLabelSuffix(sources); await this.explorerService.applyBulkEdit(resourceFileEdits, { confirmBeforeUndo: explorerConfig.confirmUndo === UndoConfirmLevel.Default || explorerConfig.confirmUndo === UndoConfirmLevel.Verbose, - undoLabel: localize('copy', "Copy {0}", labelSufix), - progressLabel: localize('copying', "Copying {0}", labelSufix), + undoLabel: localize('copy', "Copy {0}", labelSuffix), + progressLabel: localize('copying', "Copying {0}", labelSuffix), }); const editors = resourceFileEdits.filter(edit => { @@ -1410,11 +1410,11 @@ export class FileDragAndDrop implements ITreeDragAndDrop { // Do not allow moving readonly items const resourceFileEdits = sources.filter(source => !source.isReadonly).map(source => new ResourceFileEdit(source.resource, joinPath(target.resource, source.name))); - const labelSufix = getFileOrFolderLabelSufix(sources); + const labelSuffix = getFileOrFolderLabelSuffix(sources); const options = { confirmBeforeUndo: this.configurationService.getValue().explorer.confirmUndo === UndoConfirmLevel.Verbose, - undoLabel: localize('move', "Move {0}", labelSufix), - progressLabel: localize('moving', "Moving {0}", labelSufix) + undoLabel: localize('move', "Move {0}", labelSuffix), + progressLabel: localize('moving', "Moving {0}", labelSuffix) }; try { @@ -1518,7 +1518,7 @@ export class ExplorerCompressionDelegate implements ITreeCompressionDelegate { instantiationService.stub(IWorkspaceTrustRequestService, new TestWorkspaceTrustRequestService(false)); const editorService: EditorService = instantiationService.createInstance(EditorService); + disposables.add(editorService); instantiationService.stub(IEditorService, editorService); const accessor = instantiationService.createInstance(TestServiceAccessor); @@ -93,6 +94,7 @@ suite('Files - TextFileEditorTracker', () => { const resource = toResource.call(this, '/path/index.txt'); const model = await accessor.textFileService.files.resolve(resource) as IResolvedTextFileEditorModel; + disposables.add(model); model.textEditorModel.setValue('Super Good'); assert.strictEqual(snapshotToString(model.createSnapshot()!), 'Super Good'); @@ -141,6 +143,7 @@ suite('Files - TextFileEditorTracker', () => { } const model = await accessor.textFileService.files.resolve(resource) as IResolvedTextFileEditorModel; + disposables.add(model); model.textEditorModel.setValue('Super Good'); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css index 457fd102c76..fe2e0ccde7a 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css @@ -42,7 +42,7 @@ display: flex; align-items: center; justify-content: space-between; - padding: 2px 2px 2px 4px; + padding: 2px 2px 2px 6px; background-color: var(--vscode-inlineChatInput-background); cursor: text; } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 104830cc852..023fee9cfd2 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -100,7 +100,9 @@ export class InlineChatController implements IEditorContribution { private _messages = this._store.add(new Emitter()); - private readonly _sessionStore: DisposableStore = new DisposableStore(); + readonly onDidAcceptInput = Event.filter(this._messages.event, m => m === Message.ACCEPT_INPUT, this._store); + + private readonly _sessionStore: DisposableStore = this._store.add(new DisposableStore()); private readonly _stashedSession: MutableDisposable = this._store.add(new MutableDisposable()); private _activeSession?: Session; private _strategy?: EditModeStrategy; @@ -146,6 +148,7 @@ export class InlineChatController implements IEditorContribution { } dispose(): void { + this._strategy?.dispose(); this._stashedSession.clear(); this.finishExistingSession(); this._store.dispose(); @@ -394,8 +397,7 @@ export class InlineChatController implements IEditorContribution { this._zone.value.widget.placeholder = this._getPlaceholderText(); if (options.message) { - this._zone.value.widget.value = options.message; - this._zone.value.widget.selectAll(); + this.updateInput(options.message); aria.alert(options.message); delete options.message; } @@ -757,6 +759,11 @@ export class InlineChatController implements IEditorContribution { this._messages.fire(Message.ACCEPT_INPUT); } + updateInput(text: string): void { + this._zone.value.widget.value = text; + this._zone.value.widget.selectAll(); + } + regenerate(): void { this._messages.fire(Message.RERUN_INPUT); } @@ -779,6 +786,10 @@ export class InlineChatController implements IEditorContribution { this._zone.value.widget.focus(); } + hasFocus(): boolean { + return this._zone.value.widget.hasFocus(); + } + populateHistory(up: boolean) { const len = InlineChatController._promptHistory.length; if (len === 0) { diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts index 434aea1f4d2..fcbb998dc79 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts @@ -385,6 +385,8 @@ export interface IInlineChatSessionService { // recordings(): readonly Recording[]; + + dispose(): void; } type SessionData = { diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index bf16c0aec05..343749ce5c6 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -230,7 +230,7 @@ export class InlineChatWidget { })); const uri = URI.from({ scheme: 'vscode', authority: 'inline-chat', path: `/inline-chat/model${InlineChatWidget._modelPool++}.txt` }); - this._inputModel = this._modelService.getModel(uri) ?? this._modelService.createModel('', null, uri); + this._inputModel = this._store.add(this._modelService.getModel(uri) ?? this._modelService.createModel('', null, uri)); this._inputEditor.setModel(this._inputModel); // --- context keys @@ -359,13 +359,13 @@ export class InlineChatWidget { this._store.add(feedbackToolbar); // preview editors - this._previewDiffEditor = new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedDiffEditorWidget2, this._elements.previewDiff, { + this._previewDiffEditor = this._store.add(new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedDiffEditorWidget2, this._elements.previewDiff, { ..._previewEditorEditorOptions, onlyShowAccessibleDiffViewer: this._accessibilityService.isScreenReaderOptimized(), - }, { modifiedEditor: codeEditorWidgetOptions, originalEditor: codeEditorWidgetOptions }, parentEditor))); + }, { modifiedEditor: codeEditorWidgetOptions, originalEditor: codeEditorWidgetOptions }, parentEditor)))); this._previewCreateTitle = this._store.add(_instantiationService.createInstance(ResourceLabel, this._elements.previewCreateTitle, { supportIcons: true })); - this._previewCreateEditor = new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedCodeEditorWidget, this._elements.previewCreate, _previewEditorEditorOptions, codeEditorWidgetOptions, parentEditor))); + this._previewCreateEditor = this._store.add(new IdleValue(() => this._store.add(_instantiationService.createInstance(EmbeddedCodeEditorWidget, this._elements.previewCreate, _previewEditorEditorOptions, codeEditorWidgetOptions, parentEditor)))); this._elements.message.tabIndex = 0; this._elements.message.ariaLabel = this._accessibleViewService.getOpenAriaHint(AccessibilityVerbositySettingId.InlineChat); @@ -756,7 +756,7 @@ export class InlineChatWidget { this._slashCommandContentWidget.show(); // inject detail when otherwise empty - if (firstLine === `/${command.command} `) { + if (firstLine === `/${command.command}`) { newDecorations.push({ range: new Range(1, withSlash.length + 1, 1, withSlash.length + 2), options: { diff --git a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts index ab5e4b27e1b..7a9beea7519 100644 --- a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts +++ b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts @@ -24,7 +24,6 @@ import { IEditorProgressService, IProgressRunner } from 'vs/platform/progress/co import { mock } from 'vs/base/test/common/mock'; import { Emitter, Event } from 'vs/base/common/event'; import { equals } from 'vs/base/common/arrays'; -import { timeout } from 'vs/base/common/async'; import { IChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chat'; import { IChatResponseViewModel } from 'vs/workbench/contrib/chat/common/chatViewModel'; import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; @@ -114,11 +113,11 @@ suite('InteractiveChatController', function () { }] ); - instaService = workbenchInstantiationService(undefined, store).createChild(serviceCollection); - inlineChatSessionService = instaService.get(IInlineChatSessionService); + instaService = store.add(workbenchInstantiationService(undefined, store).createChild(serviceCollection)); + inlineChatSessionService = store.add(instaService.get(IInlineChatSessionService)); - model = instaService.get(IModelService).createModel('Hello\nWorld\nHello Again\nHello World\n', null); - editor = instantiateTestCodeEditor(instaService, model); + model = store.add(instaService.get(IModelService).createModel('Hello\nWorld\nHello Again\nHello World\n', null)); + editor = store.add(instantiateTestCodeEditor(instaService, model)); store.add(inlineChatService.addProvider({ debugName: 'Unit Test', @@ -142,8 +141,6 @@ suite('InteractiveChatController', function () { }); teardown(function () { - editor.dispose(); - model.dispose(); store.clear(); ctrl?.dispose(); }); @@ -295,19 +292,8 @@ suite('InteractiveChatController', function () { wholeRange: new Range(3, 1, 3, 3) }; }, - async provideResponse(session, request) { - - // SLOW response - await timeout(50000); - - return { - type: InlineChatResponseType.EditorEdit, - id: Math.random(), - edits: [{ - range: new Range(1, 1, 1, 1), // EDIT happens outside of whole range - text: `${request.prompt}\n${request.prompt}` - }] - }; + provideResponse(session, request) { + return new Promise(() => { }); } }); store.add(d); diff --git a/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts b/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts index af697829ec1..3dd004897d2 100644 --- a/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts +++ b/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts @@ -11,14 +11,12 @@ import Severity from 'vs/base/common/severity'; import { getCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { localize } from 'vs/nls'; import { Registry } from 'vs/platform/registry/common/platform'; -import { themeColorFromId } from 'vs/platform/theme/common/themeService'; -import { ThemeColor, ThemeIcon } from 'vs/base/common/themables'; +import { ThemeIcon } from 'vs/base/common/themables'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { STATUS_BAR_ERROR_ITEM_BACKGROUND, STATUS_BAR_ERROR_ITEM_FOREGROUND, STATUS_BAR_WARNING_ITEM_BACKGROUND, STATUS_BAR_WARNING_ITEM_FOREGROUND } from 'vs/workbench/common/theme'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ILanguageStatus, ILanguageStatusService } from 'vs/workbench/services/languageStatus/common/languageStatusService'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, ShowTooltipCommand, StatusbarAlignment } from 'vs/workbench/services/statusbar/browser/statusbar'; +import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, ShowTooltipCommand, StatusbarAlignment, StatusbarEntryKind } from 'vs/workbench/services/statusbar/browser/statusbar'; import { parseLinkedText } from 'vs/base/common/linkedText'; import { Link } from 'vs/platform/opener/browser/link'; import { IOpenerService } from 'vs/platform/opener/common/opener'; @@ -367,14 +365,11 @@ class EditorStatusContribution implements IWorkbenchContribution { private static _asStatusbarEntry(item: ILanguageStatus): IStatusbarEntry { - let color: ThemeColor | undefined; - let backgroundColor: ThemeColor | undefined; + let kind: StatusbarEntryKind | undefined; if (item.severity === Severity.Warning) { - color = themeColorFromId(STATUS_BAR_WARNING_ITEM_FOREGROUND); - backgroundColor = themeColorFromId(STATUS_BAR_WARNING_ITEM_BACKGROUND); + kind = 'warning'; } else if (item.severity === Severity.Error) { - color = themeColorFromId(STATUS_BAR_ERROR_ITEM_FOREGROUND); - backgroundColor = themeColorFromId(STATUS_BAR_ERROR_ITEM_BACKGROUND); + kind = 'error'; } return { @@ -383,8 +378,7 @@ class EditorStatusContribution implements IWorkbenchContribution { ariaLabel: item.accessibilityInfo?.label ?? item.label, role: item.accessibilityInfo?.role, tooltip: item.command?.tooltip || new MarkdownString(item.detail, { isTrusted: true, supportThemeIcons: true }), - color, - backgroundColor, + kind, command: item.command }; } diff --git a/src/vs/workbench/contrib/mappedEdits/common/mappedEdits.contribution.ts b/src/vs/workbench/contrib/mappedEdits/common/mappedEdits.contribution.ts new file mode 100644 index 00000000000..fc753a4b673 --- /dev/null +++ b/src/vs/workbench/contrib/mappedEdits/common/mappedEdits.contribution.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { URI } from 'vs/base/common/uri'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { ITextModelService } from 'vs/editor/common/services/resolverService'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import * as languages from 'vs/editor/common/languages'; + +CommandsRegistry.registerCommand( + '_executeMappedEditsProvider', + async ( + accessor: ServicesAccessor, + documentUri: URI, + codeBlocks: string[], + context: languages.MappedEditsContext + ): Promise => { + + const modelService = accessor.get(ITextModelService); + const langFeaturesService = accessor.get(ILanguageFeaturesService); + + const document = await modelService.createModelReference(documentUri); + + let result: languages.WorkspaceEdit | null = null; + + try { + const providers = langFeaturesService.mappedEditsProvider.ordered(document.object.textEditorModel); + + if (providers.length > 0) { + const mostRelevantProvider = providers[0]; + + const cancellationTokenSource = new CancellationTokenSource(); + + result = await mostRelevantProvider.provideMappedEdits( + document.object.textEditorModel, + codeBlocks, + context, + cancellationTokenSource.token + ); + } + } finally { + document.dispose(); + } + + return result; + } +); diff --git a/src/vs/workbench/contrib/markers/test/browser/markersModel.test.ts b/src/vs/workbench/contrib/markers/test/browser/markersModel.test.ts index 9cb2c9dc650..b8334c948d6 100644 --- a/src/vs/workbench/contrib/markers/test/browser/markersModel.test.ts +++ b/src/vs/workbench/contrib/markers/test/browser/markersModel.test.ts @@ -8,6 +8,7 @@ import { URI } from 'vs/base/common/uri'; import { IMarker, MarkerSeverity, IRelatedInformation } from 'vs/platform/markers/common/markers'; import { MarkersModel, Marker, ResourceMarkers, RelatedInformation } from 'vs/workbench/contrib/markers/browser/markersModel'; import { groupBy } from 'vs/base/common/collections'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; class TestMarkersModel extends MarkersModel { @@ -27,6 +28,8 @@ class TestMarkersModel extends MarkersModel { suite('MarkersModel Test', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('marker ids are unique', function () { const marker1 = anErrorWithRange(3); const marker2 = anErrorWithRange(3); diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/editorStatusBar/editorStatusBar.ts b/src/vs/workbench/contrib/notebook/browser/contrib/editorStatusBar/editorStatusBar.ts index e7c3a8d12c2..633dedb4a4b 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/editorStatusBar/editorStatusBar.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/editorStatusBar/editorStatusBar.ts @@ -167,7 +167,7 @@ export class KernelStatus extends Disposable implements IWorkbenchContribution { text: nls.localize('kernel.select.label', "Select Kernel"), ariaLabel: nls.localize('kernel.select.label', "Select Kernel"), command: SELECT_KERNEL_ID, - backgroundColor: { id: 'statusBarItem.prominentBackground' } + kind: 'prominent' }, SELECT_KERNEL_ID, StatusbarAlignment.RIGHT, diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts b/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts index 36a8c18f69b..cf6589b6027 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts @@ -208,6 +208,7 @@ export class NotebookCellOutline implements IOutline { } private _outlineProvider: NotebookCellOutlineProvider | undefined; + private _localDisposables = new DisposableStore(); constructor( private readonly _editor: INotebookEditorPane, @@ -221,9 +222,14 @@ export class NotebookCellOutline implements IOutline { if (!notebookEditor?.hasModel()) { this._outlineProvider?.dispose(); this._outlineProvider = undefined; + this._localDisposables.clear(); } else { this._outlineProvider?.dispose(); + this._localDisposables.clear(); this._outlineProvider = instantiationService.createInstance(NotebookCellOutlineProvider, notebookEditor, _target); + this._localDisposables.add(this._outlineProvider.onDidChange(e => { + this._onDidChange.fire(e); + })); } }; @@ -231,8 +237,6 @@ export class NotebookCellOutline implements IOutline { installSelectionListener(); })); - - installSelectionListener(); const treeDataSource: IDataSource = { getChildren: parent => parent instanceof NotebookCellOutline ? (this._outlineProvider?.entries ?? []) : parent.children }; const delegate = new NotebookOutlineVirtualDelegate(); @@ -315,6 +319,7 @@ export class NotebookCellOutline implements IOutline { this._dispoables.dispose(); this._entriesDisposables.dispose(); this._outlineProvider?.dispose(); + this._localDisposables.dispose(); } } diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index 8bbe932cb1f..2ef3dfb4e8e 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -455,7 +455,7 @@ class CellInfoContentProvider { let result: { content: string; mode: ILanguageSelection } | undefined = undefined; const mode = this._languageService.createById('json'); - const op = cell.outputs.find(op => op.outputId === data.outputId); + const op = cell.outputs.find(op => op.outputId === data.outputId || op.alternativeOutputId === data.outputId); const streamOutputData = this.parseStreamOutput(op); if (streamOutputData) { result = streamOutputData; @@ -491,7 +491,7 @@ class CellInfoContentProvider { } const ref = await this._notebookModelResolverService.resolve(data.notebook); - const cell = ref.object.notebook.cells.find(cell => !!cell.outputs.find(op => op.outputId === data.outputId)); + const cell = ref.object.notebook.cells.find(cell => !!cell.outputs.find(op => op.outputId === data.outputId || op.alternativeOutputId === data.outputId)); if (!cell) { ref.dispose(); diff --git a/src/vs/workbench/contrib/notebook/browser/notebookAccessibility.ts b/src/vs/workbench/contrib/notebook/browser/notebookAccessibility.ts index 790e9e8bdc3..a019db5693e 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookAccessibility.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookAccessibility.ts @@ -34,7 +34,7 @@ export function getAccessibilityHelpText(accessor: ServicesAccessor): string { content.push(localize('notebook.changeCellType', 'The Change Cell to Code/Markdown commands are used to switch between cell types.')); - return content.join('\n'); + return content.join('\n\n'); } function descriptionForCommand(commandId: string, msg: string, noKbMsg: string, keybindingService: IKeybindingService): string { diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts index 7256ad1d404..7901ccc3e16 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { LinkedMap, Touch } from 'vs/base/common/map'; import { localize } from 'vs/nls'; import { Categories } from 'vs/platform/action/common/actionCommonCategories'; @@ -36,6 +36,9 @@ export class NotebookKernelHistoryService extends Disposable implements INoteboo this._loadState(); this._register(this._storageService.onWillSaveState(() => this._saveState())); + this._register(this._storageService.onDidChangeValue(StorageScope.WORKSPACE, NotebookKernelHistoryService.STORAGE_KEY, this._register(new DisposableStore()))(() => { + this._restoreState(); + })); } getKernels(notebook: INotebookTextModelLike): { selected: INotebookKernel | undefined; all: INotebookKernel[] } { @@ -79,12 +82,30 @@ export class NotebookKernelHistoryService extends Disposable implements INoteboo if (notEmpty) { const serialized = this._serialize(); - this._storageService.store(NotebookKernelHistoryService.STORAGE_KEY, JSON.stringify(serialized), StorageScope.WORKSPACE, StorageTarget.MACHINE); + this._storageService.store(NotebookKernelHistoryService.STORAGE_KEY, JSON.stringify(serialized), StorageScope.WORKSPACE, StorageTarget.USER); } else { this._storageService.remove(NotebookKernelHistoryService.STORAGE_KEY, StorageScope.WORKSPACE); } } + private _restoreState(): void { + const serialized = this._storageService.get(NotebookKernelHistoryService.STORAGE_KEY, StorageScope.WORKSPACE); + if (serialized) { + try { + for (const [viewType, kernels] of JSON.parse(serialized)) { + const linkedMap = this._mostRecentKernelsMap[viewType] ?? new LinkedMap(); + for (const entry of kernels.entries) { + linkedMap.set(entry, entry, Touch.AsOld); + } + + this._mostRecentKernelsMap[viewType] = linkedMap; + } + } catch (e) { + console.error('Deserialize notebook kernel history failed', e); + } + } + } + private _loadState(): void { const serialized = this._storageService.get(NotebookKernelHistoryService.STORAGE_KEY, StorageScope.WORKSPACE); if (serialized) { diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts index 85ed20571d1..2e2ad62c97e 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts @@ -25,6 +25,15 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp return this._rawOutput.outputId; } + /** + * Alternative output id that's reused when the output is updated. + */ + private _alternativeOutputId: string; + + get alternativeOutputId(): string { + return this._alternativeOutputId; + } + private _versionId = 0; get versionId() { @@ -35,6 +44,8 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp private _rawOutput: IOutputDto ) { super(); + + this._alternativeOutputId = this._rawOutput.outputId; } replaceData(rawData: IOutputDto) { diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index e01a5c37361..2182e98f021 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -15,7 +15,7 @@ import { basename } from 'vs/base/common/path'; import { isWindows } from 'vs/base/common/platform'; import { ISplice } from 'vs/base/common/sequence'; import { URI, UriComponents } from 'vs/base/common/uri'; -import { ILineChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { Command, WorkspaceEditMetadata } from 'vs/editor/common/languages'; import { IReadonlyTextBuffer } from 'vs/editor/common/model'; @@ -214,6 +214,10 @@ export interface ICellOutput { outputs: IOutputItemDto[]; metadata?: Record; outputId: string; + /** + * Alternative output id that's reused when the output is updated. + */ + alternativeOutputId: string; onDidChangeData: Event; replaceData(items: IOutputDto): void; appendData(items: IOutputItemDto[]): void; diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookKernelHistory.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookKernelHistory.test.ts index bb7e0967612..52eadf224ae 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookKernelHistory.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookKernelHistory.test.ts @@ -18,7 +18,7 @@ import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/no import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; import { IMenu, IMenuService } from 'vs/platform/actions/common/actions'; import { NotebookKernelHistoryService } from 'vs/workbench/contrib/notebook/browser/services/notebookKernelHistoryServiceImpl'; -import { IStorageService, IWillSaveStateEvent, StorageScope } from 'vs/platform/storage/common/storage'; +import { IApplicationStorageValueChangeEvent, IProfileStorageValueChangeEvent, IStorageService, IStorageValueChangeEvent, IWillSaveStateEvent, IWorkspaceStorageValueChangeEvent, StorageScope } from 'vs/platform/storage/common/storage'; import { INotebookLoggingService } from 'vs/workbench/contrib/notebook/common/notebookLoggingService'; suite('NotebookKernelHistoryService', () => { @@ -70,6 +70,12 @@ suite('NotebookKernelHistoryService', () => { instantiationService.stub(IStorageService, new class extends mock() { override onWillSaveState: Event = Event.None; + override onDidChangeValue(scope: StorageScope.WORKSPACE, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope.PROFILE, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope.APPLICATION, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope, key: string | undefined, disposable: DisposableStore): Event { + return Event.None; + } override get(key: string, scope: StorageScope, fallbackValue: string): string; override get(key: string, scope: StorageScope, fallbackValue?: string | undefined): string | undefined; override get(key: unknown, scope: unknown, fallbackValue?: unknown): string | undefined { @@ -119,6 +125,12 @@ suite('NotebookKernelHistoryService', () => { instantiationService.stub(IStorageService, new class extends mock() { override onWillSaveState: Event = Event.None; + override onDidChangeValue(scope: StorageScope.WORKSPACE, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope.PROFILE, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope.APPLICATION, key: string | undefined, disposable: DisposableStore): Event; + override onDidChangeValue(scope: StorageScope, key: string | undefined, disposable: DisposableStore): Event { + return Event.None; + } override get(key: string, scope: StorageScope, fallbackValue: string): string; override get(key: string, scope: StorageScope, fallbackValue?: string | undefined): string | undefined; override get(key: unknown, scope: unknown, fallbackValue?: unknown): string | undefined { diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts index 486c29e09be..fe7ce4b6848 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts @@ -21,6 +21,7 @@ import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ISemanticSimilarityService } from 'vs/workbench/services/semanticSimilarity/common/semanticSimilarityService'; +import { IAiRelatedInformationService, RelatedInformationType, SettingInformationResult } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation'; export interface IEndpointDetails { urlBase?: string; @@ -302,8 +303,10 @@ class RemoteSearchKeysProvider { private settingsRecord: Record = {}; private currentPreferencesModel: ISettingsEditorModel | undefined; - constructor(private readonly semanticSimilarityService: ISemanticSimilarityService) { - } + constructor( + private readonly aiRelatedInformationService: IAiRelatedInformationService, + private readonly semanticSimilarityService: ISemanticSimilarityService + ) { } updateModel(preferencesModel: ISettingsEditorModel) { if (preferencesModel === this.currentPreferencesModel) { @@ -318,7 +321,10 @@ class RemoteSearchKeysProvider { this.settingKeys = []; this.settingsRecord = {}; - if (!this.semanticSimilarityService.isEnabled() || !this.currentPreferencesModel) { + if ( + !this.currentPreferencesModel || + (!this.semanticSimilarityService.isEnabled() && !this.aiRelatedInformationService.isEnabled()) + ) { return; } @@ -353,8 +359,9 @@ export class RemoteSearchProvider implements ISearchProvider { constructor( @ISemanticSimilarityService private readonly semanticSimilarityService: ISemanticSimilarityService, + @IAiRelatedInformationService private readonly aiRelatedInformationService: IAiRelatedInformationService ) { - this._keysProvider = new RemoteSearchKeysProvider(semanticSimilarityService); + this._keysProvider = new RemoteSearchKeysProvider(aiRelatedInformationService, semanticSimilarityService); } setFilter(filter: string) { @@ -362,11 +369,26 @@ export class RemoteSearchProvider implements ISearchProvider { } async searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken | undefined): Promise { - if (!this.semanticSimilarityService.isEnabled() || !this._filter) { + if ( + !this._filter || + (!this.semanticSimilarityService.isEnabled() && !this.aiRelatedInformationService.isEnabled())) { return null; } this._keysProvider.updateModel(preferencesModel); + const filterMatches = this.aiRelatedInformationService.isEnabled() + ? await this.getAiRelatedInformationItems(token) + : this.semanticSimilarityService.isEnabled() + ? await this.getSemanticSimilarityItems(token) + : []; + + return { + filterMatches + }; + } + + // TODO: Remove this when all semantic similarity providers are migrated to aiRelatedInformationService + private async getSemanticSimilarityItems(token?: CancellationToken | undefined) { const settingKeys = this._keysProvider.getSettingKeys(); const settingsRecord = this._keysProvider.getSettingsRecord(); @@ -389,9 +411,31 @@ export class RemoteSearchProvider implements ISearchProvider { }); numOfSmartPicks++; } - return { - filterMatches - }; + + return filterMatches; + } + + private async getAiRelatedInformationItems(token?: CancellationToken | undefined) { + const settingsRecord = this._keysProvider.getSettingsRecord(); + + const filterMatches: ISettingMatch[] = []; + const relatedInformation = await this.aiRelatedInformationService.getRelatedInformation(this._filter, [RelatedInformationType.SettingInformation], token ?? CancellationToken.None) as SettingInformationResult[]; + relatedInformation.sort((a, b) => b.weight - a.weight); + + for (const info of relatedInformation) { + if (info.weight < RemoteSearchProvider.SEMANTIC_SIMILARITY_THRESHOLD || filterMatches.length === RemoteSearchProvider.SEMANTIC_SIMILARITY_MAX_PICKS) { + break; + } + const pick = info.setting; + filterMatches.push({ + setting: settingsRecord[pick], + matches: [settingsRecord[pick].range], + matchType: SettingMatchType.RemoteMatch, + score: info.weight + }); + } + + return filterMatches; } } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts index bcd2604c8d7..180f990b5a5 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts @@ -273,7 +273,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { } private getTargetToInspect(setting: ISetting): SettingsTarget { - if (!this.userDataProfileService.currentProfile.isDefault) { + if (!this.userDataProfileService.currentProfile.isDefault && !this.userDataProfileService.currentProfile.useDefaultFlags?.settings) { if (setting.scope === ConfigurationScope.APPLICATION) { return ConfigurationTarget.APPLICATION; } diff --git a/src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts b/src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts index dd837a29ec7..4df3b8e287f 100644 --- a/src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts +++ b/src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts @@ -36,6 +36,7 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { ISemanticSimilarityService } from 'vs/workbench/services/semanticSimilarity/common/semanticSimilarityService'; import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; import { ASK_QUICK_QUESTION_ACTION_ID } from 'vs/workbench/contrib/chat/browser/actions/chatQuickInputActions'; +import { CommandInformationResult, IAiRelatedInformationService, RelatedInformationType } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation'; export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAccessProvider { @@ -75,6 +76,7 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce @IPreferencesService private readonly preferencesService: IPreferencesService, @IProductService private readonly productService: IProductService, @ISemanticSimilarityService private readonly semanticSimilarityService: ISemanticSimilarityService, + @IAiRelatedInformationService private readonly aiRelatedInformationService: IAiRelatedInformationService, @IChatService private readonly chatService: IChatService ) { super({ @@ -137,7 +139,12 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce } protected hasAdditionalCommandPicks(filter: string, token: CancellationToken): boolean { - if (!this.useSemanticSimilarity || filter === '' || token.isCancellationRequested || !this.semanticSimilarityService.isEnabled()) { + if ( + !this.useSemanticSimilarity + || token.isCancellationRequested + || filter === '' + || !(this.semanticSimilarityService.isEnabled() || this.aiRelatedInformationService.isEnabled()) + ) { return false; } @@ -149,16 +156,49 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce return []; } - const format = allPicks.map(p => p.commandId); - let scores: number[]; + let additionalPicks; + try { // Wait a bit to see if the user is still typing await timeout(CommandsQuickAccessProvider.SEMANTIC_SIMILARITY_DEBOUNCE, token); - scores = await this.semanticSimilarityService.getSimilarityScore(filter, format, token); + additionalPicks = this.aiRelatedInformationService.isEnabled() + ? await this.getRelatedInformationPicks(allPicks, picksSoFar, filter, token) + : this.semanticSimilarityService.isEnabled() + ? await this.getSemanticSimilarityPicks(allPicks, picksSoFar, filter, token) + : []; } catch (e) { return []; } + if (additionalPicks.length) { + additionalPicks.unshift({ + type: 'separator', + label: localize('semanticSimilarity', "similar commands") + }); + } + + if (picksSoFar.length || additionalPicks.length) { + additionalPicks.push({ + type: 'separator' + }); + } + + const info = this.chatService.getProviderInfos()[0]; + if (info) { + additionalPicks.push({ + label: localize('askXInChat', "Ask {0}: {1}", info.displayName, filter), + commandId: ASK_QUICK_QUESTION_ACTION_ID, + args: [filter] + }); + } + + return additionalPicks; + } + + private async getSemanticSimilarityPicks(allPicks: ICommandQuickPick[], picksSoFar: ICommandQuickPick[], filter: string, token: CancellationToken) { + const format = allPicks.map(p => p.commandId); + const scores = await this.semanticSimilarityService.getSimilarityScore(filter, format, token); + if (token.isCancellationRequested) { return []; } @@ -181,26 +221,30 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce } } - if (numOfSmartPicks) { - additionalPicks.unshift({ - type: 'separator', - label: localize('semanticSimilarity', "similar commands") - }); - } + return additionalPicks; + } - if (picksSoFar.length || additionalPicks.length) { - additionalPicks.push({ - type: 'separator' - }); - } + private async getRelatedInformationPicks(allPicks: ICommandQuickPick[], picksSoFar: ICommandQuickPick[], filter: string, token: CancellationToken) { + const relatedInformation = await this.aiRelatedInformationService.getRelatedInformation( + filter, + [RelatedInformationType.CommandInformation], + token + ) as CommandInformationResult[]; - const info = this.chatService.getProviderInfos()[0]; - if (info) { - additionalPicks.push({ - label: localize('askXInChat', "Ask {0}: {1}", info.displayName, filter), - commandId: ASK_QUICK_QUESTION_ACTION_ID, - args: [filter] - }); + // Sort by weight descending to get the most relevant results first + relatedInformation.sort((a, b) => b.weight - a.weight); + + const setOfPicksSoFar = new Set(picksSoFar.map(p => p.commandId)); + const additionalPicks = new Array(); + + for (const info of relatedInformation) { + if (info.weight < CommandsQuickAccessProvider.SEMANTIC_SIMILARITY_THRESHOLD || additionalPicks.length === CommandsQuickAccessProvider.SEMANTIC_SIMILARITY_MAX_PICKS) { + break; + } + const pick = allPicks.find(p => p.commandId === info.command && !setOfPicksSoFar.has(p.commandId)); + if (pick) { + additionalPicks.push(pick); + } } return additionalPicks; diff --git a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts index 3130f1911ca..cab8b0d506e 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts @@ -4,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import { STATUS_BAR_HOST_NAME_BACKGROUND, STATUS_BAR_HOST_NAME_FOREGROUND } from 'vs/workbench/common/theme'; -import { themeColorFromId } from 'vs/platform/theme/common/themeService'; import { IRemoteAgentService, remoteConnectionLatencyMeasurer } from 'vs/workbench/services/remote/common/remoteAgentService'; import { RunOnceScheduler, retry } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; @@ -45,7 +43,6 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { IProductService } from 'vs/platform/product/common/productService'; import { DomEmitter } from 'vs/base/browser/event'; -import { registerColor } from 'vs/platform/theme/common/colorRegistry'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ThemeIcon } from 'vs/base/common/themables'; @@ -53,20 +50,6 @@ import { infoIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcon import { IOpenerService } from 'vs/platform/opener/common/opener'; import { URI } from 'vs/base/common/uri'; -export const STATUS_BAR_OFFLINE_BACKGROUND = registerColor('statusBar.offlineBackground', { - dark: '#6c1717', - light: '#6c1717', - hcDark: '#6c1717', - hcLight: '#6c1717' -}, nls.localize('statusBarOfflineBackground', "Status bar background color when the workbench is offline. The status bar is shown in the bottom of the window")); - -export const STATUS_BAR_OFFLINE_FOREGROUND = registerColor('statusBar.offlineForeground', { - dark: STATUS_BAR_HOST_NAME_FOREGROUND, - light: STATUS_BAR_HOST_NAME_FOREGROUND, - hcDark: STATUS_BAR_HOST_NAME_FOREGROUND, - hcLight: STATUS_BAR_HOST_NAME_FOREGROUND -}, nls.localize('statusBarOfflineForeground', "Status bar foreground color when the workbench is offline. The status bar is shown in the bottom of the window")); - type ActionGroup = [string, Array]; interface RemoteExtensionMetadata { @@ -558,8 +541,7 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr const properties: IStatusbarEntry = { name: nls.localize('remoteHost', "Remote Host"), - backgroundColor: themeColorFromId(this.networkState === 'offline' ? STATUS_BAR_OFFLINE_BACKGROUND : STATUS_BAR_HOST_NAME_BACKGROUND), - color: themeColorFromId(this.networkState === 'offline' ? STATUS_BAR_OFFLINE_FOREGROUND : STATUS_BAR_HOST_NAME_FOREGROUND), + kind: this.networkState === 'offline' ? 'offline' : 'remote', ariaLabel, text, showProgress, diff --git a/src/vs/workbench/contrib/remote/browser/tunnelView.ts b/src/vs/workbench/contrib/remote/browser/tunnelView.ts index 8f94225be44..2289a2ece04 100644 --- a/src/vs/workbench/contrib/remote/browser/tunnelView.ts +++ b/src/vs/workbench/contrib/remote/browser/tunnelView.ts @@ -52,7 +52,7 @@ import { registerColor } from 'vs/platform/theme/common/colorRegistry'; import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent'; import { IHoverDelegateOptions } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate'; import { IHoverService } from 'vs/workbench/services/hover/browser/hover'; -import { STATUS_BAR_HOST_NAME_BACKGROUND } from 'vs/workbench/common/theme'; +import { STATUS_BAR_REMOTE_ITEM_BACKGROUND } from 'vs/workbench/common/theme'; import { Codicon } from 'vs/base/common/codicons'; import { defaultButtonStyles, defaultInputBoxStyles } from 'vs/platform/theme/browser/defaultStyles'; import { Attributes, CandidatePort, Tunnel, TunnelCloseReason, TunnelModel, TunnelSource, forwardedPortsViewEnabled, makeAddress, mapHasAddressLocalhostOrAllInterfaces, parseAddress } from 'vs/workbench/services/remote/common/tunnelModel'; @@ -744,7 +744,9 @@ export class TunnelPanel extends ViewPane { static readonly ID = TUNNEL_VIEW_ID; static readonly TITLE = nls.localize('remote.tunnel', "Ports"); + private panelContainer: HTMLElement | undefined; private table!: WorkbenchTable; + private tableDisposables: DisposableStore = this._register(new DisposableStore()); private tunnelTypeContext: IContextKey; private tunnelCloseableContext: IContextKey; private tunnelPrivacyContext: IContextKey; @@ -783,7 +785,7 @@ export class TunnelPanel extends ViewPane { this.tunnelCloseableContext = TunnelCloseableContextKey.bindTo(contextKeyService); this.tunnelPrivacyContext = TunnelPrivacyContextKey.bindTo(contextKeyService); this.tunnelPrivacyEnabledContext = TunnelPrivacyEnabledContextKey.bindTo(contextKeyService); - this.tunnelPrivacyEnabledContext.set(tunnelService.privacyOptions.length !== 0); + this.tunnelPrivacyEnabledContext.set(tunnelService.canChangePrivacy); this.tunnelProtocolContext = TunnelProtocolContextKey.bindTo(contextKeyService); this.tunnelViewFocusContext = TunnelViewFocusContextKey.bindTo(contextKeyService); this.tunnelViewSelectionContext = TunnelViewSelectionContextKey.bindTo(contextKeyService); @@ -806,6 +808,15 @@ export class TunnelPanel extends ViewPane { })); this.registerPrivacyActions(); + this._register(Event.once(this.tunnelService.onAddedTunnelProvider)(() => { + if (this.tunnelPrivacyEnabledContext.get() === false) { + this.tunnelPrivacyEnabledContext.set(tunnelService.canChangePrivacy); + updateActions(); + this.registerPrivacyActions(); + this.createTable(); + this.table.layout(this.height, this.width); + } + })); } private registerPrivacyActions() { @@ -827,11 +838,15 @@ export class TunnelPanel extends ViewPane { return this.remoteExplorerService.tunnelModel.forwarded.size + this.remoteExplorerService.tunnelModel.detected.size; } - protected override renderBody(container: HTMLElement): void { - super.renderBody(container); + private createTable(): void { + if (!this.panelContainer) { + return; + } + this.tableDisposables.clear(); - const panelContainer = dom.append(container, dom.$('.tree-explorer-viewlet-tree-view')); - const widgetContainer = dom.append(panelContainer, dom.$('.customview-tree')); + dom.clearNode(this.panelContainer); + + const widgetContainer = dom.append(this.panelContainer, dom.$('.customview-tree')); widgetContainer.classList.add('ports-view'); widgetContainer.classList.add('file-icon-themable-tree', 'show-file-icons'); @@ -874,18 +889,19 @@ export class TunnelPanel extends ViewPane { const actionRunner: ActionRunner = new ActionRunner(); actionBarRenderer.actionRunner = actionRunner; - this._register(this.table.onContextMenu(e => this.onContextMenu(e, actionRunner))); - this._register(this.table.onMouseDblClick(e => this.onMouseDblClick(e))); - this._register(this.table.onDidChangeFocus(e => this.onFocusChanged(e))); - this._register(this.table.onDidChangeSelection(e => this.onSelectionChanged(e))); - this._register(this.table.onDidFocus(() => this.tunnelViewFocusContext.set(true))); - this._register(this.table.onDidBlur(() => this.tunnelViewFocusContext.set(false))); + this.tableDisposables.add(this.table); + this.tableDisposables.add(this.table.onContextMenu(e => this.onContextMenu(e, actionRunner))); + this.tableDisposables.add(this.table.onMouseDblClick(e => this.onMouseDblClick(e))); + this.tableDisposables.add(this.table.onDidChangeFocus(e => this.onFocusChanged(e))); + this.tableDisposables.add(this.table.onDidChangeSelection(e => this.onSelectionChanged(e))); + this.tableDisposables.add(this.table.onDidFocus(() => this.tunnelViewFocusContext.set(true))); + this.tableDisposables.add(this.table.onDidBlur(() => this.tunnelViewFocusContext.set(false))); const rerender = () => this.table.splice(0, Number.POSITIVE_INFINITY, this.viewModel.all); rerender(); let lastPortCount = this.portCount; - this._register(Event.debounce(this.viewModel.onForwardedPortsChanged, (_last, e) => e, 50)(() => { + this.tableDisposables.add(Event.debounce(this.viewModel.onForwardedPortsChanged, (_last, e) => e, 50)(() => { const newPortCount = this.portCount; if (((lastPortCount === 0) || (newPortCount === 0)) && (lastPortCount !== newPortCount)) { this._onDidChangeViewWelcomeState.fire(); @@ -894,7 +910,7 @@ export class TunnelPanel extends ViewPane { rerender(); })); - this._register(this.table.onMouseClick(e => { + this.tableDisposables.add(this.table.onMouseClick(e => { if (this.hasOpenLinkModifier(e.browserEvent)) { const selection = this.table.getSelectedElements(); if ((selection.length === 0) || @@ -904,7 +920,7 @@ export class TunnelPanel extends ViewPane { } })); - this._register(this.table.onDidOpen(e => { + this.tableDisposables.add(this.table.onDidOpen(e => { if (!e.element || (e.element.tunnelType !== TunnelType.Forwarded)) { return; } @@ -913,7 +929,7 @@ export class TunnelPanel extends ViewPane { } })); - this._register(this.remoteExplorerService.onDidChangeEditable(e => { + this.tableDisposables.add(this.remoteExplorerService.onDidChangeEditable(e => { this.isEditing = !!this.remoteExplorerService.getEditableData(e?.tunnel, e?.editId); this._onDidChangeViewWelcomeState.fire(); @@ -938,6 +954,13 @@ export class TunnelPanel extends ViewPane { })); } + protected override renderBody(container: HTMLElement): void { + super.renderBody(container); + + this.panelContainer = dom.append(container, dom.$('.tree-explorer-viewlet-tree-view')); + this.createTable(); + } + override shouldShowWelcome(): boolean { return this.viewModel.isEmpty() && !this.isEditing; } @@ -1048,7 +1071,11 @@ export class TunnelPanel extends ViewPane { } } + private height = 0; + private width = 0; protected override layoutBody(height: number, width: number): void { + this.height = height; + this.width = width; super.layoutBody(height, width); this.table.layout(height, width); } @@ -1775,9 +1802,9 @@ MenuRegistry.appendMenuItem(MenuId.TunnelLocalAddressInline, ({ })); registerColor('ports.iconRunningProcessForeground', { - light: STATUS_BAR_HOST_NAME_BACKGROUND, - dark: STATUS_BAR_HOST_NAME_BACKGROUND, - hcDark: STATUS_BAR_HOST_NAME_BACKGROUND, - hcLight: STATUS_BAR_HOST_NAME_BACKGROUND + light: STATUS_BAR_REMOTE_ITEM_BACKGROUND, + dark: STATUS_BAR_REMOTE_ITEM_BACKGROUND, + hcDark: STATUS_BAR_REMOTE_ITEM_BACKGROUND, + hcLight: STATUS_BAR_REMOTE_ITEM_BACKGROUND }, nls.localize('portWithRunningProcess.foreground', "The color of the icon for a port that has an associated running process.")); diff --git a/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts b/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts index 41ac8d05a2b..589c0e5e99d 100644 --- a/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts +++ b/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts @@ -50,7 +50,7 @@ import { ThemeIcon } from 'vs/base/common/themables'; import { onUnexpectedError } from 'vs/base/common/errors'; import { TextCompareEditorActiveContext } from 'vs/workbench/common/contextkeys'; import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; -import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer'; +import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { Color } from 'vs/base/common/color'; import { ResourceMap } from 'vs/base/common/map'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; diff --git a/src/vs/workbench/contrib/search/browser/notebookSearchContributions.ts b/src/vs/workbench/contrib/search/browser/notebookSearchContributions.ts index 03b44bf0026..57d73a21c3f 100644 --- a/src/vs/workbench/contrib/search/browser/notebookSearchContributions.ts +++ b/src/vs/workbench/contrib/search/browser/notebookSearchContributions.ts @@ -7,7 +7,7 @@ import { ReplacePreviewContentProvider } from 'vs/workbench/contrib/search/brows import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import { INotebookSearchService } from 'vs/workbench/contrib/search/browser/notebookSearch'; +import { INotebookSearchService } from 'vs/workbench/contrib/search/common/notebookSearch'; import { NotebookSearchService } from 'vs/workbench/contrib/search/browser/notebookSearchService'; export function registerContributions(): void { diff --git a/src/vs/workbench/contrib/search/browser/notebookSearchService.ts b/src/vs/workbench/contrib/search/browser/notebookSearchService.ts index adee7532d41..19b45f30903 100644 --- a/src/vs/workbench/contrib/search/browser/notebookSearchService.ts +++ b/src/vs/workbench/contrib/search/browser/notebookSearchService.ts @@ -18,10 +18,10 @@ import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/mode import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; import { INotebookExclusiveDocumentFilter, NotebookData } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookSerializer, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService'; -import { INotebookSearchService } from 'vs/workbench/contrib/search/browser/notebookSearch'; +import { INotebookSearchService } from 'vs/workbench/contrib/search/common/notebookSearch'; import { IFileMatchWithCells, ICellMatch, CellSearchModel, contentMatchesToTextSearchMatches, webviewMatchesToTextSearchMatches, genericCellMatchesToTextSearchMatches } from 'vs/workbench/contrib/search/browser/searchNotebookHelpers'; import { IEditorResolverService, priorityToRank } from 'vs/workbench/services/editor/common/editorResolverService'; -import { ITextQuery, IFileQuery, QueryType, ISearchProgressItem, ISearchComplete, ISearchConfigurationProperties, ISearchService } from 'vs/workbench/services/search/common/search'; +import { ITextQuery, QueryType, ISearchProgressItem, ISearchComplete, ISearchConfigurationProperties, IFileQuery, ISearchService } from 'vs/workbench/services/search/common/search'; import * as arrays from 'vs/base/common/arrays'; import { isNumber } from 'vs/base/common/types'; @@ -123,48 +123,67 @@ export class NotebookSearchService implements INotebookSearchService { return Array.from(uris.keys()); } - async notebookSearch(query: ITextQuery, token: CancellationToken, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }> { + notebookSearch(query: ITextQuery, token: CancellationToken | undefined, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): { + openFilesToScan: ResourceSet; + completeData: Promise; + allScannedFiles: Promise; + } { if (query.type !== QueryType.Text) { return { - completeData: { + openFilesToScan: new ResourceSet(), + completeData: Promise.resolve({ messages: [], limitHit: false, results: [], - }, - scannedFiles: new ResourceSet() + }), + allScannedFiles: Promise.resolve(new ResourceSet()), }; } - const searchStart = Date.now(); const localNotebookWidgets = this.getLocalNotebookWidgets(); const localNotebookFiles = localNotebookWidgets.map(widget => widget.viewModel!.uri); - const localResultPromise = this.getLocalNotebookResults(query, token, localNotebookWidgets, searchInstanceID); - const searchLocalEnd = Date.now(); + const getAllResults = (): { completeData: Promise; allScannedFiles: Promise } => { + const searchStart = Date.now(); - const experimentalNotebooksEnabled = this.configurationService.getValue('search').experimental?.closedNotebookRichContentResults ?? false; + const localResultPromise = this.getLocalNotebookResults(query, token ?? CancellationToken.None, localNotebookWidgets, searchInstanceID); + const searchLocalEnd = Date.now(); - let closedResultsPromise: Promise = Promise.resolve(undefined); - if (experimentalNotebooksEnabled) { - closedResultsPromise = this.getClosedNotebookResults(query, new ResourceSet(localNotebookFiles, uri => this.uriIdentityService.extUri.getComparisonKey(uri)), token); - } + const experimentalNotebooksEnabled = this.configurationService.getValue('search').experimental?.closedNotebookRichContentResults ?? false; - const resolved = (await Promise.all([localResultPromise, closedResultsPromise])).filter((result): result is INotebookSearchMatchResults => !!result); - const resultArray = resolved.map(elem => elem.results); + let closedResultsPromise: Promise = Promise.resolve(undefined); + if (experimentalNotebooksEnabled) { + closedResultsPromise = this.getClosedNotebookResults(query, new ResourceSet(localNotebookFiles, uri => this.uriIdentityService.extUri.getComparisonKey(uri)), token ?? CancellationToken.None); + } - const results = arrays.coalesce(resultArray.flatMap(map => Array.from(map.values()))); - const scannedFiles = new ResourceSet(resultArray.flatMap(map => Array.from(map.keys())), uri => this.uriIdentityService.extUri.getComparisonKey(uri)); - if (onProgress) { - results.forEach(onProgress); - } - this.logService.trace(`local notebook search time | ${searchLocalEnd - searchStart}ms`); + const promise = Promise.all([localResultPromise, closedResultsPromise]); + return { + completeData: promise.then(resolvedPromise => { + const resolved = resolvedPromise.filter((e): e is INotebookSearchMatchResults => !!e); + const resultArray = resolved.map(elem => elem.results); + const results = arrays.coalesce(resultArray.flatMap(map => Array.from(map.values()))); + if (onProgress) { + results.forEach(onProgress); + } + this.logService.trace(`local notebook search time | ${searchLocalEnd - searchStart}ms`); + return { + messages: [], + limitHit: resolved.reduce((prev, cur) => prev || cur.limitHit, false), + results, + }; + }), + allScannedFiles: promise.then(resolvedPromise => { + const resolved = resolvedPromise.filter((e): e is INotebookSearchMatchResults => !!e); + const resultArray = resolved.map(elem => elem.results); + return new ResourceSet(resultArray.flatMap(map => Array.from(map.keys())), uri => this.uriIdentityService.extUri.getComparisonKey(uri)); + }) + }; + }; + const promiseResults = getAllResults(); return { - completeData: { - messages: [], - limitHit: resolved.reduce((prev, cur) => prev || cur.limitHit, false), - results, - }, - scannedFiles + openFilesToScan: new ResourceSet(localNotebookFiles), + completeData: promiseResults.completeData, + allScannedFiles: promiseResults.allScannedFiles }; } @@ -272,10 +291,10 @@ export class NotebookSearchService implements INotebookSearchService { regex: query.contentPattern.isRegExp, wholeWord: query.contentPattern.isWordMatch, caseSensitive: query.contentPattern.isCaseSensitive, - includeMarkupInput: query.contentPattern.notebookInfo?.isInNotebookMarkdownInput, - includeMarkupPreview: query.contentPattern.notebookInfo?.isInNotebookMarkdownPreview, - includeCodeInput: query.contentPattern.notebookInfo?.isInNotebookCellInput, - includeOutput: query.contentPattern.notebookInfo?.isInNotebookCellOutput, + includeMarkupInput: query.contentPattern.notebookInfo?.isInNotebookMarkdownInput ?? true, + includeMarkupPreview: query.contentPattern.notebookInfo?.isInNotebookMarkdownPreview ?? true, + includeCodeInput: query.contentPattern.notebookInfo?.isInNotebookCellInput ?? true, + includeOutput: query.contentPattern.notebookInfo?.isInNotebookCellOutput ?? true, }, token, false, true, searchID); diff --git a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts index ad3d5da68ff..6324613fbfd 100644 --- a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts @@ -7,22 +7,26 @@ import { IMatch } from 'vs/base/common/filters'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { basenameOrAuthority, dirname } from 'vs/base/common/resources'; import { ThemeIcon } from 'vs/base/common/themables'; +import { IRange, Range } from 'vs/editor/common/core/range'; import { localize } from 'vs/nls'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ITextEditorSelection } from 'vs/platform/editor/common/editor'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILabelService } from 'vs/platform/label/common/label'; import { WorkbenchCompressibleObjectTree, getSelectionKeyboardEvent } from 'vs/platform/list/browser/listService'; -import { IPickerQuickAccessItem, PickerQuickAccessProvider } from 'vs/platform/quickinput/browser/pickerQuickAccess'; -import { IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { FastAndSlowPicks, IPickerQuickAccessItem, PickerQuickAccessProvider, Picks } from 'vs/platform/quickinput/browser/pickerQuickAccess'; +import { DefaultQuickAccessFilterValue } from 'vs/platform/quickinput/common/quickAccess'; +import { IKeyMods, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor'; import { IViewsService } from 'vs/workbench/common/views'; import { searchDetailsIcon, searchOpenInFileIcon } from 'vs/workbench/contrib/search/browser/searchIcons'; -import { Match, MatchInNotebook, RenderableMatch, SearchModel, SearchResult } from 'vs/workbench/contrib/search/browser/searchModel'; +import { FileMatch, Match, MatchInNotebook, RenderableMatch, SearchModel, searchComparer } from 'vs/workbench/contrib/search/browser/searchModel'; import { SearchView, getEditorSelectionFromMatch } from 'vs/workbench/contrib/search/browser/searchView'; -import { getOutOfWorkspaceEditorResources } from 'vs/workbench/contrib/search/common/search'; -import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IWorkbenchSearchConfiguration, getOutOfWorkspaceEditorResources } from 'vs/workbench/contrib/search/common/search'; +import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { ITextQueryBuilderOptions, QueryBuilder } from 'vs/workbench/services/search/common/queryBuilder'; -import { IPatternInfo, ISearchConfigurationProperties, ITextQuery, VIEW_ID } from 'vs/workbench/services/search/common/search'; +import { IPatternInfo, ITextQuery, VIEW_ID } from 'vs/workbench/services/search/common/search'; export const TEXT_SEARCH_QUICK_ACCESS_PREFIX = '% '; @@ -46,8 +50,8 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider('search'); + private get configuration() { + const editorConfig = this._configurationService.getValue().workbench?.editor; + const searchConfig = this._configurationService.getValue().search; + + return { + openEditorPinned: !editorConfig?.enablePreviewFromQuickOpen || !editorConfig?.enablePreview, + preserveInput: searchConfig.experimental.quickAccess.preserveInput, + maxResults: searchConfig.maxResults, + smartCase: searchConfig.smartCase, + }; } - private async doSearch(contentPattern: string): Promise { + get defaultFilterValue(): DefaultQuickAccessFilterValue | undefined { + if (this.configuration.preserveInput) { + return DefaultQuickAccessFilterValue.LAST; + } + return undefined; + } + + private doSearch(contentPattern: string, token: CancellationToken): { + syncResults: FileMatch[]; + asyncResults: Promise; + } | undefined { if (contentPattern === '') { return undefined; } @@ -89,8 +111,16 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider folder.uri), this._getTextQueryBuilderOptions(charsPerLine)); - await this.searchModel.search(query, undefined); - return this.searchModel.searchResult; + const result = this.searchModel.search(query, undefined, token); + + const getAsyncResults = async () => { + await result.asyncResults; + return this.searchModel.searchResult.matches().filter(e => result.syncResults.indexOf(e) === -1); + }; + return { + syncResults: this.searchModel.searchResult.matches(), + asyncResults: getAsyncResults() + }; } private moveToSearchViewlet(model: SearchModel, currentElem: RenderableMatch) { @@ -107,31 +137,24 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider { - - const searchResult = await this.doSearch(contentPattern); - - if (!searchResult) { - return []; - } + private _getPicksFromMatches(matches: FileMatch[], limit: number): (IQuickPickSeparator | IPickerQuickAccessItem)[] { + matches = matches.sort(searchComparer); + const files = matches.length > limit ? matches.slice(0, limit) : matches; const picks: Array = []; - const matches = searchResult.matches(); - const files = matches.length > MAX_FILES_SHOWN ? matches.slice(0, MAX_FILES_SHOWN) : matches; - for (let fileIndex = 0; fileIndex < matches.length; fileIndex++) { - if (fileIndex === MAX_FILES_SHOWN) { + if (fileIndex === limit) { picks.push({ type: 'separator', }); picks.push({ - label: 'See More Files', + label: localize('QuickSearchSeeMoreFiles', "See More Files"), iconClass: ThemeIcon.asClassName(searchDetailsIcon), accept: async () => { - this.moveToSearchViewlet(this.searchModel, matches[MAX_FILES_SHOWN]); + this.moveToSearchViewlet(this.searchModel, matches[limit]); } }); break; @@ -159,7 +182,7 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider { this.moveToSearchViewlet(this.searchModel, element); @@ -167,36 +190,74 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider { - await this._editorService.openEditor({ - resource: fileMatch.resource, - options - }, ACTIVE_GROUP); - }, + accept: async (keyMods, event) => { + await this.handleAccept(fileMatch, { + keyMods, + selection: getEditorSelectionFromMatch(element, this.searchModel), + preserveFocus: event.inBackground, + forcePinned: event.inBackground, + indexedCellOptions: element instanceof MatchInNotebook ? { index: element.cellIndex, selection: element.range() } : undefined + }); + } }); } + } + return picks; + } + private async handleAccept(fileMatch: FileMatch, options: { keyMods?: IKeyMods; selection?: ITextEditorSelection; preserveFocus?: boolean; range?: IRange; forcePinned?: boolean; forceOpenSideBySide?: boolean; indexedCellOptions?: { index: number; selection?: Range } }): Promise { + const editorOptions = { + preserveFocus: options.preserveFocus, + pinned: options.keyMods?.ctrlCmd || options.forcePinned || this.configuration.openEditorPinned, + selection: options.selection + }; + + // from https://github.com/microsoft/vscode/blob/f40dabca07a1622b2a0ae3ee741cfc94ab964bef/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts#L1037 + const targetGroup = options.keyMods?.alt || (this.configuration.openEditorPinned && options.keyMods?.ctrlCmd) || options.forceOpenSideBySide ? SIDE_GROUP : ACTIVE_GROUP; + + await this._editorService.openEditor({ + resource: fileMatch.resource, + options: editorOptions + }, targetGroup); + } + + protected _getPicks(contentPattern: string, disposables: DisposableStore, token: CancellationToken): Picks | Promise | FastAndSlowPicks> | FastAndSlowPicks | null { + + if (contentPattern === '') { + this.searchModel.searchResult.clear(); + return []; + } + const allMatches = this.doSearch(contentPattern, token); + + if (!allMatches) { + return null; + } + const matches = allMatches.syncResults; + const syncResult = this._getPicksFromMatches(matches, MAX_FILES_SHOWN); + + if (matches.length >= MAX_FILES_SHOWN) { + return syncResult; } - return picks; + return { + picks: syncResult, + additionalPicks: allMatches.asyncResults.then((asyncResults) => { + return this._getPicksFromMatches(asyncResults, MAX_FILES_SHOWN - matches.length); + }) + }; } } diff --git a/src/vs/workbench/contrib/search/browser/replaceService.ts b/src/vs/workbench/contrib/search/browser/replaceService.ts index d45d1f289ed..8dd187bff0a 100644 --- a/src/vs/workbench/contrib/search/browser/replaceService.ts +++ b/src/vs/workbench/contrib/search/browser/replaceService.ts @@ -11,7 +11,7 @@ import { IReplaceService } from 'vs/workbench/contrib/search/browser/replace'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IModelService } from 'vs/editor/common/services/model'; import { ILanguageService } from 'vs/editor/common/languages/language'; -import { Match, FileMatch, FileMatchOrMatch, ISearchWorkbenchService, MatchInNotebook } from 'vs/workbench/contrib/search/browser/searchModel'; +import { Match, FileMatch, FileMatchOrMatch, ISearchViewModelWorkbenchService, MatchInNotebook } from 'vs/workbench/contrib/search/browser/searchModel'; import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress'; import { ITextModelService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -63,7 +63,7 @@ class ReplacePreviewModel extends Disposable { @ILanguageService private readonly languageService: ILanguageService, @ITextModelService private readonly textModelResolverService: ITextModelService, @IReplaceService private readonly replaceService: IReplaceService, - @ISearchWorkbenchService private readonly searchWorkbenchService: ISearchWorkbenchService + @ISearchViewModelWorkbenchService private readonly searchWorkbenchService: ISearchViewModelWorkbenchService ) { super(); } diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 0aa08eff74d..a2f41a98fac 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -27,7 +27,7 @@ import { SearchView } from 'vs/workbench/contrib/search/browser/searchView'; import { registerContributions as searchWidgetContributions } from 'vs/workbench/contrib/search/browser/searchWidget'; import { SymbolsQuickAccessProvider } from 'vs/workbench/contrib/search/browser/symbolsQuickAccess'; import { ISearchHistoryService, SearchHistoryService } from 'vs/workbench/contrib/search/common/searchHistoryService'; -import { ISearchWorkbenchService, SearchWorkbenchService } from 'vs/workbench/contrib/search/browser/searchModel'; +import { ISearchViewModelWorkbenchService, SearchViewModelWorkbenchService } from 'vs/workbench/contrib/search/browser/searchModel'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { SearchSortOrder, SEARCH_EXCLUDE_CONFIG, VIEWLET_ID, ViewMode, VIEW_ID } from 'vs/workbench/services/search/common/search'; import { Extensions, IConfigurationMigrationRegistry } from 'vs/workbench/common/configuration'; @@ -45,7 +45,7 @@ import 'vs/workbench/contrib/search/browser/searchActionsTopBar'; import 'vs/workbench/contrib/search/browser/searchActionsTextQuickAccess'; import { TEXT_SEARCH_QUICK_ACCESS_PREFIX, TextSearchQuickAccess } from 'vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess'; -registerSingleton(ISearchWorkbenchService, SearchWorkbenchService, InstantiationType.Delayed); +registerSingleton(ISearchViewModelWorkbenchService, SearchViewModelWorkbenchService, InstantiationType.Delayed); registerSingleton(ISearchHistoryService, SearchHistoryService, InstantiationType.Delayed); replaceContributions(); @@ -128,8 +128,14 @@ quickAccessRegistry.registerQuickAccessProvider({ ctor: TextSearchQuickAccess, prefix: TEXT_SEARCH_QUICK_ACCESS_PREFIX, contextKey: 'inTextSearchPicker', - placeholder: nls.localize('textSearchPickerPlaceholder', "Search for text in your workspace files."), - helpEntries: [{ description: nls.localize('textSearchPickerHelp', "Show All Text Results (experimental)"), commandId: Constants.QuickTextSearchActionId }] + placeholder: nls.localize('textSearchPickerPlaceholder', "Search for text in your workspace files (experimental)."), + helpEntries: [ + { + description: nls.localize('textSearchPickerHelp', "Search for Text (Experimental)"), + commandId: Constants.QuickTextSearchActionId, + commandCenterOrder: 65, + } + ] }); // Configuration @@ -370,7 +376,12 @@ configurationRegistry.registerConfiguration({ type: 'boolean', description: nls.localize('search.experimental.closedNotebookResults', "Show notebook editor rich content results for closed notebooks. Please refresh your search results after changing this setting."), default: false - } + }, + 'search.experimental.quickAccess.preserveInput': { + 'type': 'boolean', + 'description': nls.localize('search.experimental.quickAccess.preserveInput', "Controls whether the last typed input to Quick Search should be restored when opening it the next time."), + 'default': false + }, } }); diff --git a/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts b/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts index ebf0558987d..3971c1f112c 100644 --- a/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts @@ -18,8 +18,8 @@ registerAction2(class TextSearchQuickAccessAction extends Action2 { super({ id: Constants.QuickTextSearchActionId, title: { - value: nls.localize('quickTextSearch', "Quick Text Search"), - original: 'Quick Text Search' + value: nls.localize('quickTextSearch', "Quick Text Search (Experimental)"), + original: 'Quick Text Search (Experimental)' }, category, menu: [{ diff --git a/src/vs/workbench/contrib/search/browser/searchModel.ts b/src/vs/workbench/contrib/search/browser/searchModel.ts index 82bf57c7636..0d8c8ec06c0 100644 --- a/src/vs/workbench/contrib/search/browser/searchModel.ts +++ b/src/vs/workbench/contrib/search/browser/searchModel.ts @@ -36,9 +36,9 @@ import { CellFindMatchWithIndex, CellWebviewFindMatch, ICellViewModel } from 'vs import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidget'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService'; import { NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; -import { INotebookSearchService } from 'vs/workbench/contrib/search/browser/notebookSearch'; import { IReplaceService } from 'vs/workbench/contrib/search/browser/replace'; import { CellSearchModel, ICellMatch, contentMatchesToTextSearchMatches, isIFileMatchWithCells, rawCellPrefix, webviewMatchesToTextSearchMatches } from 'vs/workbench/contrib/search/browser/searchNotebookHelpers'; +import { INotebookSearchService } from 'vs/workbench/contrib/search/common/notebookSearch'; import { ReplacePattern } from 'vs/workbench/services/search/common/replace'; import { IFileMatch, IPatternInfo, ISearchComplete, ISearchConfigurationProperties, ISearchProgressItem, ISearchRange, ISearchService, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchPreviewOptions, ITextSearchResult, ITextSearchStats, OneLineRange, resultIsMatch, SearchCompletionExitCode, SearchSortOrder } from 'vs/workbench/services/search/common/search'; import { addContextToEditorMatches, editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers'; @@ -1142,13 +1142,16 @@ export class FolderMatch extends Disposable { raw.forEach(rawFileMatch => { const existingFileMatch = this.getDownstreamFileMatch(rawFileMatch.resource); if (existingFileMatch) { - rawFileMatch - .results! - .filter(resultIsMatch) - .forEach(m => { - textSearchResultToMatches(m, existingFileMatch) - .forEach(m => existingFileMatch.add(m)); - }); + + if (rawFileMatch.results) { + rawFileMatch + .results + .filter(resultIsMatch) + .forEach(m => { + textSearchResultToMatches(m, existingFileMatch) + .forEach(m => existingFileMatch.add(m)); + }); + } // add cell matches if (isIFileMatchWithCells(rawFileMatch)) { @@ -2002,34 +2005,63 @@ export class SearchModel extends Disposable { this._searchResultChangedListener = this._register(this._searchResult.onChange((e) => this._onSearchResultChanged.fire(e))); } - private async doSearch(query: ITextQuery, progressEmitter: Emitter, searchQuery: ITextQuery, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): Promise { - const searchStart = Date.now(); - const tokenSource = this.currentCancelTokenSource = new CancellationTokenSource(); - const onProgressCall = (p: ISearchProgressItem) => { - progressEmitter.fire(); - this.onSearchProgress(p, searchInstanceID); + private doSearch(query: ITextQuery, progressEmitter: Emitter, searchQuery: ITextQuery, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void, callerToken?: CancellationToken): { + asyncResults: Promise; + syncResults: IFileMatch[]; + } { + const asyncGenerateOnProgress = async (p: ISearchProgressItem) => { + progressEmitter.fire(); + this.onSearchProgress(p, searchInstanceID, false); onProgress?.(p); }; - const notebookResult = await this.notebookSearchService.notebookSearch(query, this.currentCancelTokenSource.token, searchInstanceID, onProgressCall); - const currentResult = await this.searchService.textSearch( + + const syncGenerateOnProgress = (p: ISearchProgressItem) => { + progressEmitter.fire(); + this.onSearchProgress(p, searchInstanceID, true); + onProgress?.(p); + }; + const tokenSource = this.currentCancelTokenSource = new CancellationTokenSource(callerToken); + + const notebookResult = this.notebookSearchService.notebookSearch(query, tokenSource.token, searchInstanceID, asyncGenerateOnProgress); + const textResult = this.searchService.textSearchSplitSyncAsync( searchQuery, - this.currentCancelTokenSource.token, onProgressCall, - notebookResult?.scannedFiles + this.currentCancelTokenSource.token, asyncGenerateOnProgress, + notebookResult.openFilesToScan, + notebookResult.allScannedFiles, ); - tokenSource.dispose(); - const searchLength = Date.now() - searchStart; - this.logService.trace(`whole search time | ${searchLength}ms`); + + const syncResults = textResult.syncResults.results; + syncResults.forEach(p => { if (p) { syncGenerateOnProgress(p); } }); + + const getAsyncResults = async (): Promise => { + const searchStart = Date.now(); + + // resolve async parts of search + const allClosedEditorResults = await textResult.asyncResults; + const resolvedNotebookResults = await notebookResult.completeData; + tokenSource.dispose(); + const searchLength = Date.now() - searchStart; + const resolvedResult = { + results: [...allClosedEditorResults.results, ...resolvedNotebookResults.results], + messages: [...allClosedEditorResults.messages, ...resolvedNotebookResults.messages], + limitHit: allClosedEditorResults.limitHit || resolvedNotebookResults.limitHit, + exit: allClosedEditorResults.exit, + stats: allClosedEditorResults.stats, + }; + this.logService.trace(`whole search time | ${searchLength}ms`); + return resolvedResult; + }; return { - results: currentResult.results.concat(notebookResult.completeData.results), - messages: currentResult.messages.concat(notebookResult.completeData.messages), - limitHit: currentResult.limitHit || notebookResult.completeData.limitHit, - exit: currentResult.exit, - stats: currentResult.stats, + asyncResults: getAsyncResults(), + syncResults }; } - async search(query: ITextQuery, onProgress?: (result: ISearchProgressItem) => void): Promise { + search(query: ITextQuery, onProgress?: (result: ISearchProgressItem) => void, callerToken?: CancellationToken): { + asyncResults: Promise; + syncResults: IFileMatch[]; + } { this.cancelSearch(true); this._searchQuery = query; @@ -2046,11 +2078,21 @@ export class SearchModel extends Disposable { // In search on type case, delay the streaming of results just a bit, so that we don't flash the only "local results" fast path this._startStreamDelay = new Promise(resolve => setTimeout(resolve, this.searchConfig.searchOnType ? 150 : 0)); - const currentRequest = this.doSearch(query, progressEmitter, this._searchQuery, searchInstanceID, onProgress); + const req = this.doSearch(query, progressEmitter, this._searchQuery, searchInstanceID, onProgress, callerToken); + const asyncResults = req.asyncResults; + const syncResults = req.syncResults; + + if (onProgress) { + syncResults.forEach(p => { + if (p) { + onProgress(p); + } + }); + } const start = Date.now(); - Promise.race([currentRequest, Event.toPromise(progressEmitter.event)]).finally(() => { + Promise.race([asyncResults, Event.toPromise(progressEmitter.event)]).finally(() => { /* __GDPR__ "searchResultsFirstRender" : { "owner": "roblourens", @@ -2060,12 +2102,14 @@ export class SearchModel extends Disposable { this.telemetryService.publicLog('searchResultsFirstRender', { duration: Date.now() - start }); }); - currentRequest.then( + asyncResults.then( value => this.onSearchCompleted(value, Date.now() - start, searchInstanceID), e => this.onSearchError(e, Date.now() - start)); - try { - return await currentRequest; + return { + asyncResults: asyncResults, + syncResults: syncResults + }; } finally { /* __GDPR__ "searchResultsFinished" : { @@ -2131,14 +2175,23 @@ export class SearchModel extends Disposable { } } - private async onSearchProgress(p: ISearchProgressItem, searchInstanceID: string) { + private onSearchProgress(p: ISearchProgressItem, searchInstanceID: string, sync = true) { if ((p).resource) { this._resultQueue.push(p); - await this._startStreamDelay; - if (this._resultQueue.length) { - this._searchResult.add(this._resultQueue, searchInstanceID, true); - this._resultQueue.length = 0; + if (sync) { + if (this._resultQueue.length) { + this._searchResult.add(this._resultQueue, searchInstanceID, true); + this._resultQueue.length = 0; + } + } else { + this._startStreamDelay.then(() => { + if (this._resultQueue.length) { + this._searchResult.add(this._resultQueue, searchInstanceID, true); + this._resultQueue.length = 0; + } + }); } + } } @@ -2171,7 +2224,7 @@ export type FileMatchOrMatch = FileMatch | Match; export type RenderableMatch = FolderMatch | FolderMatchWithResource | FileMatch | Match; -export class SearchWorkbenchService implements ISearchWorkbenchService { +export class SearchViewModelWorkbenchService implements ISearchViewModelWorkbenchService { declare readonly _serviceBrand: undefined; private _searchModel: SearchModel | null = null; @@ -2187,9 +2240,9 @@ export class SearchWorkbenchService implements ISearchWorkbenchService { } } -export const ISearchWorkbenchService = createDecorator('searchWorkbenchService'); +export const ISearchViewModelWorkbenchService = createDecorator('searchViewModelWorkbenchService'); -export interface ISearchWorkbenchService { +export interface ISearchViewModelWorkbenchService { readonly _serviceBrand: undefined; readonly searchModel: SearchModel; diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index cf7506c874c..b87d1347816 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -70,7 +70,7 @@ import * as Constants from 'vs/workbench/contrib/search/common/constants'; import { IReplaceService } from 'vs/workbench/contrib/search/browser/replace'; import { getOutOfWorkspaceEditorResources, SearchStateKey, SearchUIState } from 'vs/workbench/contrib/search/common/search'; import { ISearchHistoryService, ISearchHistoryValues, SearchHistoryService } from 'vs/workbench/contrib/search/common/searchHistoryService'; -import { FileMatch, FileMatchOrMatch, FolderMatch, FolderMatchWithResource, IChangeEvent, ISearchWorkbenchService, Match, MatchInNotebook, RenderableMatch, searchMatchComparer, SearchModel, SearchResult } from 'vs/workbench/contrib/search/browser/searchModel'; +import { FileMatch, FileMatchOrMatch, FolderMatch, FolderMatchWithResource, IChangeEvent, ISearchViewModelWorkbenchService, Match, MatchInNotebook, RenderableMatch, searchMatchComparer, SearchModel, SearchResult } from 'vs/workbench/contrib/search/browser/searchModel'; import { createEditorFromSearchResult } from 'vs/workbench/contrib/searchEditor/browser/searchEditorActions'; import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IPreferencesService, ISettingsEditorOptions } from 'vs/workbench/services/preferences/common/preferences'; @@ -174,7 +174,7 @@ export class SearchView extends ViewPane { @IViewDescriptorService viewDescriptorService: IViewDescriptorService, @IConfigurationService configurationService: IConfigurationService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @ISearchWorkbenchService private readonly searchWorkbenchService: ISearchWorkbenchService, + @ISearchViewModelWorkbenchService private readonly searchViewModelWorkbenchService: ISearchViewModelWorkbenchService, @IContextKeyService contextKeyService: IContextKeyService, @IReplaceService private readonly replaceService: IReplaceService, @ITextFileService private readonly textFileService: ITextFileService, @@ -235,7 +235,7 @@ export class SearchView extends ViewPane { } }); - this.viewModel = this._register(this.searchWorkbenchService.searchModel); + this.viewModel = this._register(this.searchViewModelWorkbenchService.searchModel); this.queryBuilder = this.instantiationService.createInstance(QueryBuilder); this.memento = new Memento(this.id, storageService); this.viewletState = this.memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); @@ -860,7 +860,7 @@ export class SearchView extends ViewPane { overrideStyles: { listBackground: this.getBackgroundColor() }, - additionalScrollHeight: SearchDelegate.ITEM_HEIGHT + paddingBottom: SearchDelegate.ITEM_HEIGHT })); this._register(this.tree.onContextMenu(e => this.onContextMenu(e))); const updateHasSomeCollapsible = () => this.toggleCollapseStateDelayer.trigger(() => this.hasSomeCollapsibleResultKey.set(this.hasSomeCollapsible())); @@ -903,8 +903,8 @@ export class SearchView extends ViewPane { } let editable = false; - if (focus instanceof MatchInNotebook) { - editable = !focus.isWebviewMatch(); + if (focus instanceof Match) { + editable = (focus instanceof MatchInNotebook) ? !focus.isWebviewMatch() : true; } else if (focus instanceof FileMatch) { editable = !focus.hasOnlyReadOnlyMatches(); } else if (focus instanceof FolderMatch) { @@ -1454,9 +1454,11 @@ export class SearchView extends ViewPane { if (options.triggeredOnType && !this.searchConfig.searchOnType) { return; } if (!this.pauseSearching) { + + const delay = options.triggeredOnType ? options.delay : 0; this.triggerQueryDelayer.trigger(() => { this._onQueryChanged(options.preserveFocus, options.triggeredOnType); - }, options.delay); + }, delay); } } @@ -1741,8 +1743,8 @@ export class SearchView extends ViewPane { this.tree.setSelection([]); this.tree.setFocus([]); - return this.viewModel.search(query) - .then(onComplete, onError); + const result = this.viewModel.search(query); + return result.asyncResults.then(onComplete, onError); } private onOpenSettings(e: dom.EventLike): void { @@ -1892,7 +1894,7 @@ export class SearchView extends ViewPane { pinned, selection, revealIfVisible: true, - indexedCellOptions: element instanceof MatchInNotebook ? { cellIndex: element.cellIndex, selection: element.range } : undefined, + indexedCellOptions: element instanceof MatchInNotebook ? { index: element.cellIndex, selection: element.range() } : undefined, }; try { diff --git a/src/vs/workbench/contrib/search/common/constants.ts b/src/vs/workbench/contrib/search/common/constants.ts index d6e4fd9d7a9..1f98bc77b35 100644 --- a/src/vs/workbench/contrib/search/common/constants.ts +++ b/src/vs/workbench/contrib/search/common/constants.ts @@ -30,7 +30,7 @@ export const AddCursorsAtSearchResults = 'addCursorsAtSearchResults'; export const RevealInSideBarForSearchResults = 'search.action.revealInSideBar'; export const ReplaceInFilesActionId = 'workbench.action.replaceInFiles'; export const ShowAllSymbolsActionId = 'workbench.action.showAllSymbols'; -export const QuickTextSearchActionId = 'workbench.action.quickTextSearch'; +export const QuickTextSearchActionId = 'workbench.action.experimental.quickTextSearch'; export const CancelSearchActionId = 'search.action.cancel'; export const RefreshSearchResultsActionId = 'search.action.refreshSearchResults'; export const FocusNextSearchResultActionId = 'search.action.focusNextSearchResult'; diff --git a/src/vs/workbench/contrib/search/browser/notebookSearch.ts b/src/vs/workbench/contrib/search/common/notebookSearch.ts similarity index 75% rename from src/vs/workbench/contrib/search/browser/notebookSearch.ts rename to src/vs/workbench/contrib/search/common/notebookSearch.ts index 2fb52658219..5237c1bd03c 100644 --- a/src/vs/workbench/contrib/search/browser/notebookSearch.ts +++ b/src/vs/workbench/contrib/search/common/notebookSearch.ts @@ -14,5 +14,9 @@ export interface INotebookSearchService { readonly _serviceBrand: undefined; - notebookSearch(query: ITextQuery, token: CancellationToken, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }>; + notebookSearch(query: ITextQuery, token: CancellationToken | undefined, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): { + openFilesToScan: ResourceSet; + completeData: Promise; + allScannedFiles: Promise; + }; } diff --git a/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts b/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts index 0adcb1e47d4..ca0a09f0c31 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts @@ -14,7 +14,7 @@ import { ModelService } from 'vs/editor/common/services/modelService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService, ITextSearchMatch, OneLineRange, QueryType, TextSearchMatch } from 'vs/workbench/services/search/common/search'; +import { IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService, ITextQuery, ITextSearchMatch, OneLineRange, QueryType, TextSearchMatch } from 'vs/workbench/services/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { CellMatch, MatchInNotebook, SearchModel } from 'vs/workbench/contrib/search/browser/searchModel'; @@ -36,7 +36,7 @@ import { ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBr import { FindMatch, IReadonlyTextBuffer } from 'vs/editor/common/model'; import { ResourceMap, ResourceSet } from 'vs/base/common/map'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; -import { INotebookSearchService } from 'vs/workbench/contrib/search/browser/notebookSearch'; +import { INotebookSearchService } from 'vs/workbench/contrib/search/common/notebookSearch'; const nullEvent = new class { id: number = -1; @@ -112,6 +112,20 @@ suite('SearchModel', () => { }); }); + }, + textSearchSplitSyncAsync(query: ITextQuery, token?: CancellationToken | undefined, onProgress?: ((result: ISearchProgressItem) => void) | undefined): { syncResults: ISearchComplete; asyncResults: Promise } { + return { + syncResults: { + results: [], + messages: [] + }, + asyncResults: new Promise(resolve => { + queueMicrotask(() => { + results.forEach(onProgress!); + resolve(complete!); + }); + }) + }; } }; } @@ -129,6 +143,17 @@ suite('SearchModel', () => { reject(error); }); }); + }, + textSearchSplitSyncAsync(query: ITextQuery, token?: CancellationToken | undefined, onProgress?: ((result: ISearchProgressItem) => void) | undefined): { syncResults: ISearchComplete; asyncResults: Promise } { + return { + syncResults: { + results: [], + messages: [] + }, + asyncResults: new Promise((resolve, reject) => { + reject(error); + }) + }; } }; } @@ -151,16 +176,47 @@ suite('SearchModel', () => { resolve({}); }); }); + }, + textSearchSplitSyncAsync(query: ITextQuery, token?: CancellationToken | undefined, onProgress?: ((result: ISearchProgressItem) => void) | undefined): { syncResults: ISearchComplete; asyncResults: Promise } { + token?.onCancellationRequested(() => tokenSource.cancel()); + return { + syncResults: { + results: [], + messages: [] + }, + asyncResults: new Promise(resolve => { + queueMicrotask(() => { + resolve({}); + }); + }) + }; + } + }; + } + + function searchServiceWithDeferredPromise(p: Promise): ISearchService { + return { + textSearchSplitSyncAsync(query: ITextQuery, token?: CancellationToken | undefined, onProgress?: ((result: ISearchProgressItem) => void) | undefined): { syncResults: ISearchComplete; asyncResults: Promise } { + return { + syncResults: { + results: [], + messages: [] + }, + asyncResults: p, + }; } }; } - function notebookSearchServiceWithInfo(results: IFileMatchWithCells[], tokenSource: CancellationTokenSource | undefined): INotebookSearchService { return { _serviceBrand: undefined, - notebookSearch(query: ISearchQuery, token: CancellationToken, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void, notebookURIs?: ResourceSet): Promise<{ completeData: ISearchComplete; scannedFiles: ResourceSet }> { + notebookSearch(query: ITextQuery, token: CancellationToken | undefined, searchInstanceID: string, onProgress?: (result: ISearchProgressItem) => void): { + openFilesToScan: ResourceSet; + completeData: Promise; + allScannedFiles: Promise; + } { token?.onCancellationRequested(() => tokenSource?.cancel()); const localResults = new ResourceMap(uri => uri.path); @@ -171,15 +227,15 @@ suite('SearchModel', () => { if (onProgress) { arrays.coalesce([...localResults.values()]).forEach(onProgress); } - return Promise.resolve( - { - completeData: { - messages: [], - results: arrays.coalesce([...localResults.values()]), - limitHit: false - }, - scannedFiles: new ResourceSet([...localResults.keys()]), - }); + return { + openFilesToScan: new ResourceSet([...localResults.keys()]), + completeData: Promise.resolve({ + messages: [], + results: arrays.coalesce([...localResults.values()]), + limitHit: false + }), + allScannedFiles: Promise.resolve(new ResourceSet()), + }; } }; } @@ -194,7 +250,7 @@ suite('SearchModel', () => { instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject: SearchModel = instantiationService.createInstance(SearchModel); - await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; const actual = testObject.searchResult.matches(); @@ -216,17 +272,14 @@ suite('SearchModel', () => { test('Search Model: Search can return notebook results', async () => { - const notebookUri = createFileUriFromPathFromRoot('/1'); - const results = [ aRawMatch('/2', new TextSearchMatch('test', new OneLineRange(1, 1, 5)), new TextSearchMatch('this is a test', new OneLineRange(1, 11, 15))), aRawMatch('/3', new TextSearchMatch('test', lineOneRange))]; - const searchService = instantiationService.stub(ISearchService, searchServiceWithResults(results, { limitHit: false, messages: [], results })); + instantiationService.stub(ISearchService, searchServiceWithResults(results, { limitHit: false, messages: [], results })); sinon.stub(CellMatch.prototype, 'addContext'); - const textSearch = sinon.spy(searchService, 'textSearch'); const mdInputCell = { cellKind: CellKind.Markup, textBuffer: { getLineContent(lineNumber: number): string { @@ -297,12 +350,10 @@ suite('SearchModel', () => { const notebookSearchService = instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([aRawMatchWithCells('/1', cellMatchMd, cellMatchCode)], undefined)); const notebookSearch = sinon.spy(notebookSearchService, "notebookSearch"); const model: SearchModel = instantiationService.createInstance(SearchModel); - await model.search({ contentPattern: { pattern: 'test' }, type: QueryType.Text, folderQueries }); + await model.search({ contentPattern: { pattern: 'test' }, type: QueryType.Text, folderQueries }).asyncResults; const actual = model.searchResult.matches(); assert(notebookSearch.calledOnce); - assert(textSearch.getCall(0).args[3]?.size === 1); - assert(textSearch.getCall(0).args[3]?.has(notebookUri)); // ensure that the textsearch knows not to re-source the notebooks assert.strictEqual(3, actual.length); assert.strictEqual(URI.file(`${getRootName()}/1`).toString(), actual[0].resource.toString()); @@ -351,7 +402,7 @@ suite('SearchModel', () => { instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject: SearchModel = instantiationService.createInstance(SearchModel); - await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; assert.ok(target.calledThrice); assert.ok(target.calledWith('searchResultsFirstRender')); @@ -368,7 +419,7 @@ suite('SearchModel', () => { instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject = instantiationService.createInstance(SearchModel); - const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; return result.then(() => { return timeout(1).then(() => { @@ -390,7 +441,7 @@ suite('SearchModel', () => { instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject = instantiationService.createInstance(SearchModel); - const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; return result.then(() => { return timeout(1).then(() => { @@ -410,15 +461,15 @@ suite('SearchModel', () => { instantiationService.stub(ITelemetryService, 'publicLog', target1); instantiationService.stub(ISearchService, searchServiceWithError(new Error('error'))); + instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject = instantiationService.createInstance(SearchModel); - const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; return result.then(() => { }, () => { return timeout(1).then(() => { assert.ok(target1.calledWith('searchResultsFirstRender')); assert.ok(target1.calledWith('searchResultsFinished')); - // assert.ok(target2.calledOnce); }); }); }); @@ -430,14 +481,16 @@ suite('SearchModel', () => { instantiationService.stub(ITelemetryService, 'publicLog', target1); const deferredPromise = new DeferredPromise(); - instantiationService.stub(ISearchService, 'textSearch', deferredPromise.p); + + instantiationService.stub(ISearchService, searchServiceWithDeferredPromise(deferredPromise.p)); + instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject = instantiationService.createInstance(SearchModel); - const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + const result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; deferredPromise.cancel(); - return result.then(() => { }, () => { + return result.then(() => { }, async () => { return timeout(1).then(() => { assert.ok(target1.calledWith('searchResultsFirstRender')); assert.ok(target1.calledWith('searchResultsFinished')); @@ -456,7 +509,7 @@ suite('SearchModel', () => { instantiationService.stub(ISearchService, searchServiceWithResults(results, { limitHit: false, messages: [], results: [] })); instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject: SearchModel = instantiationService.createInstance(SearchModel); - await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 'somestring' }, type: QueryType.Text, folderQueries }).asyncResults; assert.ok(!testObject.searchResult.isEmpty()); instantiationService.stub(ISearchService, searchServiceWithResults([])); @@ -487,24 +540,24 @@ suite('SearchModel', () => { instantiationService.stub(INotebookSearchService, notebookSearchServiceWithInfo([], undefined)); const testObject: SearchModel = instantiationService.createInstance(SearchModel); - await testObject.search({ contentPattern: { pattern: 're' }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 're' }, type: QueryType.Text, folderQueries }).asyncResults; testObject.replaceString = 'hello'; let match = testObject.searchResult.matches()[0].matches()[0]; assert.strictEqual('hello', match.replaceString); - await testObject.search({ contentPattern: { pattern: 're', isRegExp: true }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 're', isRegExp: true }, type: QueryType.Text, folderQueries }).asyncResults; match = testObject.searchResult.matches()[0].matches()[0]; assert.strictEqual('hello', match.replaceString); - await testObject.search({ contentPattern: { pattern: 're(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 're(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }).asyncResults; match = testObject.searchResult.matches()[0].matches()[0]; assert.strictEqual('hello', match.replaceString); - await testObject.search({ contentPattern: { pattern: 'r(e)(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 'r(e)(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }).asyncResults; match = testObject.searchResult.matches()[0].matches()[0]; assert.strictEqual('hello', match.replaceString); - await testObject.search({ contentPattern: { pattern: 'r(e)(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }); + await testObject.search({ contentPattern: { pattern: 'r(e)(?:vi)', isRegExp: true }, type: QueryType.Text, folderQueries }).asyncResults; testObject.replaceString = 'hello$1'; match = testObject.searchResult.matches()[0].matches()[0]; assert.strictEqual('helloe', match.replaceString); diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts index 783e8bea1dc..e9bc0f046cd 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts @@ -567,8 +567,8 @@ export class SearchEditor extends AbstractTextCodeEditor const { configurationModel } = await startInput.resolveModels(); configurationModel.updateConfig(config); - - startInput.ongoingSearchOperation = this.searchModel.search(query).finally(() => { + const result = this.searchModel.search(query); + startInput.ongoingSearchOperation = result.asyncResults.finally(() => { this.ongoingOperations--; if (this.ongoingOperations === 0) { this.searchOperation.stop(); diff --git a/src/vs/workbench/contrib/terminal/browser/baseTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/baseTerminalBackend.ts index fcb01ae3e84..7710088cf64 100644 --- a/src/vs/workbench/contrib/terminal/browser/baseTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/baseTerminalBackend.ts @@ -8,9 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; import { localize } from 'vs/nls'; import { ICrossVersionSerializedTerminalState, IPtyHostController, ISerializedTerminalState, ITerminalLogService } from 'vs/platform/terminal/common/terminal'; -import { themeColorFromId } from 'vs/platform/theme/common/themeService'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { STATUS_BAR_WARNING_ITEM_BACKGROUND, STATUS_BAR_WARNING_ITEM_FOREGROUND } from 'vs/workbench/common/theme'; import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; @@ -68,8 +66,7 @@ export abstract class BaseTerminalBackend extends Disposable { tooltip: localize('nonResponsivePtyHost', "The connection to the terminal's pty host process is unresponsive, terminals may stop working. Click to manually restart the pty host."), ariaLabel: localize('ptyHostStatus.ariaLabel', 'Pty Host is unresponsive'), command: TerminalCommandId.RestartPtyHost, - backgroundColor: themeColorFromId(STATUS_BAR_WARNING_ITEM_BACKGROUND), - color: themeColorFromId(STATUS_BAR_WARNING_ITEM_FOREGROUND), + kind: 'warning' }; } statusBarAccessor = statusBarService.addEntry(unresponsiveStatusBarEntry, 'ptyHostStatus', StatusbarAlignment.LEFT); diff --git a/src/vs/workbench/contrib/terminal/browser/media/terminal.css b/src/vs/workbench/contrib/terminal/browser/media/terminal.css index 1b240eafdab..ca3f5ed9a05 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/terminal.css +++ b/src/vs/workbench/contrib/terminal/browser/media/terminal.css @@ -20,7 +20,7 @@ visibility: hidden; } .monaco-workbench .part.panel .pane-body.integrated-terminal .terminal-outer-container { - background-color: var(--vscode-terminal-background, --vscode-panel-background); + background-color: var(--vscode-terminal-background, var(--vscode-panel-background)); } .monaco-workbench .pane-body.integrated-terminal .terminal-outer-container, .monaco-workbench .pane-body.integrated-terminal .terminal-groups-container, @@ -32,7 +32,7 @@ } .monaco-workbench .part.sidebar .pane-body.integrated-terminal .terminal-outer-container, .monaco-workbench .part.auxiliarybar .pane-body.integrated-terminal .terminal-outer-container { - background-color: var(--vscode-terminal-background, --vscode-sideBar-background); + background-color: var(--vscode-terminal-background, var(--vscode-sideBar-background)); } .monaco-workbench .pane-body.integrated-terminal .split-view-view:not(:first-child), @@ -41,7 +41,7 @@ } .monaco-workbench .pane-body.integrated-terminal .terminal-drop-overlay { - background-color: var(--vscode-terminal-dropBackground, --vscode-editorGroup-dropBackground); + background-color: var(--vscode-terminal-dropBackground, var(--vscode-editorGroup-dropBackground)); } .monaco-workbench .pane-body.integrated-terminal .terminal-tabs-entry.is-active::before { @@ -78,7 +78,7 @@ } .monaco-workbench .terminal-editor .terminal-wrapper { - background-color: var(--vscode-terminal-background, --vscode-editorPane-background); + background-color: var(--vscode-terminal-background, var(--vscode-editorPane-background)); } .monaco-workbench .terminal-editor .terminal-wrapper, .monaco-workbench .pane-body.integrated-terminal .terminal-wrapper { @@ -484,7 +484,12 @@ } .monaco-workbench .terminal .terminal-command-decoration.quick-fix { color: var(--vscode-editorLightBulb-foreground) !important; - background-color: var(--vscode-terminal-background, --vscode-panel-background); + background-color: var(--vscode-terminal-background, var(--vscode-panel-background)); +} +.monaco-workbench .terminal .terminal-command-decoration.quick-fix.explainOnly { + /* Use success background to blend in with the terminal better as it's lower priority. We will + * probably want to add an explicit color for this eventually. */ + color: var(--vscode-terminalCommandDecoration-successBackground) !important; } .terminal-scroll-highlight { @@ -583,7 +588,7 @@ pointer-events: all; opacity: 1; z-index: 33; - background-color: var(--vscode-terminal-background, --vscode-panel-background); + background-color: var(--vscode-terminal-background, var(--vscode-panel-background)); } .monaco-workbench .xterm.terminal.hide { diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/decorationStyles.ts b/src/vs/workbench/contrib/terminal/browser/xterm/decorationStyles.ts index 46ee2d10d7a..4d475759e0b 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/decorationStyles.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/decorationStyles.ts @@ -29,8 +29,7 @@ export const enum DecorationSelector { Codicon = 'codicon', XtermDecoration = 'xterm-decoration', OverviewRuler = '.xterm-decoration-overview-ruler', - QuickFix = 'quick-fix', - LightBulb = 'codicon-light-bulb' + QuickFix = 'quick-fix' } export class TerminalDecorationHoverManager extends Disposable { diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index b5847637730..fcf7a078831 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -961,7 +961,7 @@ export function getXtermScaledDimensions(font: ITerminalFont, width: number, hei function vscodeToXtermLogLevel(logLevel: LogLevel): XtermLogLevel { switch (logLevel) { - case LogLevel.Trace: + case LogLevel.Trace: return 'trace'; case LogLevel.Debug: return 'debug'; case LogLevel.Info: return 'info'; case LogLevel.Warning: return 'warn'; diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 77e37c5b574..46692bccd1b 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -495,6 +495,7 @@ export const enum TerminalCommandId { HideSuggestWidget = 'workbench.action.terminal.hideSuggestWidget', FocusHover = 'workbench.action.terminal.focusHover', ShowEnvironmentContributions = 'workbench.action.terminal.showEnvironmentContributions', + FocusAndHideAccessibleBuffer = 'workbench.action.terminal.focusAndHideAccessibleBuffer', // Developer commands @@ -569,6 +570,7 @@ export const DEFAULT_COMMANDS_TO_SKIP_SHELL: string[] = [ TerminalCommandId.HideSuggestWidget, TerminalCommandId.FocusHover, AccessibilityCommandId.OpenAccessibilityHelp, + TerminalCommandId.FocusAndHideAccessibleBuffer, 'editor.action.toggleTabFocusMode', 'notifications.hideList', 'notifications.hideToasts', diff --git a/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts b/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts index 1d480dbd649..ce4f7a4168c 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts @@ -16,6 +16,7 @@ export const enum TerminalContextKeyStrings { Focus = 'terminalFocus', FocusInAny = 'terminalFocusInAny', AccessibleBufferFocus = 'terminalAccessibleBufferFocus', + AccessibleBufferOnLastLine = 'terminalAccessibleBufferOnLastLine', EditorFocus = 'terminalEditorFocus', TabsFocus = 'terminalTabsFocus', WebExtensionContributedProfile = 'terminalWebExtensionContributedProfile', @@ -51,6 +52,9 @@ export namespace TerminalContextKeys { /** Whether the accessible buffer is focused. */ export const accessibleBufferFocus = new RawContextKey(TerminalContextKeyStrings.AccessibleBufferFocus, false, localize('terminalAccessibleBufferFocusContextKey', "Whether the terminal accessible buffer is focused.")); + /** Whether the accessible buffer focus is on the last line. */ + export const accessibleBufferOnLastLine = new RawContextKey(TerminalContextKeyStrings.AccessibleBufferOnLastLine, false, localize('terminalAccessibleBufferOnLastLineContextKey', "Whether the accessible buffer focus is on the last line.")); + /** Whether a terminal in the editor area is focused. */ export const editorFocus = new RawContextKey(TerminalContextKeyStrings.EditorFocus, false, localize('terminalEditorFocusContextKey', "Whether a terminal in the editor area is focused.")); diff --git a/src/vs/workbench/contrib/terminal/common/terminalStrings.ts b/src/vs/workbench/contrib/terminal/common/terminalStrings.ts index 75e281c9f2d..43b4589df6c 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalStrings.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalStrings.ts @@ -22,6 +22,10 @@ export const terminalStrings = { value: localize('workbench.action.terminal.focus', "Focus Terminal"), original: 'Focus Terminal' }, + focusAndHideAccessibleBuffer: { + value: localize('workbench.action.terminal.focusAndHideAccessibleBuffer', "Focus Terminal and Hide Accessible Buffer"), + original: 'Focus Terminal and Hide Accessible Buffer' + }, kill: { value: localize('killTerminal', "Kill Terminal"), original: 'Kill Terminal', diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index b69943c18de..96b9602e45d 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -11,7 +11,7 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { terminalTabFocusModeContextKey } from 'vs/platform/terminal/common/terminal'; +import { TerminalLocation, terminalTabFocusModeContextKey } from 'vs/platform/terminal/common/terminal'; import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions'; import { ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; @@ -20,6 +20,7 @@ import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/brow import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; import { ITerminalProcessManager, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; +import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; import { TerminalAccessibleContentProvider } from 'vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp'; import { AccessibleBufferWidget, NavigationType } from 'vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer'; import { TextAreaSyncAddon } from 'vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon'; @@ -83,6 +84,9 @@ class AccessibleBufferContribution extends DisposableStore implements ITerminalC navigateToCommand(type: NavigationType): void { return this._accessibleBufferWidget?.navigateToCommand(type); } + hide(): void { + this._accessibleBufferWidget?.hide(); + } } registerTerminalContribution(AccessibleBufferContribution.ID, AccessibleBufferContribution); @@ -114,6 +118,7 @@ registerTerminalAction({ keybinding: [ { primary: KeyMod.Shift | KeyCode.Tab, + secondary: [KeyMod.CtrlCmd | KeyCode.UpArrow, KeyMod.Alt | KeyCode.F2], weight: KeybindingWeight.WorkbenchContrib, when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, TerminalContextKeys.focus, ContextKeyExpr.or(terminalTabFocusModeContextKey, TerminalContextKeys.accessibleBufferFocus.negate())) } @@ -161,8 +166,7 @@ registerTerminalAction({ weight: KeybindingWeight.WorkbenchContrib + 2 }, { - primary: KeyMod.CtrlCmd | KeyCode.DownArrow, - mac: { primary: KeyMod.Alt | KeyCode.DownArrow }, + primary: KeyMod.Alt | KeyCode.DownArrow, when: ContextKeyExpr.and(TerminalContextKeys.accessibleBufferFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED), weight: KeybindingWeight.WorkbenchContrib + 2 } @@ -189,8 +193,7 @@ registerTerminalAction({ weight: KeybindingWeight.WorkbenchContrib + 2 }, { - primary: KeyMod.CtrlCmd | KeyCode.UpArrow, - mac: { primary: KeyMod.Alt | KeyCode.UpArrow }, + primary: KeyMod.Alt | KeyCode.UpArrow, when: ContextKeyExpr.and(TerminalContextKeys.accessibleBufferFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED), weight: KeybindingWeight.WorkbenchContrib + 2 } @@ -204,3 +207,20 @@ registerTerminalAction({ await AccessibleBufferContribution.get(instance)?.navigateToCommand(NavigationType.Previous); } }); + +registerTerminalAction({ + id: TerminalCommandId.FocusAndHideAccessibleBuffer, + title: terminalStrings.focusAndHideAccessibleBuffer, + f1: false, + keybinding: { + when: ContextKeyExpr.and(TerminalContextKeys.accessibleBufferFocus, TerminalContextKeys.accessibleBufferOnLastLine), + primary: KeyMod.CtrlCmd | KeyCode.DownArrow, + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + const instance = c.service.activeInstance || await c.service.createTerminal({ location: TerminalLocation.Panel }); + instance.getContribution(AccessibleBufferContribution.ID)?.hide(); + instance.focus(true); + } +}); diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts index d3a0e3a592c..2504d461fb2 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts @@ -75,18 +75,20 @@ export class TerminalAccessibleContentProvider extends Disposable implements IAc content.push(localize('commandPromptMigration', "Consider using powershell instead of command prompt for an improved experience")); } if (this._hasShellIntegration) { - content.push(localize('shellIntegration', "The terminal has a feature called shell integration that offers an enhanced experience and provides useful commands for screen readers such as:")); - content.push('- ' + this._descriptionForCommand(TerminalCommandId.AccessibleBufferGoToNextCommand, localize('goToNextCommand', 'Go to Next Command ({0})'), localize('goToNextCommandNoKb', 'Go to Next Command is currently not triggerable by a keybinding.'))); - content.push('- ' + this._descriptionForCommand(TerminalCommandId.AccessibleBufferGoToPreviousCommand, localize('goToPreviousCommand', 'Go to Previous Command ({0})'), localize('goToPreviousCommandNoKb', 'Go to Previous Command is currently not triggerable by a keybinding.'))); - content.push('- ' + this._descriptionForCommand(TerminalCommandId.NavigateAccessibleBuffer, localize('navigateAccessibleBuffer', 'Navigate Accessible Buffer ({0})'), localize('navigateAccessibleBufferNoKb', 'Navigate Accessible Buffer is currently not triggerable by a keybinding.'))); - content.push('- ' + this._descriptionForCommand(TerminalCommandId.RunRecentCommand, localize('runRecentCommand', 'Run Recent Command ({0})'), localize('runRecentCommandNoKb', 'Run Recent Command is currently not triggerable by a keybinding.'))); - content.push('- ' + this._descriptionForCommand(TerminalCommandId.GoToRecentDirectory, localize('goToRecentDirectory', 'Go to Recent Directory ({0})'), localize('goToRecentDirectoryNoKb', 'Go to Recent Directory is currently not triggerable by a keybinding.'))); + const shellIntegrationCommandList = []; + shellIntegrationCommandList.push(localize('shellIntegration', "The terminal has a feature called shell integration that offers an enhanced experience and provides useful commands for screen readers such as:")); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.AccessibleBufferGoToNextCommand, localize('goToNextCommand', 'Go to Next Command ({0})'), localize('goToNextCommandNoKb', 'Go to Next Command is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.AccessibleBufferGoToPreviousCommand, localize('goToPreviousCommand', 'Go to Previous Command ({0})'), localize('goToPreviousCommandNoKb', 'Go to Previous Command is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.NavigateAccessibleBuffer, localize('navigateAccessibleBuffer', 'Navigate Accessible Buffer ({0})'), localize('navigateAccessibleBufferNoKb', 'Navigate Accessible Buffer is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.RunRecentCommand, localize('runRecentCommand', 'Run Recent Command ({0})'), localize('runRecentCommandNoKb', 'Run Recent Command is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.GoToRecentDirectory, localize('goToRecentDirectory', 'Go to Recent Directory ({0})'), localize('goToRecentDirectoryNoKb', 'Go to Recent Directory is currently not triggerable by a keybinding.'))); + content.push(shellIntegrationCommandList.join('\n')); } else { content.push(this._descriptionForCommand(TerminalCommandId.RunRecentCommand, localize('goToRecentDirectoryNoShellIntegration', 'The Go to Recent Directory command ({0}) enables screen readers to easily navigate to a directory that has been used in the terminal.'), localize('goToRecentDirectoryNoKbNoShellIntegration', 'The Go to Recent Directory command enables screen readers to easily navigate to a directory that has been used in the terminal and is currently not triggerable by a keybinding.'))); } content.push(this._descriptionForCommand(TerminalCommandId.OpenDetectedLink, localize('openDetectedLink', 'The Open Detected Link ({0}) command enables screen readers to easily open links found in the terminal.'), localize('openDetectedLinkNoKb', 'The Open Detected Link command enables screen readers to easily open links found in the terminal and is currently not triggerable by a keybinding.'))); content.push(this._descriptionForCommand(TerminalCommandId.NewWithProfile, localize('newWithProfile', 'The Create New Terminal (With Profile) ({0}) command allows for easy terminal creation using a specific profile.'), localize('newWithProfileNoKb', 'The Create New Terminal (With Profile) command allows for easy terminal creation using a specific profile and is currently not triggerable by a keybinding.'))); content.push(localize('accessibilitySettings', 'Access accessibility settings such as `terminal.integrated.tabFocusMode` via the Preferences: Open Accessibility Settings command.')); - return content.join('\n'); + return content.join('\n\n'); } } diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts index fab258f94e6..b851ad094ca 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts @@ -14,6 +14,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { ICurrentPartialCommand } from 'vs/platform/terminal/common/capabilities/commandDetectionCapability'; import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; import { ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; @@ -56,7 +57,7 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { @ITerminalLogService private readonly _logService: ITerminalLogService, @ITerminalService _terminalService: ITerminalService ) { - super(ClassName.AccessibleBuffer, _instance, _xterm, TerminalContextKeys.accessibleBufferFocus, _instantiationService, _modelService, _configurationService, _contextKeyService, _terminalService); + super(ClassName.AccessibleBuffer, _instance, _xterm, TerminalContextKeys.accessibleBufferFocus, TerminalContextKeys.accessibleBufferOnLastLine, _instantiationService, _modelService, _configurationService, _contextKeyService, _terminalService); this._bufferTracker = _instantiationService.createInstance(BufferContentTracker, _xterm); this.element.ariaRoleDescription = localize('terminal.integrated.accessibleBuffer', 'Terminal buffer'); this.updateEditor(); @@ -91,9 +92,14 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { this._resetPosition(); } - private _getEditorLineForCommand(command: ITerminalCommand): number | undefined { - let line = command.marker?.line; - if (line === undefined || !command.command.length || line < 0) { + private _getEditorLineForCommand(command: ITerminalCommand | ICurrentPartialCommand): number | undefined { + let line: number | undefined; + if ('marker' in command) { + line = command.marker?.line; + } else if ('commandStartMarker' in command) { + line = command.commandStartMarker?.line; + } + if (line === undefined || line < 0) { return; } line = this._bufferTracker.bufferToEditorLineMapping.get(line); @@ -104,7 +110,9 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { } private _getCommandsWithEditorLine(): ICommandWithEditorLine[] | undefined { - const commands = this._instance.capabilities.get(TerminalCapability.CommandDetection)?.commands; + const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection); + const commands = capability?.commands; + const currentCommand = capability?.currentCommand; if (!commands?.length) { return; } @@ -116,6 +124,12 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { } result.push({ command, lineNumber }); } + if (currentCommand) { + const lineNumber = this._getEditorLineForCommand(currentCommand); + if (!!lineNumber) { + result.push({ command: currentCommand, lineNumber }); + } + } return result; } @@ -135,7 +149,7 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { { label: localize('terminal.integrated.symbolQuickPick.labelNoExitCode', '{0}', command.command), lineNumber, - exitCode: command.exitCode + exitCode: 'exitCode' in command ? command.exitCode : undefined }); } const quickPick = this._quickInputService.createQuickPick(); @@ -261,5 +275,5 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { } } -interface ICommandWithEditorLine { command: ITerminalCommand; lineNumber: number } +interface ICommandWithEditorLine { command: ITerminalCommand | ICurrentPartialCommand; lineNumber: number } diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts index 46a475b67f3..b95d8814f1e 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts @@ -40,14 +40,16 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { protected _listeners: IDisposable[] = []; - private readonly _focusedContextKey?: IContextKey; + private readonly _focusedContextKey: IContextKey; + private readonly _focusedLastLineContextKey: IContextKey; private readonly _focusTracker?: dom.IFocusTracker; constructor( private readonly _className: string, protected readonly _instance: Pick, protected readonly _xterm: Pick & { raw: Terminal }, - private _focusContextKey: RawContextKey | undefined, + rawFocusContextKey: RawContextKey, + rawFocusLastLineContextKey: RawContextKey, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IModelService private readonly _modelService: IModelService, @IConfigurationService private readonly _configurationService: IConfigurationService, @@ -87,12 +89,21 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { this._element.replaceChildren(this._editorContainer); this._xtermElement.insertAdjacentElement('beforebegin', this._element); - if (this._focusContextKey) { - this._focusTracker = this.add(dom.trackFocus(this._editorContainer)); - this._focusedContextKey = this._focusContextKey.bindTo(this._contextKeyService); - this.add(this._focusTracker.onDidFocus(() => this._focusedContextKey?.set(true))); - this.add(this._focusTracker.onDidBlur(() => this._focusedContextKey?.reset())); - } + this._focusTracker = this.add(dom.trackFocus(this._editorContainer)); + this._focusedContextKey = rawFocusContextKey.bindTo(this._contextKeyService); + this._focusedLastLineContextKey = rawFocusLastLineContextKey.bindTo(this._contextKeyService); + this.add(this._focusTracker.onDidFocus(() => { + this._focusedContextKey?.set(true); + this._focusedLastLineContextKey?.set(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); + })); + this.add(this._focusTracker.onDidBlur(() => { + this._focusedContextKey?.reset(); + this._focusedLastLineContextKey?.reset(); + })); + this._editorWidget.onDidChangeCursorPosition(() => { + console.log(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); + this._focusedLastLineContextKey?.set(this._editorWidget.getSelection()?.positionLineNumber === this._editorWidget.getModel()?.getLineCount()); + }); this.add(Event.runAndSubscribe(this._xterm.raw.onResize, () => this.layout())); this.add(this._configurationService.onDidChangeConfiguration(e => { diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts index 8ed986db3cf..9916a6f60d0 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts @@ -3,11 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { ITerminalCapabilityStore, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; import type { Terminal, ITerminalAddon } from 'xterm'; +import { debounce } from 'vs/base/common/decorators'; +import { addDisposableListener } from 'vs/base/browser/dom'; export interface ITextAreaData { content: string; @@ -16,11 +18,14 @@ export interface ITextAreaData { export class TextAreaSyncAddon extends Disposable implements ITerminalAddon { private _terminal: Terminal | undefined; - private _onCursorMoveListener = this._register(new MutableDisposable()); + private _listeners = this._register(new MutableDisposable()); + private _currentCommand: string | undefined; + private _cursorX: number | undefined; + activate(terminal: Terminal): void { this._terminal = terminal; if (this._accessibilityService.isScreenReaderOptimized()) { - this._onCursorMoveListener.value = this._terminal.onCursorMove(() => this._refreshTextArea()); + this._registerSyncListeners(); } } @@ -31,75 +36,77 @@ export class TextAreaSyncAddon extends Disposable implements ITerminalAddon { ) { super(); this._register(this._accessibilityService.onDidChangeScreenReaderOptimized(() => { - if (this._accessibilityService.isScreenReaderOptimized() && this._terminal) { - this._refreshTextArea(); - this._onCursorMoveListener.value = this._terminal.onCursorMove(() => this._refreshTextArea()); + if (this._accessibilityService.isScreenReaderOptimized()) { + this._syncTextArea(); + this._registerSyncListeners(); } else { - this._onCursorMoveListener.clear(); + this._listeners.clear(); } })); } - private _refreshTextArea(focusChanged?: boolean): void { + private _registerSyncListeners(): void { + if (this._accessibilityService.isScreenReaderOptimized() && this._terminal?.textarea) { + this._listeners.value = new DisposableStore(); + this._listeners.value.add(this._terminal.onCursorMove(() => this._syncTextArea())); + this._listeners.value.add(this._terminal.onData(() => this._syncTextArea())); + this._listeners.value.add(addDisposableListener(this._terminal.textarea, 'focus', () => this._syncTextArea())); + } + } + + @debounce(50) + private _syncTextArea(): void { + this._logService.debug('TextAreaSyncAddon#syncTextArea'); + const textArea = this._terminal?.textarea; + if (!textArea) { + this._logService.debug(`TextAreaSyncAddon#syncTextArea: no textarea`); + return; + } + + this._updateCommandAndCursor(); + + if (this._currentCommand !== textArea.value) { + textArea.value = this._currentCommand || ''; + this._logService.debug(`TextAreaSyncAddon#syncTextArea: text changed to "${this._currentCommand}"`); + } else if (!this._currentCommand) { + textArea.value = ''; + this._logService.debug(`TextAreaSyncAddon#syncTextArea: text cleared`); + } + + if (this._cursorX !== textArea.selectionStart) { + textArea.selectionStart = this._cursorX ?? 0; + textArea.selectionEnd = this._cursorX ?? 0; + this._logService.debug(`TextAreaSyncAddon#syncTextArea: selection start/end changed to ${this._cursorX}`); + } + } + + private _updateCommandAndCursor(): void { if (!this._terminal) { return; } - this._logService.debug('TextAreaSyncAddon#refreshTextArea'); const commandCapability = this._capabilities.get(TerminalCapability.CommandDetection); const currentCommand = commandCapability?.currentCommand; if (!currentCommand) { - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: no currentCommand`); + this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no current command`); return; } const buffer = this._terminal.buffer.active; - const line = buffer.getLine(buffer.cursorY)?.translateToString(true); - let commandStartX: number | undefined; - if (!line) { - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: no line`); + const lineNumber = currentCommand.commandStartMarker?.line; + if (!lineNumber) { return; } - let content: string | undefined; - if (currentCommand.commandStartX) { - // Left prompt - content = line.substring(currentCommand.commandStartX); - commandStartX = currentCommand.commandStartX; - } else if (currentCommand.commandRightPromptStartX) { - // Right prompt - content = line.substring(0, currentCommand.commandRightPromptStartX); - commandStartX = 0; - } - - if (!content) { - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: no content`); + const commandLine = buffer.getLine(lineNumber)?.translateToString(true); + if (!commandLine) { + this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no line`); return; } - - if (commandStartX === undefined) { - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: no commandStartX`); - return; + if (!!currentCommand.commandStartX) { + this._currentCommand = commandLine.substring(currentCommand.commandStartX); + this._cursorX = buffer.cursorX - currentCommand.commandStartX; + } else { + this._currentCommand = undefined; + this._cursorX = undefined; + this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no commandStartX`); } - - const textArea = this._terminal.textarea; - if (!textArea) { - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: no textarea`); - return; - } - - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: content is "${content}"`); - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: textContent is "${textArea.textContent}"`); - if (focusChanged || content !== textArea.textContent) { - textArea.textContent = content; - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: textContent changed to "${content}"`); - } - - const cursorX = buffer.cursorX - commandStartX; - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: cursorX is ${cursorX}`); - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: selectionStart is ${textArea.selectionStart}`); - if (focusChanged || cursorX !== textArea.selectionStart) { - textArea.selectionStart = cursorX; - textArea.selectionEnd = cursorX; - this._logService.debug(`TextAreaSyncAddon#refreshTextArea: selectionStart changed to ${cursorX}`); - } - // TODO: cursorY? } } diff --git a/src/vs/workbench/contrib/terminalContrib/environmentChanges/browser/terminal.environmentChanges.contribution.ts b/src/vs/workbench/contrib/terminalContrib/environmentChanges/browser/terminal.environmentChanges.contribution.ts index ed59231bb57..e4bcaf9b0c0 100644 --- a/src/vs/workbench/contrib/terminalContrib/environmentChanges/browser/terminal.environmentChanges.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/environmentChanges/browser/terminal.environmentChanges.contribution.ts @@ -55,15 +55,14 @@ function describeEnvironmentChanges(collection: IMergedEnvironmentVariableCollec content += '\n'; const globalDescription = globalDescriptions.get(ext); if (globalDescription) { - content += `\n${globalDescription}`; + content += `\n${globalDescription}\n`; } const workspaceDescription = workspaceDescriptions.get(ext); if (workspaceDescription) { // Only show '(workspace)' suffix if there is already a description for the extension. const workspaceSuffix = globalDescription ? ` (${localize('ScopedEnvironmentContributionInfo', 'workspace')})` : ''; - content += `\n${workspaceDescription}${workspaceSuffix}`; + content += `\n${workspaceDescription}${workspaceSuffix}\n`; } - content += '\n'; for (const mutator of coll.map.values()) { if (filterScope(mutator, scope) === false) { diff --git a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix.ts b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix.ts index 8a13380b971..f576102fe85 100644 --- a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix.ts +++ b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix.ts @@ -56,6 +56,7 @@ export interface ITerminalQuickFixOptions { commandLineMatcher: string | RegExp; outputMatcher?: ITerminalOutputMatcher; commandExitResult: 'success' | 'error'; + kind?: 'fix' | 'explain'; } export interface ITerminalQuickFix { diff --git a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFixAddon.ts b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFixAddon.ts index 0631a1e4e04..9f1ccc65e8c 100644 --- a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFixAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/quickFixAddon.ts @@ -36,9 +36,8 @@ import { Codicon } from 'vs/base/common/codicons'; import { ThemeIcon } from 'vs/base/common/themables'; import { ICommandService } from 'vs/platform/commands/common/commands'; -const quickFixSelectors = [ +const quickFixClasses = [ DecorationSelector.QuickFix, - DecorationSelector.LightBulb, DecorationSelector.Codicon, DecorationSelector.CommandDecoration, DecorationSelector.XtermDecoration @@ -116,7 +115,7 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon, } // TODO: What's documentation do? Need a vscode command? - const actions = this._currentRenderContext.quickFixes.map(f => new TerminalQuickFixItem(f, f.type, f.source, f.label)); + const actions = this._currentRenderContext.quickFixes.map(f => new TerminalQuickFixItem(f, f.type, f.source, f.label, f.kind)); const documentation = this._currentRenderContext.quickFixes.map(f => { return { id: f.source, title: f.label, tooltip: f.source }; }); const actionSet = { // TODO: Documentation and actions are separate? @@ -150,7 +149,8 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon, type: 'unresolved', commandLineMatcher: selector.commandLineMatcher, outputMatcher: selector.outputMatcher, - commandExitResult: selector.commandExitResult + commandExitResult: selector.commandExitResult, + kind: selector.kind }); this._registeredSelectors.add(selector.id); this._commandListeners.set(matcherKey, currentOptions); @@ -192,7 +192,14 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon, } const id = selector.id; await this._extensionService.activateByEvent(`onTerminalQuickFixRequest:${id}`); - return this._quickFixService.providers.get(id)?.provideTerminalQuickFixes(command, lines, { type: 'resolved', commandLineMatcher: selector.commandLineMatcher, outputMatcher: selector.outputMatcher, commandExitResult: selector.commandExitResult, id: selector.id }, new CancellationTokenSource().token); + return this._quickFixService.providers.get(id)?.provideTerminalQuickFixes(command, lines, { + type: 'resolved', + commandLineMatcher: selector.commandLineMatcher, + outputMatcher: selector.outputMatcher, + commandExitResult: selector.commandExitResult, + kind: selector.kind, + id: selector.id + }, new CancellationTokenSource().token); }; const result = await getQuickFixesForCommand(aliases, terminal, command, this._commandListeners, this._commandService, this._openerService, this._labelService, this._onDidRequestRerunCommand, resolver); if (!result) { @@ -266,7 +273,13 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon, return; } - e.classList.add(...quickFixSelectors); + e.classList.add(...quickFixClasses); + const isExplainOnly = fixes.every(e => e.kind === 'explain'); + if (isExplainOnly) { + e.classList.add('explainOnly'); + } + e.classList.add(...ThemeIcon.asClassNameArray(isExplainOnly ? Codicon.sparkle : Codicon.lightBulb)); + updateLayout(this._configurationService, e); this._audioCueService.playAudioCue(AudioCue.terminalQuickFix); @@ -285,6 +298,7 @@ export class TerminalQuickFixAddon extends Disposable implements ITerminalAddon, export interface ITerminalAction extends IAction { type: TerminalQuickFixType; + kind?: 'fix' | 'explain'; source: string; uri?: URI; command?: string; @@ -351,6 +365,7 @@ export async function getQuickFixesForCommand( const label = localize('quickFix.command', 'Run: {0}', fix.terminalCommand); action = { type: TerminalQuickFixType.TerminalCommand, + kind: option.kind, class: undefined, source: quickFix.source, id: quickFix.id, @@ -384,6 +399,7 @@ export async function getQuickFixesForCommand( id: quickFix.id, label, type: TerminalQuickFixType.Opener, + kind: option.kind, class: undefined, enabled: true, run: () => openerService.open(fix.uri), @@ -397,6 +413,7 @@ export async function getQuickFixesForCommand( action = { source: 'builtin', type: fix.type, + kind: option.kind, id: fix.id, label: fix.label, class: fix.class, @@ -413,6 +430,7 @@ export async function getQuickFixesForCommand( action = { source: quickFix.source, type: fix.type, + kind: option.kind, id: fix.id, label: fix.title, class: undefined, @@ -441,22 +459,20 @@ function convertToQuickFixOptions(selectorProvider: ITerminalQuickFixProviderSel commandLineMatcher: selectorProvider.selector.commandLineMatcher, outputMatcher: selectorProvider.selector.outputMatcher, commandExitResult: selectorProvider.selector.commandExitResult, + kind: selectorProvider.selector.kind, getQuickFixes: selectorProvider.provider.provideTerminalQuickFixes }; } class TerminalQuickFixItem { - action: ITerminalAction; - type: TerminalQuickFixType; - disabled?: boolean; - title?: string; - source: string; - constructor(action: ITerminalAction, type: TerminalQuickFixType, source: string, title?: string, disabled?: boolean) { - this.action = action; - this.disabled = disabled; - this.title = title; - this.source = source; - this.type = type; + readonly disabled = false; + constructor( + readonly action: ITerminalAction, + readonly type: TerminalQuickFixType, + readonly source: string, + readonly title: string | undefined, + readonly kind: 'fix' | 'explain' = 'fix' + ) { } } @@ -488,6 +504,9 @@ function toActionWidgetItems(inputQuickFixes: readonly TerminalQuickFixItem[], s } function getQuickFixIcon(quickFix: TerminalQuickFixItem): ThemeIcon { + if (quickFix.kind === 'explain') { + return Codicon.sparkle; + } switch (quickFix.type) { case TerminalQuickFixType.Opener: if ('uri' in quickFix.action && quickFix.action.uri) { diff --git a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminal.quickFix.contribution.ts b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminal.quickFix.contribution.ts index f910bb1b7c3..96f2fccd74f 100644 --- a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminal.quickFix.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminal.quickFix.contribution.ts @@ -55,7 +55,7 @@ class TerminalQuickFixContribution extends DisposableStore implements ITerminalC // Register quick fixes for (const actionOption of [ gitTwoDashes(), - freePort(this), + freePort((port: string, command: string) => this._instance.freePortKillProcess(port, command)), gitSimilar(), gitPushSetUpstream(), gitCreatePr(), diff --git a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixBuiltinActions.ts b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixBuiltinActions.ts index 386eb5153fb..89284446f73 100644 --- a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixBuiltinActions.ts +++ b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixBuiltinActions.ts @@ -5,7 +5,6 @@ import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; -import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ITerminalQuickFixInternalOptions, ITerminalCommandMatchResult, ITerminalQuickFixExecuteTerminalCommandAction, TerminalQuickFixActionInternal, TerminalQuickFixType } from 'vs/workbench/contrib/terminalContrib/quickFix/browser/quickFix'; export const GitCommandLineRegex = /git/; @@ -88,7 +87,7 @@ export function gitTwoDashes(): ITerminalQuickFixInternalOptions { } }; } -export function freePort(terminalInstance?: Partial): ITerminalQuickFixInternalOptions { +export function freePort(runCallback: (port: string, commandLine: string) => Promise): ITerminalQuickFixInternalOptions { return { id: 'Free Port', type: 'internal', @@ -114,9 +113,7 @@ export function freePort(terminalInstance?: Partial): ITermin label, enabled: true, source: QuickFixSource.Builtin, - run: async () => { - await terminalInstance?.freePortKillProcess?.(port, matchResult.commandLine); - } + run: () => runCallback(port, matchResult.commandLine) }; } }; diff --git a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixService.ts b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixService.ts index 4119c99c047..61b17085bb6 100644 --- a/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixService.ts +++ b/src/vs/workbench/contrib/terminalContrib/quickFix/browser/terminalQuickFixService.ts @@ -139,6 +139,14 @@ const quickFixExtensionPoint = ExtensionsRegistry.registerExtensionPoint { let quickFixAddon: TerminalQuickFixAddon; - let terminalInstance: Pick; let commandDetection: CommandDetectionCapability; let commandService: TestCommandService; let openerService: OpenerService; @@ -65,9 +63,6 @@ suite('QuickFixAddon', () => { instantiationService.stub(IContextMenuService, instantiationService.createInstance(ContextMenuService)); instantiationService.stub(IOpenerService, {} as Partial); commandService = new TestCommandService(instantiationService); - terminalInstance = { - async freePortKillProcess(port: string): Promise { } - } as Pick; quickFixAddon = instantiationService.createInstance(TerminalQuickFixAddon, [], capabilities); terminal.loadAddon(quickFixAddon); @@ -212,7 +207,7 @@ suite('QuickFixAddon', () => { enabled: true }]; setup(() => { - const command = freePort(terminalInstance); + const command = freePort(() => Promise.resolve()); expectedMap.set(command.commandLineMatcher.toString(), [command]); quickFixAddon.registerCommandFinishedListener(command); }); diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts index fe492af83eb..3e67da4150b 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts @@ -224,7 +224,7 @@ export class TreeProjection extends Disposable implements ITestTreeProjection { } // The first element will cause the root to be hidden - const affectsRootElement = toRemove.parent?.children.size === 1; + const affectsRootElement = toRemove.depth === 1 && toRemove.parent?.children.size === 1; this.changedParents.add(affectsRootElement ? null : toRemove.parent); const queue: Iterable[] = [[toRemove]]; @@ -302,7 +302,7 @@ export class TreeProjection extends Disposable implements ITestTreeProjection { this.items.set(treeElement.test.item.extId, treeElement); // The first element will cause the root to be shown - const affectsRootElement = treeElement.parent?.children.size === 1; + const affectsRootElement = treeElement.depth === 1 && treeElement.parent?.children.size === 1; this.changedParents.add(affectsRootElement ? null : treeElement.parent); if (treeElement.depth === 0 || isCollapsedInSerializedTestTree(this.lastState, treeElement.test.item.extId) === false) { diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts index 5080d93ece2..84e09da8c8f 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts @@ -993,7 +993,7 @@ class TestingExplorerViewModel extends Disposable { this.projection.value = this.instantiationService.createInstance(TreeProjection, lastState); } - const scheduler = new RunOnceScheduler(() => this.applyProjectionChanges(), 200); + const scheduler = this._register(new RunOnceScheduler(() => this.applyProjectionChanges(), 200)); this.projection.value.onUpdate(() => { if (!scheduler.isScheduled()) { scheduler.schedule(); diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts index 85ba62c640e..f0c08e1b826 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts @@ -16,7 +16,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' import { URI } from 'vs/base/common/uri'; import { joinPath } from 'vs/base/common/resources'; import { FileAccess } from 'vs/base/common/network'; -import { EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { EXTENSION_INSTALL_DEP_PACK_CONTEXT, EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ThemeIcon } from 'vs/base/common/themables'; import { walkthroughs } from 'vs/workbench/contrib/welcomeGettingStarted/common/gettingStartedContent'; import { IWorkbenchAssignmentService } from 'vs/workbench/services/assignment/common/assignmentService'; @@ -229,9 +229,10 @@ export class WalkthroughsService extends Disposable implements IWalkthroughsServ this._register(this.extensionManagementService.onDidInstallExtensions(async (result) => { const hadLastFoucs = await this.hostService.hadLastFocus(); for (const e of result) { + const skipWalkthrough = e?.context?.[EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT] || e?.context?.[EXTENSION_INSTALL_DEP_PACK_CONTEXT]; // If the window had last focus and the install didn't specify to skip the walkthrough // Then add it to the sessionInstallExtensions to be opened - if (hadLastFoucs && !e?.context?.[EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT]) { + if (hadLastFoucs && !skipWalkthrough) { this.sessionInstalledExtensions.add(e.identifier.id.toLowerCase()); } this.progressByEvent(`extensionInstalled:${e.identifier.id.toLowerCase()}`); diff --git a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts index 6d705492fe9..8bc95f4f591 100644 --- a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts +++ b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts @@ -32,7 +32,6 @@ import { isEmptyWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleF import { dirname, resolve } from 'vs/base/common/path'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent'; -import { STATUS_BAR_PROMINENT_ITEM_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_FOREGROUND } from 'vs/workbench/common/theme'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IBannerItem, IBannerService } from 'vs/workbench/services/banner/browser/bannerService'; @@ -527,9 +526,6 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon private getStatusbarEntry(trusted: boolean): IStatusbarEntry { const text = workspaceTrustToString(trusted); - const backgroundColor = { id: STATUS_BAR_PROMINENT_ITEM_BACKGROUND }; - const color = { id: STATUS_BAR_PROMINENT_ITEM_FOREGROUND }; - let ariaLabel = ''; let toolTip: IMarkdownString | string | undefined; switch (this.workspaceContextService.getWorkbenchState()) { @@ -586,8 +582,7 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon ariaLabel: ariaLabel, tooltip: toolTip, command: MANAGE_TRUST_COMMAND_ID, - backgroundColor, - color + kind: 'prominent' }; } diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts index 5b625c9c856..1efcf6ba71f 100644 --- a/src/vs/workbench/electron-sandbox/window.ts +++ b/src/vs/workbench/electron-sandbox/window.ts @@ -723,118 +723,35 @@ export class NativeWindow extends Disposable { } } - // Windows 7/8/8.1 warning - if (isWindows) { - const version = this.environmentService.os.release.split('.'); - const majorVersion = version[0]; - const minorVersion = version[1]; - const eolReleases = new Map>([ - ['6', new Map([ - ['1', 'Windows 7 / Windows Server 2008 R2'], - ['2', 'Windows 8 / Windows Server 2012'], - ['3', 'Windows 8.1 / Windows Server 2012 R2'], - ])], - ]); + // Windows 32-bit warning + if (isWindows && this.environmentService.os.arch === 'ia32') { + const message = localize('windows32eolmessage', "{0} on Windows 32-bit will soon stop receiving updates. Consider upgrading to the 64-bit build.", this.productService.nameLong); + const actions = [{ + label: localize('windowseolBannerLearnMore', "Learn More"), + href: 'https://aka.ms/vscode-faq-old-windows' + }]; - // Refs https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoa - if (eolReleases.get(majorVersion)?.has(minorVersion)) { - const message = localize('windowseolmessage', "{0} on {1} will soon stop receiving updates. Consider upgrading your windows version.", this.productService.nameLong, eolReleases.get(majorVersion)?.get(minorVersion)); - const actions = [{ - label: localize('windowseolBannerLearnMore', "Learn More"), - href: 'https://aka.ms/vscode-faq-old-windows' - }]; + this.bannerService.show({ + id: 'windows32eol.banner', + message, + ariaLabel: localize('windowseolarialabel', "{0}. Use navigation keys to access banner actions.", message), + actions, + icon: Codicon.warning + }); - this.bannerService.show({ - id: 'windowseol.banner', - message, - ariaLabel: localize('windowseolarialabel', "{0}. Use navigation keys to access banner actions.", message), - actions, - icon: Codicon.warning - }); - - this.notificationService.prompt( - Severity.Warning, - message, - [{ - label: localize('learnMore', "Learn More"), - run: () => this.openerService.open(URI.parse('https://aka.ms/vscode-faq-old-windows')) - }], - { - neverShowAgain: { id: 'windowseol', isSecondary: true, scope: NeverShowAgainScope.APPLICATION }, - priority: NotificationPriority.URGENT, - sticky: true - } - ); - } - - else if (this.environmentService.os.arch === 'ia32') { - const message = localize('windows32eolmessage', "{0} on Windows 32-bit will soon stop receiving updates. Consider upgrading to the 64-bit build.", this.productService.nameLong); - const actions = [{ - label: localize('windowseolBannerLearnMore', "Learn More"), - href: 'https://aka.ms/vscode-faq-old-windows' - }]; - - this.bannerService.show({ - id: 'windows32eol.banner', - message, - ariaLabel: localize('windowseolarialabel', "{0}. Use navigation keys to access banner actions.", message), - actions, - icon: Codicon.warning - }); - - this.notificationService.prompt( - Severity.Warning, - message, - [{ - label: localize('learnMore', "Learn More"), - run: () => this.openerService.open(URI.parse('https://aka.ms/vscode-faq-old-windows')) - }], - { - neverShowAgain: { id: 'windows32eol', isSecondary: true, scope: NeverShowAgainScope.APPLICATION }, - priority: NotificationPriority.URGENT, - sticky: true - } - ); - } - } - - // MacOS 10.11 and 10.12 warning - if (isMacintosh) { - const majorVersion = this.environmentService.os.release.split('.')[0]; - const eolReleases = new Map([ - ['15', 'OS X El Capitan'], - ['16', 'macOS Sierra'], - ]); - // Refs https://en.wikipedia.org/wiki/Darwin_%28operating_system%29#Release_history - if (eolReleases.has(majorVersion)) { - const message = localize('macoseolmessage', "{0} on {1} will soon stop receiving updates. Consider upgrading your macOS version.", this.productService.nameLong, eolReleases.get(majorVersion)); - const actions = [{ - label: localize('macoseolBannerLearnMore', "Learn More"), - href: 'https://aka.ms/vscode-faq-old-macOS' - }]; - - this.bannerService.show({ - id: 'macoseol.banner', - message, - ariaLabel: localize('macoseolarialabel', "{0}. Use navigation keys to access banner actions.", message), - actions, - icon: Codicon.warning - }); - - this.notificationService.prompt( - Severity.Warning, - message, - [{ - label: localize('learnMore', "Learn More"), - run: () => this.openerService.open(URI.parse('https://aka.ms/vscode-faq-old-macOS')) - }], - { - neverShowAgain: { id: 'macoseol', isSecondary: true, scope: NeverShowAgainScope.APPLICATION }, - priority: NotificationPriority.URGENT, - sticky: true - } - ); - } + this.notificationService.prompt( + Severity.Warning, + message, + [{ + label: localize('learnMore', "Learn More"), + run: () => this.openerService.open(URI.parse('https://aka.ms/vscode-faq-old-windows')) + }], + { + neverShowAgain: { id: 'windows32eol', isSecondary: true, scope: NeverShowAgainScope.APPLICATION }, + priority: NotificationPriority.URGENT, + sticky: true + } + ); } // Slow shell environment progress indicator diff --git a/src/vs/workbench/services/aiEmbeddingVector/common/aiEmbeddingVectorService.ts b/src/vs/workbench/services/aiEmbeddingVector/common/aiEmbeddingVectorService.ts new file mode 100644 index 00000000000..bb143a48893 --- /dev/null +++ b/src/vs/workbench/services/aiEmbeddingVector/common/aiEmbeddingVectorService.ts @@ -0,0 +1,114 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { CancelablePromise, createCancelablePromise, raceCancellablePromises, timeout } from 'vs/base/common/async'; +import { IDisposable } from 'vs/base/common/lifecycle'; +import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { StopWatch } from 'vs/base/common/stopwatch'; +import { ILogService } from 'vs/platform/log/common/log'; + +export const IAiEmbeddingVectorService = createDecorator('IAiEmbeddingVectorService'); + +export interface IAiEmbeddingVectorService { + readonly _serviceBrand: undefined; + + isEnabled(): boolean; + getEmbeddingVector(str: string, token: CancellationToken): Promise; + getEmbeddingVector(strings: string[], token: CancellationToken): Promise; + registerAiEmbeddingVectorProvider(model: string, provider: IAiEmbeddingVectorProvider): IDisposable; +} + +export interface IAiEmbeddingVectorProvider { + provideAiEmbeddingVector(strings: string[], token: CancellationToken): Promise; +} + +export class AiEmbeddingVectorService implements IAiEmbeddingVectorService { + readonly _serviceBrand: undefined; + + static readonly DEFAULT_TIMEOUT = 1000 * 10; // 10 seconds + + private readonly _providers: IAiEmbeddingVectorProvider[] = []; + + constructor(@ILogService private readonly logService: ILogService) { } + + isEnabled(): boolean { + return this._providers.length > 0; + } + + registerAiEmbeddingVectorProvider(model: string, provider: IAiEmbeddingVectorProvider): IDisposable { + this._providers.push(provider); + return { + dispose: () => { + const index = this._providers.indexOf(provider); + if (index >= 0) { + this._providers.splice(index, 1); + } + } + }; + } + + getEmbeddingVector(str: string, token: CancellationToken): Promise; + getEmbeddingVector(strings: string[], token: CancellationToken): Promise; + async getEmbeddingVector(strings: string | string[], token: CancellationToken): Promise { + if (this._providers.length === 0) { + throw new Error('No embedding vector providers registered'); + } + + const stopwatch = StopWatch.create(); + + const cancellablePromises: Array> = []; + + const timer = timeout(AiEmbeddingVectorService.DEFAULT_TIMEOUT); + const disposable = token.onCancellationRequested(() => { + disposable.dispose(); + timer.cancel(); + }); + + for (const provider of this._providers) { + cancellablePromises.push(createCancelablePromise(async t => { + try { + return await provider.provideAiEmbeddingVector( + Array.isArray(strings) ? strings : [strings], + t + ); + } catch (e) { + // logged in extension host + } + // Wait for the timer to finish to allow for another provider to resolve. + // Alternatively, if something resolved, or we've timed out, this will throw + // as expected. + await timer; + throw new Error('Embedding vector provider timed out'); + })); + } + + cancellablePromises.push(createCancelablePromise(async (t) => { + const disposable = t.onCancellationRequested(() => { + timer.cancel(); + disposable.dispose(); + }); + await timer; + throw new Error('Embedding vector provider timed out'); + })); + + try { + const result = await raceCancellablePromises(cancellablePromises); + + // If we have a single result, return it directly, otherwise return an array. + // This aligns with the API overloads. + if (result.length === 1) { + return result[0]; + } + return result; + } finally { + stopwatch.stop(); + this.logService.trace(`[AiEmbeddingVectorService]: getEmbeddingVector took ${stopwatch.elapsed()}ms`); + } + } +} + +registerSingleton(IAiEmbeddingVectorService, AiEmbeddingVectorService, InstantiationType.Delayed); diff --git a/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts b/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts new file mode 100644 index 00000000000..f3b7d9a090f --- /dev/null +++ b/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IDisposable } from 'vs/base/common/lifecycle'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const IAiRelatedInformationService = createDecorator('IAiRelatedInformationService'); + +export enum RelatedInformationType { + SymbolInformation = 1, + CommandInformation = 2, + SearchInformation = 3, + SettingInformation = 4 +} + +interface RelatedInformationBaseResult { + type: RelatedInformationType; + weight: number; +} + +export interface CommandInformationResult extends RelatedInformationBaseResult { + type: RelatedInformationType.CommandInformation; + command: string; +} + +export interface SettingInformationResult extends RelatedInformationBaseResult { + type: RelatedInformationType.SettingInformation; + setting: string; +} + +export type RelatedInformationResult = CommandInformationResult | SettingInformationResult; + +export interface IAiRelatedInformationService { + readonly _serviceBrand: undefined; + + isEnabled(): boolean; + getRelatedInformation(query: string, types: RelatedInformationType[], token: CancellationToken): Promise; + registerAiRelatedInformationProvider(type: RelatedInformationType, provider: IAiRelatedInformationProvider): IDisposable; +} + +export interface IAiRelatedInformationProvider { + provideAiRelatedInformation(query: string, token: CancellationToken): Promise; +} diff --git a/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformationService.ts b/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformationService.ts new file mode 100644 index 00000000000..7168c3b4eed --- /dev/null +++ b/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformationService.ts @@ -0,0 +1,111 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationToken } from 'vs/base/common/cancellation'; +import { CancelablePromise, createCancelablePromise, raceCancellablePromises, timeout } from 'vs/base/common/async'; +import { IDisposable } from 'vs/base/common/lifecycle'; +import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { StopWatch } from 'vs/base/common/stopwatch'; +import { ILogService } from 'vs/platform/log/common/log'; +import { IAiRelatedInformationService, IAiRelatedInformationProvider, RelatedInformationType, RelatedInformationResult } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation'; + +export class AiRelatedInformationService implements IAiRelatedInformationService { + readonly _serviceBrand: undefined; + + static readonly DEFAULT_TIMEOUT = 1000 * 10; // 10 seconds + + private readonly _providers: Map = new Map(); + + constructor(@ILogService private readonly logService: ILogService) { } + + isEnabled(): boolean { + return this._providers.size > 0; + } + + registerAiRelatedInformationProvider(type: RelatedInformationType, provider: IAiRelatedInformationProvider): IDisposable { + const providers = this._providers.get(type) ?? []; + providers.push(provider); + this._providers.set(type, providers); + + + return { + dispose: () => { + const providers = this._providers.get(type) ?? []; + const index = providers.indexOf(provider); + if (index !== -1) { + providers.splice(index, 1); + } + if (providers.length === 0) { + this._providers.delete(type); + } + } + }; + } + + async getRelatedInformation(query: string, types: RelatedInformationType[], token: CancellationToken): Promise { + if (this._providers.size === 0) { + throw new Error('No related information providers registered'); + } + + // get providers for each type + const providers: IAiRelatedInformationProvider[] = []; + for (const type of types) { + const typeProviders = this._providers.get(type); + if (typeProviders) { + providers.push(...typeProviders); + } + } + + if (providers.length === 0) { + throw new Error('No related information providers registered for the given types'); + } + + const stopwatch = StopWatch.create(); + + const cancellablePromises: Array> = []; + + const timer = timeout(AiRelatedInformationService.DEFAULT_TIMEOUT); + const disposable = token.onCancellationRequested(() => { + disposable.dispose(); + timer.cancel(); + }); + + for (const provider of providers) { + cancellablePromises.push(createCancelablePromise(async t => { + try { + const result = await provider.provideAiRelatedInformation(query, t); + // double filter just in case + return result.filter(r => types.includes(r.type)); + } catch (e) { + // logged in extension host + } + // Wait for the timer to finish to allow for another provider to resolve. + // Alternatively, if something resolved, or we've timed out, this will throw + // as expected. + await timer; + throw new Error('Related information provider timed out'); + })); + } + + cancellablePromises.push(createCancelablePromise(async (t) => { + const disposable = t.onCancellationRequested(() => { + timer.cancel(); + disposable.dispose(); + }); + await timer; + throw new Error('Related information provider timed out'); + })); + + try { + const result = await raceCancellablePromises(cancellablePromises); + return result; + } finally { + stopwatch.stop(); + this.logService.trace(`[AiRelatedInformationService]: getRelatedInformation took ${stopwatch.elapsed()}ms`); + } + } +} + +registerSingleton(IAiRelatedInformationService, AiRelatedInformationService, InstantiationType.Delayed); diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 8f942efdd0e..591bddbe576 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -259,8 +259,8 @@ class FileServiceBasedConfiguration extends Disposable { const resolveContents = async (resources: URI[]): Promise<(string | undefined)[]> => { return Promise.all(resources.map(async resource => { try { - const content = (await this.fileService.readFile(resource)).value.toString(); - return content; + const content = await this.fileService.readFile(resource, { atomic: true }); + return content.value.toString(); } catch (error) { this.logService.trace(`Error while resolving configuration file '${resource.toString()}': ${errors.getErrorMessage(error)}`); if ((error).fileOperationResult !== FileOperationResult.FILE_NOT_FOUND @@ -494,7 +494,7 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable { } async resolveContent(): Promise { - const content = await this.fileService.readFile(this.configurationResource); + const content = await this.fileService.readFile(this.configurationResource, { atomic: true }); return content.value.toString(); } @@ -764,7 +764,7 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable { } async resolveContent(workspaceIdentifier: IWorkspaceIdentifier): Promise { - const content = await this.fileService.readFile(workspaceIdentifier.configPath); + const content = await this.fileService.readFile(workspaceIdentifier.configPath, { atomic: true }); return content.value.toString(); } diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index bc40358f62f..d2c05378c9c 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -47,7 +47,7 @@ import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/envir import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined { - return userDataProfile.isDefault + return (userDataProfile.isDefault || userDataProfile.useDefaultFlags?.settings) ? hasRemote ? LOCAL_MACHINE_SCOPES : undefined : hasRemote ? LOCAL_MACHINE_PROFILE_SCOPES : PROFILE_SCOPES; } diff --git a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts index e0613cac0c7..72084f75018 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts @@ -1774,6 +1774,22 @@ suite('WorkspaceConfigurationService - Profiles', () => { assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'profileValue2'); })); + test('switch to non default profile using settings from default profile', () => runWithFakedTimers({ useFakeTimers: true }, async () => { + await fileService.writeFile(instantiationService.get(IUserDataProfilesService).defaultProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.applicationSetting": "applicationValue", "configurationService.profiles.testSetting": "userValue" }')); + await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.applicationSetting": "profileValue", "configurationService.profiles.testSetting": "profileValue" }')); + await testObject.reloadConfiguration(); + + const profile = toUserDataProfile('custom3', 'custom3', joinPath(environmentService.userRoamingDataHome, 'profiles', 'custom2'), joinPath(environmentService.cacheHome, 'profilesCache'), { useDefaultFlags: { settings: true } }, instantiationService.get(IUserDataProfilesService).defaultProfile); + await fileService.writeFile(profile.settingsResource, VSBuffer.fromString('{ "configurationService.profiles.applicationSetting": "applicationValue2", "configurationService.profiles.testSetting": "profileValue2" }')); + const promise = Event.toPromise(testObject.onDidChangeConfiguration); + await userDataProfileService.updateCurrentProfile(profile); + + const changeEvent = await promise; + assert.deepStrictEqual([...changeEvent.affectedKeys], ['configurationService.profiles.applicationSetting', 'configurationService.profiles.testSetting']); + assert.strictEqual(testObject.getValue('configurationService.profiles.applicationSetting'), 'applicationValue2'); + assert.strictEqual(testObject.getValue('configurationService.profiles.testSetting'), 'profileValue2'); + })); + test('In non-default profile, changing application settings shall include only application scope settings in the change event', () => runWithFakedTimers({ useFakeTimers: true }, async () => { await fileService.writeFile(instantiationService.get(IUserDataProfilesService).defaultProfile.settingsResource, VSBuffer.fromString('{}')); await testObject.reloadConfiguration(); diff --git a/src/vs/workbench/services/editor/browser/codeEditorService.ts b/src/vs/workbench/services/editor/browser/codeEditorService.ts index 657f203312c..9930f85f58c 100644 --- a/src/vs/workbench/services/editor/browser/codeEditorService.ts +++ b/src/vs/workbench/services/editor/browser/codeEditorService.ts @@ -25,8 +25,8 @@ export class CodeEditorService extends AbstractCodeEditorService { ) { super(themeService); - this.registerCodeEditorOpenHandler(this.doOpenCodeEditor.bind(this)); - this.registerCodeEditorOpenHandler(this.doOpenCodeEditorFromDiff.bind(this)); + this._register(this.registerCodeEditorOpenHandler(this.doOpenCodeEditor.bind(this))); + this._register(this.registerCodeEditorOpenHandler(this.doOpenCodeEditorFromDiff.bind(this))); } getActiveCodeEditor(): ICodeEditor | null { diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index e241e493f65..f997b3ecfbd 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -83,9 +83,9 @@ export class EditorService extends Disposable implements EditorServiceImpl { // Editor & group changes this.editorGroupService.whenReady.then(() => this.onEditorGroupsReady()); - this.editorGroupService.onDidChangeActiveGroup(group => this.handleActiveEditorChange(group)); - this.editorGroupService.onDidAddGroup(group => this.registerGroupListeners(group as IEditorGroupView)); - this.editorsObserver.onDidMostRecentlyActiveEditorsChange(() => this._onDidMostRecentlyActiveEditorsChange.fire()); + this._register(this.editorGroupService.onDidChangeActiveGroup(group => this.handleActiveEditorChange(group))); + this._register(this.editorGroupService.onDidAddGroup(group => this.registerGroupListeners(group as IEditorGroupView))); + this._register(this.editorsObserver.onDidMostRecentlyActiveEditorsChange(() => this._onDidMostRecentlyActiveEditorsChange.fire())); // Out of workspace file watchers this._register(this.onDidVisibleEditorsChange(() => this.handleVisibleEditorsChange())); diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index f100b353488..fcff4bbe95c 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -251,7 +251,7 @@ class InstallExtensionTask extends AbstractExtensionTask implem constructor( manifest: IExtensionManifest, private readonly extension: URI | IGalleryExtension, - private readonly options: InstallExtensionTaskOptions, + readonly options: InstallExtensionTaskOptions, private readonly webExtensionsScannerService: IWebExtensionsScannerService, private readonly userDataProfilesService: IUserDataProfilesService, ) { diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index f3dc351a3a5..835775b8fbe 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -6,6 +6,7 @@ // THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY. export const allApiProposals = Object.freeze({ + aiRelatedInformation: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts', authGetSessions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authGetSessions.d.ts', authSession: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authSession.d.ts', canonicalUriProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.canonicalUriProvider.d.ts', @@ -39,8 +40,6 @@ export const allApiProposals = Object.freeze({ dropMetadata: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.dropMetadata.d.ts', editSessionIdentityProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.editSessionIdentityProvider.d.ts', editorInsets: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.editorInsets.d.ts', - envCollectionOptions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.envCollectionOptions.d.ts', - envCollectionWorkspace: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.envCollectionWorkspace.d.ts', envShellEvent: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.envShellEvent.d.ts', extensionRuntime: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.extensionRuntime.d.ts', extensionsAny: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.extensionsAny.d.ts', @@ -58,6 +57,7 @@ export const allApiProposals = Object.freeze({ interactiveWindow: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.interactiveWindow.d.ts', ipc: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.ipc.d.ts', languageConfigurationAutoClosingPairs: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.languageConfigurationAutoClosingPairs.d.ts', + mappedEditsProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts', notebookCellExecutionState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookCellExecutionState.d.ts', notebookCodeActions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookCodeActions.d.ts', notebookControllerAffinityHidden: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookControllerAffinityHidden.d.ts', diff --git a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts index 0df7ff16687..743f0a688d0 100644 --- a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts +++ b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts @@ -569,6 +569,12 @@ export const schema: IJSONSchema = { '{Locked="vscode.l10n API"}' ] }, 'The relative path to a folder containing localization (bundle.l10n.*.json) files. Must be specified if you are using the vscode.l10n API.') + }, + pricing: { + type: 'string', + markdownDescription: nls.localize('vscode.extension.pricing', 'The pricing information for the extension. Can be Free (default) or Trial. For more details visit: https://code.visualstudio.com/api/working-with-extensions/publishing-extension#extension-pricing-label'), + enum: ['Free', 'Trial'], + default: 'Free' } } }; diff --git a/src/vs/workbench/services/search/common/search.ts b/src/vs/workbench/services/search/common/search.ts index 1702df60753..6935850b671 100644 --- a/src/vs/workbench/services/search/common/search.ts +++ b/src/vs/workbench/services/search/common/search.ts @@ -19,6 +19,7 @@ import * as paths from 'vs/base/common/path'; import { isCancellationError } from 'vs/base/common/errors'; import { TextSearchCompleteMessageType } from 'vs/workbench/services/search/common/searchExtTypes'; import { isThenable } from 'vs/base/common/async'; +import { ResourceSet } from 'vs/base/common/map'; export { TextSearchCompleteMessageType }; @@ -41,7 +42,8 @@ export const ISearchService = createDecorator('searchService'); */ export interface ISearchService { readonly _serviceBrand: undefined; - textSearch(query: ITextQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void, notebookURIs?: Set): Promise; + textSearch(query: ITextQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): Promise; + textSearchSplitSyncAsync(query: ITextQuery, token?: CancellationToken | undefined, onProgress?: ((result: ISearchProgressItem) => void) | undefined, notebookFilesToIgnore?: ResourceSet, asyncNotebookFilesToIgnore?: Promise): { syncResults: ISearchComplete; asyncResults: Promise }; fileSearch(query: IFileQuery, token?: CancellationToken): Promise; clearCache(cacheKey: string): Promise; registerSearchResultProvider(scheme: string, type: SearchProviderType, provider: ISearchResultProvider): IDisposable; @@ -412,6 +414,9 @@ export interface ISearchConfigurationProperties { defaultViewMode: ViewMode; experimental: { closedNotebookRichContentResults: boolean; + quickAccess: { + preserveInput: boolean; + }; }; } diff --git a/src/vs/workbench/services/search/common/searchService.ts b/src/vs/workbench/services/search/common/searchService.ts index 63b1c192a86..bbabce133c8 100644 --- a/src/vs/workbench/services/search/common/searchService.ts +++ b/src/vs/workbench/services/search/common/searchService.ts @@ -73,37 +73,63 @@ export class SearchService extends Disposable implements ISearchService { }); } - async textSearch(query: ITextQuery, token?: CancellationToken, onProgress?: (item: ISearchProgressItem) => void, notebookURIs?: ResourceSet): Promise { - // Get local results from dirty/untitled - const localResults = this.getLocalResults(query); + async textSearch(query: ITextQuery, token?: CancellationToken, onProgress?: (item: ISearchProgressItem) => void): Promise { + const results = this.textSearchSplitSyncAsync(query, token, onProgress); + const openEditorResults = results.syncResults; + const otherResults = await results.asyncResults; + return { + limitHit: otherResults.limitHit || openEditorResults.limitHit, + results: [...otherResults.results, ...openEditorResults.results], + messages: [...otherResults.messages, ...openEditorResults.messages] + }; + } + + textSearchSplitSyncAsync( + query: ITextQuery, + token?: CancellationToken | undefined, + onProgress?: ((result: ISearchProgressItem) => void) | undefined, + notebookFilesToIgnore?: ResourceSet, + asyncNotebookFilesToIgnore?: Promise + ): { + syncResults: ISearchComplete; + asyncResults: Promise; + } { + // Get open editor results from dirty/untitled + const openEditorResults = this.getOpenEditorResults(query); if (onProgress) { - arrays.coalesce([...localResults.results.values()]).forEach(onProgress); + arrays.coalesce([...openEditorResults.results.values()]).filter(e => !(notebookFilesToIgnore && notebookFilesToIgnore.has(e.resource))).forEach(onProgress); } - const onProviderProgress = (progress: ISearchProgressItem) => { - if (isFileMatch(progress)) { - // Match - if (!localResults.results.has(progress.resource) && !(notebookURIs && notebookURIs.has(progress.resource)) && onProgress) { // don't override local results - onProgress(progress); + const syncResults: ISearchComplete = { + results: arrays.coalesce([...openEditorResults.results.values()]), + limitHit: openEditorResults.limitHit ?? false, + messages: [] + }; + + const getAsyncResults = async () => { + const resolvedAsyncNotebookFilesToIgnore = await asyncNotebookFilesToIgnore ?? new ResourceSet(); + const onProviderProgress = (progress: ISearchProgressItem) => { + if (isFileMatch(progress)) { + // Match + if (!openEditorResults.results.has(progress.resource) && !resolvedAsyncNotebookFilesToIgnore.has(progress.resource) && onProgress) { // don't override open editor results + onProgress(progress); + } + } else if (onProgress) { + // Progress + onProgress(progress); } - } else if (onProgress) { - // Progress - onProgress(progress); - } - if (isProgressMessage(progress)) { - this.logService.debug('SearchService#search', progress.message); - } + if (isProgressMessage(progress)) { + this.logService.debug('SearchService#search', progress.message); + } + }; + return await this.doSearch(query, token, onProviderProgress); }; - const otherResults = await this.doSearch(query, token, onProviderProgress); return { - ...otherResults, - ...{ - limitHit: otherResults.limitHit || localResults.limitHit - }, - results: [...otherResults.results, ...arrays.coalesce([...localResults.results.values()])] + syncResults, + asyncResults: getAsyncResults() }; } @@ -404,8 +430,8 @@ export class SearchService extends Disposable implements ISearchService { } } - private getLocalResults(query: ITextQuery): { results: ResourceMap; limitHit: boolean } { - const localResults = new ResourceMap(uri => this.uriIdentityService.extUri.getComparisonKey(uri)); + private getOpenEditorResults(query: ITextQuery): { results: ResourceMap; limitHit: boolean } { + const openEditorResults = new ResourceMap(uri => this.uriIdentityService.extUri.getComparisonKey(uri)); let limitHit = false; if (query.type === QueryType.Text) { @@ -465,18 +491,18 @@ export class SearchService extends Disposable implements ISearchService { } const fileMatch = new FileMatch(originalResource); - localResults.set(originalResource, fileMatch); + openEditorResults.set(originalResource, fileMatch); const textSearchResults = editorMatchesToTextSearchResults(matches, model, query.previewOptions); fileMatch.results = addContextToEditorMatches(textSearchResults, model, query); } else { - localResults.set(originalResource, null); + openEditorResults.set(originalResource, null); } }); } return { - results: localResults, + results: openEditorResults, limitHit }; } diff --git a/src/vs/workbench/services/semanticSimilarity/common/semanticSimilarityService.ts b/src/vs/workbench/services/semanticSimilarity/common/semanticSimilarityService.ts index ff203430c99..e322503d117 100644 --- a/src/vs/workbench/services/semanticSimilarity/common/semanticSimilarityService.ts +++ b/src/vs/workbench/services/semanticSimilarity/common/semanticSimilarityService.ts @@ -11,8 +11,14 @@ import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/ import { StopWatch } from 'vs/base/common/stopwatch'; import { ILogService } from 'vs/platform/log/common/log'; +/** + * @deprecated Use `IAiRelatedInformationService` instead. + */ export const ISemanticSimilarityService = createDecorator('ISemanticSimilarityService'); +/** + * @deprecated Use `IAiRelatedInformationService` instead. + */ export interface ISemanticSimilarityService { readonly _serviceBrand: undefined; diff --git a/src/vs/workbench/services/sharedProcess/electron-sandbox/sharedProcessService.ts b/src/vs/workbench/services/sharedProcess/electron-sandbox/sharedProcessService.ts index ce810b44b05..fffa5df2feb 100644 --- a/src/vs/workbench/services/sharedProcess/electron-sandbox/sharedProcessService.ts +++ b/src/vs/workbench/services/sharedProcess/electron-sandbox/sharedProcessService.ts @@ -8,6 +8,7 @@ import { IChannel, IServerChannel, getDelayedChannel } from 'vs/base/parts/ipc/c import { ILogService } from 'vs/platform/log/common/log'; import { Disposable } from 'vs/base/common/lifecycle'; import { ISharedProcessService } from 'vs/platform/ipc/electron-sandbox/services'; +import { SharedProcessChannelConnection, SharedProcessRawConnection } from 'vs/platform/sharedProcess/common/sharedProcess'; import { mark } from 'vs/base/common/performance'; import { Barrier, timeout } from 'vs/base/common/async'; import { acquirePort } from 'vs/base/parts/ipc/electron-sandbox/ipc.mp'; @@ -44,7 +45,7 @@ export class SharedProcessService extends Disposable implements ISharedProcessSe // Acquire a message port connected to the shared process mark('code/willConnectSharedProcess'); this.logService.trace('Renderer->SharedProcess#connect: before acquirePort'); - const port = await acquirePort('vscode:createSharedProcessMessageChannel', 'vscode:createSharedProcessMessageChannelResult'); + const port = await acquirePort(SharedProcessChannelConnection.request, SharedProcessChannelConnection.response); mark('code/didConnectSharedProcess'); this.logService.trace('Renderer->SharedProcess#connect: connection established'); @@ -64,4 +65,17 @@ export class SharedProcessService extends Disposable implements ISharedProcessSe registerChannel(channelName: string, channel: IServerChannel): void { this.withSharedProcessConnection.then(connection => connection.registerChannel(channelName, channel)); } + + async createRawConnection(): Promise { + + // Await initialization of the shared process + await this.withSharedProcessConnection; + + // Create a new port to the shared process + this.logService.trace('Renderer->SharedProcess#createRawConnection: before acquirePort'); + const port = await acquirePort(SharedProcessRawConnection.request, SharedProcessRawConnection.response); + this.logService.trace('Renderer->SharedProcess#createRawConnection: connection established'); + + return port; + } } diff --git a/src/vs/workbench/services/statusbar/browser/statusbar.ts b/src/vs/workbench/services/statusbar/browser/statusbar.ts index e38c45d1cf3..2e5abde6fba 100644 --- a/src/vs/workbench/services/statusbar/browser/statusbar.ts +++ b/src/vs/workbench/services/statusbar/browser/statusbar.ts @@ -153,6 +153,9 @@ export interface IStatusbarStyleOverride { readonly border?: ColorIdentifier; } +export type StatusbarEntryKind = 'standard' | 'warning' | 'error' | 'prominent' | 'remote' | 'offline'; +export const StatusbarEntryKinds: StatusbarEntryKind[] = ['standard', 'warning', 'error', 'prominent', 'remote', 'offline']; + /** * A declarative way of describing a status bar entry */ @@ -188,12 +191,16 @@ export interface IStatusbarEntry { readonly tooltip?: string | IMarkdownString | HTMLElement; /** - * An optional color to use for the entry + * An optional color to use for the entry. + * + * @deprecated Use `kind` instead to support themable hover styles. */ readonly color?: string | ThemeColor; /** - * An optional background color to use for the entry + * An optional background color to use for the entry. + * + * @deprecated Use `kind` instead to support themable hover styles. */ readonly backgroundColor?: string | ThemeColor; @@ -215,6 +222,11 @@ export interface IStatusbarEntry { * specified, `syncing` will be used. */ readonly showProgress?: boolean | 'syncing' | 'loading'; + + /** + * The kind of status bar entry. This applies different colors to the entry. + */ + readonly kind?: StatusbarEntryKind; } export interface IStatusbarEntryAccessor extends IDisposable { diff --git a/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts b/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts index b121441fd78..9558ffdd75e 100644 --- a/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts +++ b/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts @@ -63,7 +63,7 @@ export class ThreadedBackgroundTokenizerFactory implements IDisposable { const controllerContainer = this._getWorkerProxy().then((workerProxy) => { if (store.isDisposed || !workerProxy) { return undefined; } - const controllerContainer = { controller: undefined as undefined | TextMateWorkerTokenizerController }; + const controllerContainer = { controller: undefined as undefined | TextMateWorkerTokenizerController, worker: this._worker }; store.add(keepAliveWhenAttached(textModel, () => { const controller = new TextMateWorkerTokenizerController(textModel, workerProxy, this._languageService.languageIdCodec, tokenStore, this._configurationService, maxTokenizationLineLength); controllerContainer.controller = controller; @@ -82,10 +82,12 @@ export class ThreadedBackgroundTokenizerFactory implements IDisposable { store.dispose(); }, requestTokens: async (startLineNumber, endLineNumberExclusive) => { - const controller = (await controllerContainer)?.controller; - if (controller) { - // If there is no controller, the model has been detached in the meantime - controller.requestTokens(startLineNumber, endLineNumberExclusive); + const container = await controllerContainer; + + // If there is no controller, the model has been detached in the meantime. + // Only request the proxy object if the worker is the same! + if (container?.controller && container.worker === this._worker) { + container.controller.requestTokens(startLineNumber, endLineNumberExclusive); } }, reportMismatchingTokens: (lineNumber) => { diff --git a/src/vs/workbench/services/textfile/browser/browserTextFileService.ts b/src/vs/workbench/services/textfile/browser/browserTextFileService.ts index 78957c01afd..188ca299d5f 100644 --- a/src/vs/workbench/services/textfile/browser/browserTextFileService.ts +++ b/src/vs/workbench/services/textfile/browser/browserTextFileService.ts @@ -54,7 +54,7 @@ export class BrowserTextFileService extends AbstractTextFileService { private registerListeners(): void { // Lifecycle - this.lifecycleService.onBeforeShutdown(event => event.veto(this.onBeforeShutdown(), 'veto.textFiles')); + this._register(this.lifecycleService.onBeforeShutdown(event => event.veto(this.onBeforeShutdown(), 'veto.textFiles'))); } private onBeforeShutdown(): boolean { diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts index 45015baa458..f7a87fb1b4b 100644 --- a/src/vs/workbench/services/textfile/browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -89,7 +89,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex private provideDecorations(): void { // Text file model decorations - this.decorationsService.registerDecorationsProvider(new class extends Disposable implements IDecorationsProvider { + const provider = this._register(new class extends Disposable implements IDecorationsProvider { readonly label = localize('textFileModelDecorations', "Text File Model Decorations"); @@ -161,6 +161,8 @@ export abstract class AbstractTextFileService extends Disposable implements ITex return undefined; } }(this.files)); + + this._register(this.decorationsService.registerDecorationsProvider(provider)); } //#endregin diff --git a/src/vs/workbench/services/textfile/common/encoding.ts b/src/vs/workbench/services/textfile/common/encoding.ts index 6675f732b0e..ad67fb4f422 100644 --- a/src/vs/workbench/services/textfile/common/encoding.ts +++ b/src/vs/workbench/services/textfile/common/encoding.ts @@ -6,6 +6,7 @@ import { Readable, ReadableStream, newWriteableStream, listenStream } from 'vs/base/common/stream'; import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer'; import { importAMDNodeModule } from 'vs/amdX'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; export const UTF8 = 'utf8'; export const UTF8_with_bom = 'utf8bom'; @@ -124,6 +125,8 @@ export function toDecodeStream(source: VSBufferReadableStream, options: IDecodeS let decoder: IDecoderStream | undefined = undefined; + const cts = new CancellationTokenSource(); + const createDecoder = async () => { try { @@ -158,14 +161,14 @@ export function toDecodeStream(source: VSBufferReadableStream, options: IDecodeS } catch (error) { // Stop handling anything from the source and target - sourceListener?.dispose(); + cts.cancel(); target.destroy(); reject(error); } }; - const sourceListener = listenStream(source, { + listenStream(source, { onData: async chunk => { // if the decoder is ready, we just write directly @@ -205,7 +208,7 @@ export function toDecodeStream(source: VSBufferReadableStream, options: IDecodeS // end the target with the remainders of the decoder target.end(decoder?.end()); } - }); + }, cts.token); }); } diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 51af0329394..a60dc9a4560 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -290,7 +290,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Unless there are explicit contents provided, it is important that we do not // resolve a model that is dirty or is in the process of saving to prevent data // loss. - if (!options?.contents && (this.dirty || this.saveSequentializer.hasPending())) { + if (!options?.contents && (this.dirty || this.saveSequentializer.isRunning())) { this.trace('resolve() - exit - without resolving because model is dirty or being saved'); return; @@ -767,15 +767,15 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil return; } - // Lookup any running pending save for this versionId and return it if found + // Lookup any running save for this versionId and return it if found // // Scenario: user invoked the save action multiple times quickly for the same contents // while the save was not yet finished to disk // - if (this.saveSequentializer.hasPending(versionId)) { - this.trace(`doSave(${versionId}) - exit - found a pending save for versionId ${versionId}`); + if (this.saveSequentializer.isRunning(versionId)) { + this.trace(`doSave(${versionId}) - exit - found a running save for versionId ${versionId}`); - return this.saveSequentializer.pending; + return this.saveSequentializer.running; } // Return early if not dirty (unless forced) @@ -795,18 +795,18 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Scenario B: save is very slow (e.g. network share) and the user manages to change the buffer and trigger another save // while the first save has not returned yet. // - if (this.saveSequentializer.hasPending()) { + if (this.saveSequentializer.isRunning()) { this.trace(`doSave(${versionId}) - exit - because busy saving`); // Indicate to the save sequentializer that we want to - // cancel the pending operation so that ours can run - // before the pending one finishes. - // Currently this will try to cancel pending save - // participants but never a pending save. - this.saveSequentializer.cancelPending(); + // cancel the running operation so that ours can run + // before the running one finishes. + // Currently this will try to cancel running save + // participants but never a running save. + this.saveSequentializer.cancelRunning(); - // Register this as the next upcoming save and return - return this.saveSequentializer.setNext(() => this.doSave(options)); + // Queue this as the upcoming save and return + return this.saveSequentializer.queue(() => this.doSave(options)); } // Push all edit operations to the undo stack so that the user has a chance to @@ -817,7 +817,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil const saveCancellation = new CancellationTokenSource(); - return this.saveSequentializer.setPending(versionId, (async () => { + return this.saveSequentializer.run(versionId, (async () => { // A save participant can still change the model now and since we are so close to saving // we do not want to trigger another auto save or similar, so we block this @@ -894,13 +894,13 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Clear error flag since we are trying to save again this.inErrorMode = false; - // Save to Disk. We mark the save operation as currently pending with + // Save to Disk. We mark the save operation as currently running with // the latest versionId because it might have changed from a save // participant triggering this.trace(`doSave(${versionId}) - before write()`); const lastResolvedFileStat = assertIsDefined(this.lastResolvedFileStat); const resolvedTextFileEditorModel = this; - return this.saveSequentializer.setPending(versionId, (async () => { + return this.saveSequentializer.run(versionId, (async () => { try { const stat = await this.textFileService.write(lastResolvedFileStat.resource, resolvedTextFileEditorModel.createSnapshot(), { mtime: lastResolvedFileStat.mtime, @@ -1013,14 +1013,14 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil case TextFileEditorModelState.ORPHAN: return this.inOrphanMode; case TextFileEditorModelState.PENDING_SAVE: - return this.saveSequentializer.hasPending(); + return this.saveSequentializer.isRunning(); case TextFileEditorModelState.SAVED: return !this.dirty; } } async joinState(state: TextFileEditorModelState.PENDING_SAVE): Promise { - return this.saveSequentializer.pending; + return this.saveSequentializer.running; } override getLanguageId(this: IResolvedTextFileEditorModel): string; diff --git a/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts b/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts index ab3cb0a0e8a..3dc16d1a46e 100644 --- a/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts +++ b/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts @@ -60,11 +60,15 @@ export class TextFileSaveParticipant extends Disposable { model.textEditorModel?.pushStackElement(); }, () => { // user cancel - cts.dispose(true); + cts.cancel(); + }).finally(() => { + cts.dispose(); }); } override dispose(): void { this.saveParticipants.splice(0, this.saveParticipants.length); + + super.dispose(); } } diff --git a/src/vs/workbench/services/textfile/test/browser/textFileEditorModel.test.ts b/src/vs/workbench/services/textfile/test/browser/textFileEditorModel.test.ts index 7595d417a5f..7ca2a09bfb1 100644 --- a/src/vs/workbench/services/textfile/test/browser/textFileEditorModel.test.ts +++ b/src/vs/workbench/services/textfile/test/browser/textFileEditorModel.test.ts @@ -548,7 +548,7 @@ suite('Files - TextFileEditorModel', () => { test('Update Dirty', async function () { let eventCounter = 0; - const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined); + const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined); model.setDirty(true); assert.ok(!model.isDirty()); // needs to be resolved @@ -638,8 +638,8 @@ suite('Files - TextFileEditorModel', () => { }); test('save() and isDirty() - proper with check for mtimes', async function () { - const input1 = createFileEditorInput(instantiationService, toResource.call(this, '/path/index_async2.txt')); - const input2 = createFileEditorInput(instantiationService, toResource.call(this, '/path/index_async.txt')); + const input1 = disposables.add(createFileEditorInput(instantiationService, toResource.call(this, '/path/index_async2.txt'))); + const input2 = disposables.add(createFileEditorInput(instantiationService, toResource.call(this, '/path/index_async.txt'))); const model1 = await input1.resolve() as TextFileEditorModel; const model2 = await input2.resolve() as TextFileEditorModel; diff --git a/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts b/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts index 93d906d886e..4b745f7af41 100644 --- a/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts +++ b/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts @@ -419,7 +419,8 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IUnt startColumn: 1, endColumn: UntitledTextEditorModel.FIRST_LINE_NAME_CANDIDATE_MAX_LENGTH + 1 // first cap at FIRST_LINE_NAME_CANDIDATE_MAX_LENGTH }) - .trim().replace(/\s+/g, ' '); // normalize whitespaces + .trim().replace(/\s+/g, ' ') // normalize whitespaces + .replace(/\u202E/g, ''); // drop Right-to-Left Override character (#190133) firstLineText = firstLineText.substr(0, getCharContainingOffset( // finally cap at FIRST_LINE_NAME_MAX_LENGTH (grapheme aware #111235) firstLineText, UntitledTextEditorModel.FIRST_LINE_NAME_MAX_LENGTH)[0] diff --git a/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.test.ts b/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.test.ts index c724a93fd1b..935b78a3dfd 100644 --- a/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.test.ts +++ b/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.test.ts @@ -542,10 +542,14 @@ suite('Untitled text editors', () => { assert.strictEqual(input.getName(), '123456789012345678901234567890123456789'); assert.strictEqual(model.name, '123456789012345678901234567890123456789'); - assert.strictEqual(counter, 6); + model.textEditorModel?.setValue('hello\u202Eworld'); // do not allow RTL in names (#190133) + assert.strictEqual(input.getName(), 'helloworld'); + assert.strictEqual(model.name, 'helloworld'); + + assert.strictEqual(counter, 7); model.textEditorModel?.setValue('Hello\nWorld'); - assert.strictEqual(counter, 7); + assert.strictEqual(counter, 8); function createSingleEditOp(text: string, positionLineNumber: number, positionColumn: number, selectionLineNumber: number = positionLineNumber, selectionColumn: number = positionColumn): ISingleEditOperation { const range = new Range( @@ -563,7 +567,7 @@ suite('Untitled text editors', () => { } model.textEditorModel?.applyEdits([createSingleEditOp('hello', 2, 2)]); - assert.strictEqual(counter, 7); // change was not on first line + assert.strictEqual(counter, 8); // change was not on first line input.dispose(); model.dispose(); diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts index cea4e9de5f8..9dc107dd7fb 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts @@ -324,14 +324,15 @@ export class UserDataProfileImportExportService extends Disposable implements IU let result: { name: string; items: ReadonlyArray } | undefined; disposables.add(Event.any(quickPick.onDidCustom, quickPick.onDidAccept)(() => { - if (!quickPick.value) { - quickPick.validationMessage = localize('name required', "Provide a name for the new profile"); + const name = quickPick.value.trim(); + if (!name) { + quickPick.validationMessage = localize('name required', "Profile name is required and must be a non-empty value."); quickPick.severity = Severity.Error; } if (quickPick.validationMessage) { return; } - result = { name: quickPick.value, items: quickPick.selectedItems }; + result = { name, items: quickPick.selectedItems }; quickPick.hide(); quickPick.severity = Severity.Ignore; quickPick.validationMessage = undefined; diff --git a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts index 0668f9e3b6a..d509a21c76c 100644 --- a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts +++ b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts @@ -171,17 +171,19 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat } private async initialize(): Promise { - const authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService); - if (this.currentSessionId === undefined && authenticationSession?.id) { - if (this.environmentService.options?.settingsSyncOptions?.authenticationProvider && this.environmentService.options.settingsSyncOptions.enabled) { - this.currentSessionId = authenticationSession.id; - } + if (isWeb) { + const authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService); + if (this.currentSessionId === undefined && authenticationSession?.id) { + if (this.environmentService.options?.settingsSyncOptions?.authenticationProvider && this.environmentService.options.settingsSyncOptions.enabled) { + this.currentSessionId = authenticationSession.id; + } - // Backward compatibility - else if (this.useWorkbenchSessionId) { - this.currentSessionId = authenticationSession.id; + // Backward compatibility + else if (this.useWorkbenchSessionId) { + this.currentSessionId = authenticationSession.id; + } + this.useWorkbenchSessionId = false; } - this.useWorkbenchSessionId = false; } await this.update(); diff --git a/src/vs/workbench/services/voiceRecognition/electron-sandbox/voiceTranscriptionWorklet.ts b/src/vs/workbench/services/voiceRecognition/electron-sandbox/voiceTranscriptionWorklet.ts new file mode 100644 index 00000000000..47c7baf3433 --- /dev/null +++ b/src/vs/workbench/services/voiceRecognition/electron-sandbox/voiceTranscriptionWorklet.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. + *--------------------------------------------------------------------------------------------*/ + +declare class AudioWorkletProcessor { + + readonly port: MessagePort; + + process(inputs: [Float32Array[]], outputs: [Float32Array[]]): boolean; +} + +class VoiceTranscriptionWorklet extends AudioWorkletProcessor { + + private static readonly BUFFER_TIMESPAN = 1000; + + private startTime: number | undefined = undefined; + private stopped: boolean = false; + + private buffer: Float32Array[] = []; + + private sharedProcessConnection: MessagePort | undefined = undefined; + + constructor() { + super(); + + this.registerListeners(); + } + + private registerListeners() { + this.port.onmessage = event => { + switch (event.data) { + case 'vscode:startVoiceTranscription': { + this.sharedProcessConnection = event.ports[0]; + + this.sharedProcessConnection.onmessage = event => { + if (this.stopped) { + return; + } + + if (typeof event.data === 'string') { + this.port.postMessage(event.data); + } + }; + + this.sharedProcessConnection.start(); + break; + } + + case 'vscode:stopVoiceTranscription': { + this.stopped = true; + + this.sharedProcessConnection?.close(); + this.sharedProcessConnection = undefined; + + break; + } + } + }; + } + + override process(inputs: [Float32Array[]]): boolean { + if (this.startTime === undefined) { + this.startTime = Date.now(); + } + + const inputChannelData = inputs[0][0]; + if ((!(inputChannelData instanceof Float32Array))) { + return !this.stopped; + } + + this.buffer.push(inputChannelData.slice(0)); + + if (Date.now() - this.startTime > VoiceTranscriptionWorklet.BUFFER_TIMESPAN && this.sharedProcessConnection) { + const buffer = this.buffer; + this.buffer = []; + + this.sharedProcessConnection.postMessage(buffer); + + this.startTime = Date.now(); + } + + return !this.stopped; + } +} + +// @ts-ignore +registerProcessor('voice-transcription-worklet', VoiceTranscriptionWorklet); diff --git a/src/vs/workbench/services/voiceRecognition/electron-sandbox/workbenchVoiceRecognitionService.ts b/src/vs/workbench/services/voiceRecognition/electron-sandbox/workbenchVoiceRecognitionService.ts new file mode 100644 index 00000000000..d35dd681f77 --- /dev/null +++ b/src/vs/workbench/services/voiceRecognition/electron-sandbox/workbenchVoiceRecognitionService.ts @@ -0,0 +1,193 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { Emitter, Event } from 'vs/base/common/event'; +import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; +import { DeferredPromise } from 'vs/base/common/async'; +import { FileAccess } from 'vs/base/common/network'; +import { ISharedProcessService } from 'vs/platform/ipc/electron-sandbox/services'; +import { INotificationService } from 'vs/platform/notification/common/notification'; + +export const IWorkbenchVoiceRecognitionService = createDecorator('workbenchVoiceRecognitionService'); + +export interface IWorkbenchVoiceRecognitionOptions { + + /** + * Optional event that is fired when the user cancels the voice recognition. + */ + readonly onDidCancel?: () => void; +} + +export interface IWorkbenchVoiceRecognitionService { + + readonly _serviceBrand: undefined; + + /** + * Starts listening to the microphone transcribing the voice to text. Microphone + * recording starts when the returned promise is resolved. + * + * @param cancellation a cancellation token to stop transcribing and + * listening to the microphone. + */ + transcribe(cancellation: CancellationToken, options?: IWorkbenchVoiceRecognitionOptions): Promise>; +} + +class VoiceTranscriptionWorkletNode extends AudioWorkletNode { + + constructor( + context: BaseAudioContext, + options: AudioWorkletNodeOptions, + private readonly onDidTranscribe: Emitter, + private readonly sharedProcessService: ISharedProcessService + ) { + super(context, 'voice-transcription-worklet', options); + + this.registerListeners(); + } + + private registerListeners(): void { + this.port.onmessage = e => { + if (typeof e.data === 'string') { + this.onDidTranscribe.fire(e.data); + } + }; + } + + async start(token: CancellationToken): Promise { + token.onCancellationRequested(() => this.stop()); + + const sharedProcessConnection = await this.sharedProcessService.createRawConnection(); + + if (token.isCancellationRequested) { + this.stop(); + return; + } + + this.port.postMessage('vscode:startVoiceTranscription', [sharedProcessConnection]); + } + + private stop(): void { + this.port.postMessage('vscode:stopVoiceTranscription'); + this.disconnect(); + } +} + +export class WorkbenchVoiceRecognitionService implements IWorkbenchVoiceRecognitionService { + + declare readonly _serviceBrand: undefined; + + private static readonly AUDIO_SAMPLING_RATE = 16000; + private static readonly AUDIO_BIT_DEPTH = 16; + private static readonly AUDIO_CHANNELS = 1; + + constructor( + @IProgressService private readonly progressService: IProgressService, + @ISharedProcessService private readonly sharedProcessService: ISharedProcessService, + @INotificationService private readonly notificationService: INotificationService + ) { } + + async transcribe(cancellation: CancellationToken, options?: IWorkbenchVoiceRecognitionOptions): Promise> { + const cts = new CancellationTokenSource(cancellation); + + const onDidTranscribe = new Emitter(); + cts.token.onCancellationRequested(() => { + onDidTranscribe.dispose(); + options?.onDidCancel?.(); + }); + + await this.doTranscribe(onDidTranscribe, cts); + + return onDidTranscribe.event; + } + + private doTranscribe(onDidTranscribe: Emitter, cts: CancellationTokenSource): Promise { + const recordingReady = new DeferredPromise(); + cts.token.onCancellationRequested(() => recordingReady.complete()); + + this.progressService.withProgress({ + location: ProgressLocation.Window, + title: localize('voiceTranscription', "Voice Transcription"), + cancellable: true + }, async progress => { + const recordingDone = new DeferredPromise(); + try { + progress.report({ message: localize('voiceTranscriptionGettingReady', "Getting microphone ready...") }); + + const microphoneDevice = await navigator.mediaDevices.getUserMedia({ + audio: { + sampleRate: WorkbenchVoiceRecognitionService.AUDIO_SAMPLING_RATE, + sampleSize: WorkbenchVoiceRecognitionService.AUDIO_BIT_DEPTH, + channelCount: WorkbenchVoiceRecognitionService.AUDIO_CHANNELS, + autoGainControl: true, + noiseSuppression: true + } + }); + + if (cts.token.isCancellationRequested) { + return; + } + + const audioContext = new AudioContext({ + sampleRate: WorkbenchVoiceRecognitionService.AUDIO_SAMPLING_RATE, + latencyHint: 'interactive' + }); + + const microphoneSource = audioContext.createMediaStreamSource(microphoneDevice); + + cts.token.onCancellationRequested(() => { + try { + for (const track of microphoneDevice.getTracks()) { + track.stop(); + } + + microphoneSource.disconnect(); + audioContext.close(); + } finally { + recordingDone.complete(); + } + }); + + await audioContext.audioWorklet.addModule(FileAccess.asBrowserUri('vs/workbench/services/voiceRecognition/electron-sandbox/voiceTranscriptionWorklet.js').toString(true)); + + if (cts.token.isCancellationRequested) { + return; + } + + const voiceTranscriptionTarget = new VoiceTranscriptionWorkletNode(audioContext, { + channelCount: WorkbenchVoiceRecognitionService.AUDIO_CHANNELS, + channelCountMode: 'explicit' + }, onDidTranscribe, this.sharedProcessService); + await voiceTranscriptionTarget.start(cts.token); + + if (cts.token.isCancellationRequested) { + return; + } + + microphoneSource.connect(voiceTranscriptionTarget); + + progress.report({ message: localize('voiceTranscriptionRecording', "Recording from microphone...") }); + recordingReady.complete(); + + return recordingDone.p; + } catch (error) { + this.notificationService.error(localize('voiceTranscriptionError', "Voice transcription failed: {0}", error.message)); + + recordingReady.error(error); + recordingDone.error(error); + } + }, () => { + cts.cancel(); + }); + + return recordingReady.p; + } +} + +// Register Service +registerSingleton(IWorkbenchVoiceRecognitionService, WorkbenchVoiceRecognitionService, InstantiationType.Delayed); diff --git a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts index d3fff96bb86..f96b3de0015 100644 --- a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts +++ b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts @@ -433,7 +433,7 @@ export class StoredFileWorkingCopy extend // Unless there are explicit contents provided, it is important that we do not // resolve a working copy that is dirty or is in the process of saving to prevent // data loss. - if (!options?.contents && (this.dirty || this.saveSequentializer.hasPending())) { + if (!options?.contents && (this.dirty || this.saveSequentializer.isRunning())) { this.trace('resolve() - exit - without resolving because file working copy is dirty or being saved'); return; @@ -851,15 +851,15 @@ export class StoredFileWorkingCopy extend return; } - // Lookup any running pending save for this versionId and return it if found + // Lookup any running save for this versionId and return it if found // // Scenario: user invoked the save action multiple times quickly for the same contents // while the save was not yet finished to disk // - if (this.saveSequentializer.hasPending(versionId)) { - this.trace(`doSave(${versionId}) - exit - found a pending save for versionId ${versionId}`); + if (this.saveSequentializer.isRunning(versionId)) { + this.trace(`doSave(${versionId}) - exit - found a running save for versionId ${versionId}`); - return this.saveSequentializer.pending; + return this.saveSequentializer.running; } // Return early if not dirty (unless forced) @@ -879,20 +879,20 @@ export class StoredFileWorkingCopy extend // Scenario B: save is very slow (e.g. network share) and the user manages to change the working copy and trigger another save // while the first save has not returned yet. // - if (this.saveSequentializer.hasPending()) { + if (this.saveSequentializer.isRunning()) { this.trace(`doSave(${versionId}) - exit - because busy saving`); // Indicate to the save sequentializer that we want to - // cancel the pending operation so that ours can run - // before the pending one finishes. - // Currently this will try to cancel pending save - // participants and pending snapshots from the + // cancel the running operation so that ours can run + // before the running one finishes. + // Currently this will try to cancel running save + // participants and running snapshots from the // save operation, but not the actual save which does // not support cancellation yet. - this.saveSequentializer.cancelPending(); + this.saveSequentializer.cancelRunning(); - // Register this as the next upcoming save and return - return this.saveSequentializer.setNext(() => this.doSave(options)); + // Queue this as the upcoming save and return + return this.saveSequentializer.queue(() => this.doSave(options)); } // Push all edit operations to the undo stack so that the user has a chance to @@ -903,7 +903,7 @@ export class StoredFileWorkingCopy extend const saveCancellation = new CancellationTokenSource(); - return this.saveSequentializer.setPending(versionId, (async () => { + return this.saveSequentializer.run(versionId, (async () => { // A save participant can still change the working copy now // and since we are so close to saving we do not want to trigger @@ -975,13 +975,13 @@ export class StoredFileWorkingCopy extend // Clear error flag since we are trying to save again this.inErrorMode = false; - // Save to Disk. We mark the save operation as currently pending with + // Save to Disk. We mark the save operation as currently running with // the latest versionId because it might have changed from a save // participant triggering this.trace(`doSave(${versionId}) - before write()`); const lastResolvedFileStat = assertIsDefined(this.lastResolvedFileStat); const resolvedFileWorkingCopy = this; - return this.saveSequentializer.setPending(versionId, (async () => { + return this.saveSequentializer.run(versionId, (async () => { try { const writeFileOptions: IWriteFileOptions = { mtime: lastResolvedFileStat.mtime, @@ -1256,14 +1256,14 @@ export class StoredFileWorkingCopy extend case StoredFileWorkingCopyState.ORPHAN: return this.isOrphaned(); case StoredFileWorkingCopyState.PENDING_SAVE: - return this.saveSequentializer.hasPending(); + return this.saveSequentializer.isRunning(); case StoredFileWorkingCopyState.SAVED: return !this.dirty; } } async joinState(state: StoredFileWorkingCopyState.PENDING_SAVE): Promise { - return this.saveSequentializer.pending; + return this.saveSequentializer.running; } //#endregion diff --git a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts index 18be856eb47..11bddb67625 100644 --- a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts +++ b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts @@ -69,5 +69,7 @@ export class StoredFileWorkingCopySaveParticipant extends Disposable { override dispose(): void { this.saveParticipants.splice(0, this.saveParticipants.length); + + super.dispose(); } } diff --git a/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts b/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts index e75246b8b83..f3f4dd8f05e 100644 --- a/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts +++ b/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts @@ -46,5 +46,7 @@ export class WorkingCopyFileOperationParticipant extends Disposable { override dispose(): void { this.participants.clear(); + + super.dispose(); } } diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 0fffe75c46f..c566bc46401 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -283,15 +283,16 @@ export function workbenchInstantiationService( instantiationService.stub(IUndoRedoService, instantiationService.createInstance(UndoRedoService)); const themeService = new TestThemeService(); instantiationService.stub(IThemeService, themeService); - instantiationService.stub(ILanguageConfigurationService, new TestLanguageConfigurationService()); + instantiationService.stub(ILanguageConfigurationService, disposables.add(new TestLanguageConfigurationService())); instantiationService.stub(IModelService, disposables.add(instantiationService.createInstance(ModelService))); const fileService = overrides?.fileService ? overrides.fileService(instantiationService) : new TestFileService(); instantiationService.stub(IFileService, fileService); const uriIdentityService = new UriIdentityService(fileService); + disposables.add(uriIdentityService); instantiationService.stub(IFilesConfigurationService, disposables.add(new TestFilesConfigurationService(contextKeyService, configService, workspaceContextService, environmentService, uriIdentityService, fileService))); instantiationService.stub(IUriIdentityService, uriIdentityService); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, new NullLogService())); - instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, disposables.add(new UserDataProfilesService(environmentService, fileService, uriIdentityService, new NullLogService()))); + instantiationService.stub(IUserDataProfileService, disposables.add(new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService))); instantiationService.stub(IWorkingCopyBackupService, overrides?.workingCopyBackupService ? overrides?.workingCopyBackupService(instantiationService) : new TestWorkingCopyBackupService()); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(INotificationService, new TestNotificationService()); @@ -305,7 +306,7 @@ export function workbenchInstantiationService( instantiationService.stub(ITextFileService, overrides?.textFileService ? overrides.textFileService(instantiationService) : disposables.add(instantiationService.createInstance(TestTextFileService))); instantiationService.stub(IHostService, instantiationService.createInstance(TestHostService)); instantiationService.stub(ITextModelService, disposables.add(instantiationService.createInstance(TextModelResolverService))); - instantiationService.stub(ILoggerService, new TestLoggerService(TestEnvironmentService.logsHome)); + instantiationService.stub(ILoggerService, disposables.add(new TestLoggerService(TestEnvironmentService.logsHome))); instantiationService.stub(ILogService, new NullLogService()); const editorGroupService = new TestEditorGroupsService([new TestEditorGroupView(0)]); instantiationService.stub(IEditorGroupsService, editorGroupService); @@ -314,10 +315,10 @@ export function workbenchInstantiationService( instantiationService.stub(IEditorService, editorService); instantiationService.stub(IWorkingCopyEditorService, disposables.add(instantiationService.createInstance(WorkingCopyEditorService))); instantiationService.stub(IEditorResolverService, disposables.add(instantiationService.createInstance(EditorResolverService))); - const textEditorService = overrides?.textEditorService ? overrides.textEditorService(instantiationService) : instantiationService.createInstance(TextEditorService); + const textEditorService = overrides?.textEditorService ? overrides.textEditorService(instantiationService) : disposables.add(instantiationService.createInstance(TextEditorService)); instantiationService.stub(ITextEditorService, textEditorService); instantiationService.stub(ICodeEditorService, disposables.add(new CodeEditorService(editorService, themeService, configService))); - instantiationService.stub(IPaneCompositePartService, new TestPaneCompositeService()); + instantiationService.stub(IPaneCompositePartService, disposables.add(new TestPaneCompositeService())); instantiationService.stub(IListService, new TestListService()); const hoverService = instantiationService.stub(IHoverService, instantiationService.createInstance(TestHoverService)); instantiationService.stub(IQuickInputService, disposables.add(new QuickInputService(configService, instantiationService, keybindingService, contextKeyService, themeService, layoutService, hoverService))); diff --git a/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts index 45fa3e437b7..1a40dc62bd5 100644 --- a/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts @@ -51,6 +51,8 @@ export class TestSharedProcessService implements ISharedProcessService { declare readonly _serviceBrand: undefined; + createRawConnection(): never { throw new Error('Not Implemented'); } + getChannel(channelName: string): any { return undefined; } registerChannel(channelName: string, channel: any): void { } diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index a52b2b4c274..1f6253a29b6 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -68,6 +68,8 @@ import 'vs/workbench/services/configuration/common/jsonEditingService'; import 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; import 'vs/workbench/services/editor/browser/editorService'; import 'vs/workbench/services/editor/browser/editorResolverService'; +import 'vs/workbench/services/aiEmbeddingVector/common/aiEmbeddingVectorService'; +import 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformationService'; import 'vs/workbench/services/history/browser/historyService'; import 'vs/workbench/services/activity/browser/activityService'; import 'vs/workbench/services/keybinding/browser/keybindingService'; @@ -226,6 +228,9 @@ import 'vs/workbench/contrib/markers/browser/markers.contribution'; // Merge Editor import 'vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution'; +// Mapped Edits +import 'vs/workbench/contrib/mappedEdits/common/mappedEdits.contribution'; + // Commands import 'vs/workbench/contrib/commands/common/commands.contribution'; diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index e943de4afff..1e429387e2d 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -77,6 +77,7 @@ import 'vs/workbench/services/environment/electron-sandbox/shellEnvironmentServi import 'vs/workbench/services/integrity/electron-sandbox/integrityService'; import 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupService'; import 'vs/workbench/services/checksum/electron-sandbox/checksumService'; +import 'vs/workbench/services/voiceRecognition/electron-sandbox/workbenchVoiceRecognitionService'; import 'vs/platform/remote/electron-sandbox/sharedProcessTunnelService'; import 'vs/workbench/services/tunnel/electron-sandbox/tunnelService'; import 'vs/platform/diagnostics/electron-sandbox/diagnosticsService'; @@ -169,6 +170,9 @@ import 'vs/workbench/contrib/mergeEditor/electron-sandbox/mergeEditor.contributi // Remote Tunnel import 'vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution'; +// Chat +import 'vs/workbench/contrib/chat/electron-sandbox/chat.contribution'; + //#endregion diff --git a/src/vscode-dts/README.md b/src/vscode-dts/README.md index a69e5eb65e1..9b3640d9208 100644 --- a/src/vscode-dts/README.md +++ b/src/vscode-dts/README.md @@ -1,18 +1,17 @@ -## vscode-dts +# vscode-dts This is the place for the stable API and for API proposals. - -### Consume a proposal +## Consume a proposal 1. find a proposal you are interested in 1. add its name to your extensions `package.json#enabledApiProposals` property 1. run `npx vscode-dts dev` to download the `d.ts` files into your project 1. don't forget that extension using proposed API cannot be published -1. learn more here: https://code.visualstudio.com/api/advanced-topics/using-proposed-api +1. learn more here: -### Add a new proposal +## Add a new proposal 1. create a _new_ file in this directory, its name must follow this pattern `vscode.proposed.[a-zA-Z]+.d.ts` 1. creating the proposal-file will automatically update `src/vs/workbench/services/extensions/common/extensionsApiProposals.ts` (make sure to run `yarn watch`) diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index db7d29f3b1b..d440e2d2fc1 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -7185,10 +7185,10 @@ declare module 'vscode' { readonly extensionPath: string; /** - * Gets the extension's environment variable collection for this workspace, enabling changes - * to be applied to terminal environment variables. + * Gets the extension's global environment variable collection for this workspace, enabling changes to be + * applied to terminal environment variables. */ - readonly environmentVariableCollection: EnvironmentVariableCollection; + readonly environmentVariableCollection: GlobalEnvironmentVariableCollection; /** * Get the absolute path of a resource contained in the extension. @@ -11334,6 +11334,23 @@ declare module 'vscode' { Prepend = 3 } + /** + * Options applied to the mutator. + */ + export interface EnvironmentVariableMutatorOptions { + /** + * Apply to the environment just before the process is created. Defaults to false. + */ + applyAtProcessCreation?: boolean; + + /** + * Apply to the environment in the shell integration script. Note that this _will not_ apply + * the mutator if shell integration is disabled or not working for some reason. Defaults to + * false. + */ + applyAtShellIntegration?: boolean; + } + /** * A type of mutation and its value to be applied to an environment variable. */ @@ -11347,6 +11364,11 @@ declare module 'vscode' { * The value to use for the variable. */ readonly value: string; + + /** + * Options applied to the mutator. + */ + readonly options: EnvironmentVariableMutatorOptions; } /** @@ -11376,8 +11398,10 @@ declare module 'vscode' { * * @param variable The variable to replace. * @param value The value to replace the variable with. + * @param options Options applied to the mutator, when no options are provided this will + * default to `{ applyAtProcessCreation: true }`. */ - replace(variable: string, value: string): void; + replace(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void; /** * Append a value to an environment variable. @@ -11387,8 +11411,10 @@ declare module 'vscode' { * * @param variable The variable to append to. * @param value The value to append to the variable. + * @param options Options applied to the mutator, when no options are provided this will + * default to `{ applyAtProcessCreation: true }`. */ - append(variable: string, value: string): void; + append(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void; /** * Prepend a value to an environment variable. @@ -11398,8 +11424,10 @@ declare module 'vscode' { * * @param variable The variable to prepend. * @param value The value to prepend to the variable. + * @param options Options applied to the mutator, when no options are provided this will + * default to `{ applyAtProcessCreation: true }`. */ - prepend(variable: string, value: string): void; + prepend(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void; /** * Gets the mutator that this collection applies to a variable, if any. @@ -11429,6 +11457,31 @@ declare module 'vscode' { clear(): void; } + export interface GlobalEnvironmentVariableCollection extends EnvironmentVariableCollection { + /** + * Gets scope-specific environment variable collection for the extension. This enables alterations to + * terminal environment variables solely within the designated scope, and is applied in addition to (and + * after) the global collection. + * + * Each object obtained through this method is isolated and does not impact objects for other scopes, + * including the global collection. + * + * @param scope The scope to which the environment variable collection applies to. + * + * If a scope parameter is omitted, collection applicable to all relevant scopes for that parameter is + * returned. For instance, if the 'workspaceFolder' parameter is not specified, the collection that applies + * across all workspace folders will be returned. + */ + getScoped(scope: EnvironmentVariableScope): EnvironmentVariableCollection; + } + + export type EnvironmentVariableScope = { + /** + * Any specific workspace folder to get collection for. + */ + workspaceFolder?: WorkspaceFolder; + }; + /** * A location in the editor at which progress information can be shown. It depends on the * location how progress is visually represented. diff --git a/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts b/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts new file mode 100644 index 00000000000..e5e28653cec --- /dev/null +++ b/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + // https://github.com/microsoft/vscode/issues/190909 + + export enum RelatedInformationType { + SymbolInformation = 1, + CommandInformation = 2, + SearchInformation = 3, + SettingInformation = 4 + } + + interface RelatedInformationBaseResult { + type: RelatedInformationType; + weight: number; + } + + // TODO: Symbols and Search + + export interface CommandInformationResult extends RelatedInformationBaseResult { + type: RelatedInformationType.CommandInformation; + command: string; + } + + export interface SettingInformationResult extends RelatedInformationBaseResult { + type: RelatedInformationType.SettingInformation; + setting: string; + } + + export type RelatedInformationResult = CommandInformationResult | SettingInformationResult; + + export interface RelatedInformationProvider { + provideRelatedInformation(query: string, token: CancellationToken): ProviderResult; + } + + export interface EmbeddingVectorProvider { + provideEmbeddingVector(strings: string[], token: CancellationToken): ProviderResult; + } + + export namespace ai { + export function getRelatedInformation(query: string, types: RelatedInformationType[], token: CancellationToken): Thenable; + export function registerRelatedInformationProvider(type: RelatedInformationType, provider: RelatedInformationProvider): Disposable; + export function registerEmbeddingVectorProvider(model: string, provider: EmbeddingVectorProvider): Disposable; + } +} diff --git a/src/vscode-dts/vscode.proposed.envCollectionOptions.d.ts b/src/vscode-dts/vscode.proposed.envCollectionOptions.d.ts deleted file mode 100644 index d25a92725a4..00000000000 --- a/src/vscode-dts/vscode.proposed.envCollectionOptions.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -declare module 'vscode' { - - // https://github.com/microsoft/vscode/issues/179476 - - /** - * Options applied to the mutator. - */ - export interface EnvironmentVariableMutatorOptions { - /** - * Apply to the environment just before the process is created. - * - * Defaults to true. - */ - applyAtProcessCreation?: boolean; - - /** - * Apply to the environment in the shell integration script. Note that this _will not_ apply - * the mutator if shell integration is disabled or not working for some reason. - * - * Defaults to false. - */ - applyAtShellIntegration?: boolean; - } - - /** - * A type of mutation and its value to be applied to an environment variable. - */ - export interface EnvironmentVariableMutator { - /** - * Options applied to the mutator. - */ - readonly options: EnvironmentVariableMutatorOptions; - } - - export interface EnvironmentVariableCollection extends Iterable<[variable: string, mutator: EnvironmentVariableMutator]> { - /** - * @param options Options applied to the mutator. - */ - replace(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void; - - /** - * @param options Options applied to the mutator. - */ - append(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void; - - /** - * @param options Options applied to the mutator. - */ - prepend(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void; - } -} diff --git a/src/vscode-dts/vscode.proposed.envCollectionWorkspace.d.ts b/src/vscode-dts/vscode.proposed.envCollectionWorkspace.d.ts deleted file mode 100644 index 73bd11df4e2..00000000000 --- a/src/vscode-dts/vscode.proposed.envCollectionWorkspace.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -declare module 'vscode' { - - // https://github.com/microsoft/vscode/issues/171173 - - export interface ExtensionContext { - /** - * Gets the extension's environment variable collection for this workspace, enabling changes - * to be applied to terminal environment variables. - * - * @deprecated Use {@link getEnvironmentVariableCollection} instead. - */ - readonly environmentVariableCollection: EnvironmentVariableCollection; - /** - * Gets the extension's environment variable collection for this scope, enabling changes - * to be applied to terminal environment variables. - * - * @param scope The scope to which the environment variable collection applies to. - */ - getEnvironmentVariableCollection(scope?: EnvironmentVariableScope): EnvironmentVariableCollection; - } - - export type EnvironmentVariableScope = { - /** - * Any specific workspace folder to get collection for. If unspecified, collection applicable to all workspace folders is returned. - */ - workspaceFolder?: WorkspaceFolder; - }; -} diff --git a/src/vscode-dts/vscode.proposed.interactive.d.ts b/src/vscode-dts/vscode.proposed.interactive.d.ts index 382afeb8277..8ec16060be1 100644 --- a/src/vscode-dts/vscode.proposed.interactive.d.ts +++ b/src/vscode-dts/vscode.proposed.interactive.d.ts @@ -121,7 +121,7 @@ declare module 'vscode' { } export interface InteractiveProgressContent { - content: string; + content: string | MarkdownString; } export interface InteractiveProgressId { diff --git a/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts b/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts new file mode 100644 index 00000000000..9d05e467fd9 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts @@ -0,0 +1,48 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + export interface RelatedContextItem { + readonly uri: Uri; + readonly range: Range; + } + + export interface MappedEditsContext { + selections: Selection[]; + + /** + * If there's no context, the array should be empty. It's also empty until we figure out how to compute this or retrieve from an extension (eg, copilot chat) + * + * TODO: it was suggested initially to be sorted from highest priority to lowest. How would it look like? + */ + related: RelatedContextItem[]; + } + + /** + * Interface for providing mapped edits for a given document. + */ + export interface MappedEditsProvider { + /** + * Provide mapped edits for a given document. + * @param document The document to provide mapped edits for. + * @param codeBlocks Code blocks that come from an LLM's reply. + * "Insert at cursor" in the panel chat only sends one edit that the user clicks on, but inline chat can send multiple blocks and let the lang server decide what to do with them. + * @param context The context for providing mapped edits. + * @param token A cancellation token. + * @returns A provider result of text edits. + */ + provideMappedEdits( + document: TextDocument, + codeBlocks: string[], + context: MappedEditsContext, + token: CancellationToken + ): ProviderResult; + } + + namespace chat { + export function registerMappedEditsProvider(documentSelector: DocumentSelector, provider: MappedEditsProvider): Disposable; + } +} diff --git a/test/README.md b/test/README.md index 80cf9d92912..1e4d114dce5 100644 --- a/test/README.md +++ b/test/README.md @@ -3,6 +3,7 @@ ## Contents This folder contains the various test runners for VSCode. Please refer to the documentation within for how to run them: + * `unit`: our suite of unit tests ([README](unit/README.md)) * `integration`: our suite of API tests ([README](integration/browser/README.md)) * `smoke`: our suite of automated UI tests ([README](smoke/README.md)) diff --git a/test/integration/browser/README.md b/test/integration/browser/README.md index 34107241f8e..8b25994564d 100644 --- a/test/integration/browser/README.md +++ b/test/integration/browser/README.md @@ -21,7 +21,7 @@ All integration tests run in a browser instance as specified by the command line Add the `--debug` flag to see a browser window with the tests running. -**Note**: you can enable verbose logging of playwright library by setting a `DEBUG` environment variable before running the tests (https://playwright.dev/docs/debug#verbose-api-logs) +**Note**: you can enable verbose logging of playwright library by setting a `DEBUG` environment variable before running the tests () ## Debug diff --git a/test/monaco/README.md b/test/monaco/README.md index 68bb7051ce8..e55338934f2 100644 --- a/test/monaco/README.md +++ b/test/monaco/README.md @@ -4,10 +4,10 @@ This directory contains scripts that are used to smoke test the Monaco Editor di ## Setup & Bundle - $test/monaco> yarn - $test/monaco> yarn run bundle + $test/monaco> yarn + $test/monaco> yarn run bundle ## Compile and run tests - $test/monaco> yarn run compile - $test/monaco> yarn test + $test/monaco> yarn run compile + $test/monaco> yarn test diff --git a/test/smoke/Audit.md b/test/smoke/Audit.md index 4ec76567e9c..fd8913b44e2 100644 --- a/test/smoke/Audit.md +++ b/test/smoke/Audit.md @@ -1,13 +1,15 @@ # VS Code Smoke Tests Failures History + This file contains a history of smoke test failures which could be avoided if particular techniques were used in the test (e.g. binding test elements with HTML5 `data-*` attribute). To better understand what can be employed in smoke test to ensure its stability, it is important to understand patterns that led to smoke test breakage. This markdown is a result of work on [this issue](https://github.com/microsoft/vscode/issues/27906). -# Log -1. This following change led to the smoke test failure because DOM element's attribute `a[title]` was changed: - [eac49a3](https://github.com/microsoft/vscode/commit/eac49a321b84cb9828430e9dcd3f34243a3480f7) +## Log - This attribute was used in the smoke test to grab the contents of SCM part in status bar: - [0aec2d6](https://github.com/microsoft/vscode/commit/0aec2d6838b5e65cc74c33b853ffbd9fa191d636) +1. This following change led to the smoke test failure because DOM element's attribute `a[title]` was changed: + [eac49a3](https://github.com/microsoft/vscode/commit/eac49a321b84cb9828430e9dcd3f34243a3480f7) + + This attribute was used in the smoke test to grab the contents of SCM part in status bar: + [0aec2d6](https://github.com/microsoft/vscode/commit/0aec2d6838b5e65cc74c33b853ffbd9fa191d636) 2. To be continued... diff --git a/test/smoke/README.md b/test/smoke/README.md index ffef4c28339..9b5eb6282b4 100644 --- a/test/smoke/README.md +++ b/test/smoke/README.md @@ -2,7 +2,7 @@ Make sure you are on **Node v12.x**. -### Quick Overview +## Quick Overview ```bash # Build extensions in the VS Code repo (if needed) @@ -57,7 +57,7 @@ xattr -d com.apple.quarantine - `-f PATTERN` (alias `-g PATTERN`) filters the tests to be run. You can also use pretty much any mocha argument; - `--headless` will run playwright in headless mode when `--web` is used. -**Note**: you can enable verbose logging of playwright library by setting a `DEBUG` environment variable before running the tests (https://playwright.dev/docs/debug#verbose-api-logs), for example to `pw:browser`. +**Note**: you can enable verbose logging of playwright library by setting a `DEBUG` environment variable before running the tests (), for example to `pw:browser`. ### Develop diff --git a/test/unit/README.md b/test/unit/README.md index 58d569d571f..154f1cf0ad0 100644 --- a/test/unit/README.md +++ b/test/unit/README.md @@ -33,10 +33,10 @@ Unit tests from layers `common` and `browser` are run inside `chromium`, `webkit The following command will create a `coverage` folder in the `.build` folder at the root of the workspace: -**OS X and Linux** +### OS X and Linux ./scripts/test.sh --coverage -**Windows** +### Windows scripts\test --coverage diff --git a/yarn.lock b/yarn.lock index b2b8a437cc0..582d6e845a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10075,10 +10075,10 @@ typescript@^4.7.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== -typescript@^5.3.0-dev.20230816: - version "5.3.0-dev.20230816" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.0-dev.20230816.tgz#409982c629164811db1eb62b365ed2e1b526458d" - integrity sha512-iEOudrx61DsbJn+z2bVX+/FldF7ILAuGwQYO2EvF4F33Q8DUV0KSkiikxUB83VVH8ExkwQHVNdtkr16wd2V71w== +typescript@^5.3.0-dev.20230824: + version "5.3.0-dev.20230824" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.0-dev.20230824.tgz#14fc65c14c588363c0d290dbbbda8ae0968fd95b" + integrity sha512-iiUWxGibzrRHEBLDJfVymsvpPKflf3cMrw0oQTMQoguFS2ikNlVlfQWAsYeHqGpRQc77nSQkzsE9rAHNHqvIjw== typical@^4.0.0: version "4.0.0" @@ -10759,45 +10759,45 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" -xterm-addon-canvas@0.5.0-beta.9: - version "0.5.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.9.tgz#d4a9536cf586f78a54527751e03abf6445613886" - integrity sha512-AMyFctHbIWx0aLcACINuZqFFNoz4ndGtIAb4pQguIl9t8r+2otiV11MY4FJmPM0kUzEzoLWzVFJaGxOzykCWuw== +xterm-addon-canvas@0.5.0-beta.22: + version "0.5.0-beta.22" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.5.0-beta.22.tgz#513f0c2b7cf96073f47627b27e8965c1b1a22431" + integrity sha512-9F6ZI0DMRgffVfHkLkDwl5n8VscvCaV10tWI3skXOX7Y7Aws6OEeglkOPoU3IllofCU792kHKM4pPoToUxTltg== -xterm-addon-image@0.6.0-beta.2: - version "0.6.0-beta.2" - resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.2.tgz#04c5ea11c89032b01b577b37f891109168ed0b09" - integrity sha512-58d1mqIpJwq8Zy/a/QM8JVuA1g5SceG8UvLoj9T6r+2XIktka6GK2oS66Fmo+0MP0s0HDPy+yJtl8lHY6UyzHw== +xterm-addon-image@0.6.0-beta.14: + version "0.6.0-beta.14" + resolved "https://registry.yarnpkg.com/xterm-addon-image/-/xterm-addon-image-0.6.0-beta.14.tgz#75fc3f824123183a4bbb5306e22f8b2c6966b0a6" + integrity sha512-D5Gh5JTKhHaPt1KwQNf6diF37KA4eToJw3XId1wy62tWmSqfq+QflhOGTfd+SnSQYCktU05ETzM+0tncIU62pQ== -xterm-addon-search@0.13.0-beta.8: - version "0.13.0-beta.8" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.8.tgz#90bc70bff87cd7e4f540cce51d9f968f04d5c0ef" - integrity sha512-Hlocg6gGvKAs4eRTW78wTtVqaOEurweJjdyPDjr7KrzwlEEsASsUXJaB2+vgsyTFKuYnCuLrp5u369jck993GQ== +xterm-addon-search@0.13.0-beta.20: + version "0.13.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0-beta.20.tgz#8ddd0513e2a70fcefa325722100d2e1bfaf3b9cb" + integrity sha512-wrx6187cJ1UenGL6ZeYv3jFvRPhhENTfbC+Hv1Fnww8LmsKhcj+0+Pm6yInNjX/9hNVsNzdqKyqNeEMoykyoyA== -xterm-addon-serialize@0.11.0-beta.8: - version "0.11.0-beta.8" - resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.11.0-beta.8.tgz#343357aad7c549a37aacac2fb19692b1c2fd69cd" - integrity sha512-1jNrX+Y8dorWtjMvz02mRUP+ahqQ4STO0lYlKe8m06p+NYuFk24CylnPZFuBgk91OUU3RAdl4glaKh5M4f0/Zw== +xterm-addon-serialize@0.11.0-beta.20: + version "0.11.0-beta.20" + resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.11.0-beta.20.tgz#e879b34d214761403f1081833f9221c6903bf0c3" + integrity sha512-OXnC1SATaz7kEFjFWhyv9MJaXi8yHdPjazpGLNi11h33CRTKtCQiqqPBHU87dztnXmpEX6Jw0/jr3zlyXuAmnw== -xterm-addon-unicode11@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.5.0.tgz#41c0d96acc1e3bb6c6596eee64e163b6bca74be7" - integrity sha512-Jm4/g4QiTxiKiTbYICQgC791ubhIZyoIwxAIgOW8z8HWFNY+lwk+dwaKEaEeGBfM48Vk8fklsUW9u/PlenYEBg== +xterm-addon-unicode11@0.6.0-beta.12: + version "0.6.0-beta.12" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0-beta.12.tgz#ac6df9d635325dc692e4c602e74a2fc27a09405c" + integrity sha512-9wWWf/5nFafYgq0pn9EgAWnXaXGleVxfjNOqavpLRYFv0nw42QbaYyGvnGcxyYHM5Aqx/8rYE/DDVWZBqQZdYA== -xterm-addon-webgl@0.16.0-beta.16: - version "0.16.0-beta.16" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.16.tgz#2c31308f8c7f636576720adca529297f8fff3224" - integrity sha512-k0ZSwpBVtxXaqUc29CmlfFgIK7LEYAmwcDC3QVp2ESZo2JHYuQrWFpImjbzbYu0ON6qqcfbX8SnbzRid/XfGUg== +xterm-addon-webgl@0.16.0-beta.30: + version "0.16.0-beta.30" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.16.0-beta.30.tgz#820d5c65f868b14ec4177bfb8a294931a53616bf" + integrity sha512-39qPHPFmNENxcHf8/CzGHS6wzKMMegoRkHB1+scqtBhSxFaD8tX5Ye33HZIEdQ9nXe9xtr4FWVp77T+n9hdrew== -xterm-headless@5.3.0-beta.46: - version "5.3.0-beta.46" - resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.3.0-beta.46.tgz#3f941f673e3c61aad2705e4b34b42fbe467aed48" - integrity sha512-e/VbZKrfyD1TTxOY5/jah3dUih6q8nTO5v5GQV7YOASp+yyI0XHKiDjLrCyFPQOLTKxCcRutMHvr+CoCcPpcHg== +xterm-headless@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.3.0-beta.61.tgz#28654550cb572709b99ea3eb8672d4568ae141c9" + integrity sha512-yfkbPLUtKjE4K7DsZ204A1BuOKpu6Usqi6rIYWT4XRMi+LjnkTbBjGr2BSjyJ3Gmtm+cSgBD0SvRN+V3xNxbxA== -xterm@5.3.0-beta.46: - version "5.3.0-beta.46" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.46.tgz#9bd2b2a588c88ae64f1989ca3bf5bd9116554b5a" - integrity sha512-keB3C6sXm56ug1+hylAQiNyZP4YtPgd2W+Gu/ZKwJMk5haD25DEnenBYL++Cl3+sNGYxOGS42QlmYj6Mrq1LPw== +xterm@5.3.0-beta.61: + version "5.3.0-beta.61" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0-beta.61.tgz#a6c27d90a5314da51d80deeb32f3bd77f1e1c8f6" + integrity sha512-rJHpCc48GSpHnu0SSERynQ80D5ikvFVsqhv6JdmeONTrnAFRr134OglJRIpbi2YK8UPbV6F6Dfqm/AQh+9GZzA== y18n@^3.2.1: version "3.2.2"