diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 002b81d2161..58c0cebd204 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "VS Code", + "name": "Code - OSS with X11/Wayland", "build": { "dockerfile": "Dockerfile" }, diff --git a/.devcontainer/prebuilt/devcontainer.json b/.devcontainer/prebuilt/devcontainer.json index 455df4f9079..079b8de6cd2 100644 --- a/.devcontainer/prebuilt/devcontainer.json +++ b/.devcontainer/prebuilt/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "Code - OSS", + "name": "Code - OSS with VNC", // Image contents: https://github.com/microsoft/vscode-dev-containers/blob/master/repository-containers/images/github.com/microsoft/vscode/.devcontainer/base.Dockerfile "image": "mcr.microsoft.com/vscode/devcontainers/repos/microsoft/vscode:branch-main", diff --git a/.eslintrc.json b/.eslintrc.json index d95ee4630c3..c33c41eb614 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -181,6 +181,7 @@ "invalidate", "open", "override", + "perform", "receive", "register", "remove", @@ -428,7 +429,8 @@ "vs/workbench/api/~", "vs/workbench/~", "vs/workbench/services/*/~", - "vs/workbench/contrib/*/~" + "vs/workbench/contrib/*/~", + "vs/workbench/contrib/terminalContrib/*/~" ] }, { @@ -476,6 +478,35 @@ } // node module allowed even in /browser/ ] }, + { + "target": "src/vs/workbench/contrib/terminalContrib/*/~", + "restrictions": [ + "vs/base/~", + "vs/base/parts/*/~", + "vs/platform/*/~", + "vs/editor/~", + "vs/editor/contrib/*/~", + "vs/workbench/~", + "vs/workbench/services/*/~", + "vs/workbench/contrib/*/~", + // Only allow terminalContrib to import from itself, this works because + // terminalContrib is one extra folder deep + "vs/workbench/contrib/terminalContrib/*/~", + "vscode-notebook-renderer", // Type only import + { + "when": "hasBrowser", + "pattern": "xterm" + }, // node module allowed even in /browser/ + { + "when": "hasBrowser", + "pattern": "xterm-addon-*" + }, // node module allowed even in /browser/ + { + "when": "hasBrowser", + "pattern": "vscode-textmate" + } // node module allowed even in /browser/ + ] + }, { "target": "src/vs/code/~", "restrictions": [ @@ -512,6 +543,13 @@ "vs/server/~" ] }, + { + "target": "src/vs/workbench/contrib/terminal/terminal.all.ts", + "layer": "browser", + "restrictions": [ + "vs/workbench/contrib/**" + ] + }, { "target": "src/vs/workbench/workbench.common.main.ts", "layer": "browser", @@ -525,7 +563,8 @@ "vs/workbench/~", "vs/workbench/api/~", "vs/workbench/services/*/~", - "vs/workbench/contrib/*/~" + "vs/workbench/contrib/*/~", + "vs/workbench/contrib/terminal/terminal.all" ] }, { diff --git a/.github/classifier.json b/.github/classifier.json index 19bbd7d578d..25196345d09 100644 --- a/.github/classifier.json +++ b/.github/classifier.json @@ -25,7 +25,7 @@ "comments": {"assign": ["alexr00"]}, "config": {"assign": ["sandy081"]}, "containers": {"assign": ["chrmarti"]}, - "context-keys": {"assign": ["alexdima"]}, + "context-keys": {"assign": ["ulugbekna"]}, "continue-working-on": {"assign": ["joyceerhl"]}, "css-less-scss": {"assign": ["aeschli"]}, "custom-editors": {"assign": ["mjbvz"]}, @@ -40,7 +40,7 @@ "editor-bracket-matching": {"assign": ["hediet"]}, "editor-clipboard": {"assign": ["alexdima", "rebornix"]}, "editor-code-actions": {"assign": ["mjbvz"]}, - "editor-color-picker": {"assign": ["rebornix"]}, + "editor-color-picker": {"assign": ["aiday-mar"]}, "editor-columnselect": {"assign": ["alexdima"]}, "editor-commands": {"assign": ["alexdima"]}, "editor-comments": {"assign": ["alexdima"]}, @@ -51,7 +51,7 @@ "editor-find": {"assign": ["rebornix"]}, "editor-folding": {"assign": ["aeschli"]}, "editor-highlight": {"assign": ["alexdima"]}, - "editor-hover": {"assign": ["alexdima"]}, + "editor-hover": {"assign": ["aiday-mar"]}, "editor-indent-detection": {"assign": ["alexdima"]}, "editor-indent-guides": {"assign": ["hediet"]}, "editor-input": {"assign": ["alexdima"]}, @@ -65,7 +65,7 @@ "editor-RTL": {"assign": ["alexdima"]}, "editor-scrollbar": {"assign": ["alexdima"]}, "editor-sorting": {"assign": ["alexdima"]}, - "editor-sticky-scroll": {"assign": ["jrieken"]}, + "editor-sticky-scroll": {"assign": ["aiday-mar"]}, "editor-symbols": {"assign": ["jrieken"]}, "editor-synced-region": {"assign": ["aeschli"]}, "editor-textbuffer": {"assign": ["alexdima", "rebornix"]}, @@ -105,7 +105,7 @@ "image-preview": {"assign": ["mjbvz"]}, "inlay-hints": {"assign": ["jrieken", "hediet"]}, "inline-completions": {"assign": ["hediet"]}, - "install-update": {"assign": ["joaomoreno"]}, + "install-update": {"assign": ["joaomoreno"], "accuracy": 0.85}, "intellisense-config": {"assign": ["rzhao271"]}, "interactive-playground": {"assign": ["chrmarti"]}, "interactive-window": {"assign": ["amunger", "rebornix"]}, @@ -114,9 +114,10 @@ "issue-reporter": {"assign": ["TylerLeonhardt"]}, "javascript": {"assign": ["mjbvz"]}, "json": {"assign": ["aeschli"]}, - "keybindings": {"assign": ["alexdima"]}, + "json-sorting": {"assign": ["aiday-mar"]}, + "keybindings": {"assign": ["ulugbekna"]}, "keybindings-editor": {"assign": ["sandy081"]}, - "keyboard-layout": {"assign": ["alexdima"]}, + "keyboard-layout": {"assign": ["ulugbekna"]}, "L10N": {"assign": ["TylerLeonhardt", "csigs"]}, "l10n-platform": {"assign": ["TylerLeonhardt"]}, "label-provider": {"assign": ["lramos15"]}, @@ -193,6 +194,7 @@ "remote-explorer": {"assign": ["alexr00"]}, "remote-tunnel": {"assign": ["aeschli", "connor4312"]}, "rename": {"assign": ["jrieken"]}, + "runCommands": {"assign": ["ulugbekna"]}, "sandbox": {"assign": ["deepak1556"]}, "sash-widget": {"assign": ["joaomoreno"]}, "scm": {"assign": ["lszomoru"]}, @@ -210,7 +212,7 @@ "shared-process": {"assign": []}, "simple-file-dialog": {"assign": ["alexr00"]}, "smart-select": {"assign": ["jrieken"]}, - "snap": {"assign": ["joaomoreno"]}, + "snap": {"assign": ["deepak1556"]}, "snippets": {"assign": ["jrieken"]}, "splitview-widget": {"assign": ["joaomoreno"]}, "ssh": {"assign": ["eleanorjboyd"]}, diff --git a/.github/commands.json b/.github/commands.json index d83ca4d0c5c..417fdbd6068 100644 --- a/.github/commands.json +++ b/.github/commands.json @@ -440,6 +440,20 @@ "addLabel": "*caused-by-extension", "comment": "It looks like this is caused by the Codespaces extension. Please file the issue in the [Codespaces Discussion Forum](http://aka.ms/ghcs-feedback). Make sure to check their issue reporting template and provide them relevant information such as the extension version you're using. See also our [issue reporting guidelines](https://aka.ms/vscodeissuereporting) for more information.\n\nHappy Coding!" }, + { + "type": "comment", + "name": "extCopilot", + "allowUsers": [ + "cleidigh", + "usernamehw", + "gjsjohnmurray", + "IllusionMH" + ], + "action": "close", + "reason": "not_planned", + "addLabel": "*caused-by-extension", + "comment": "It looks like this is caused by the Copilot extension. Please file the issue in the [Copilot Discussion Forum](https://github.com/community/community/discussions/categories/copilot). Make sure to check their issue reporting template and provide them relevant information such as the extension version you're using. See also our [issue reporting guidelines](https://aka.ms/vscodeissuereporting) for more information.\n\nHappy Coding!" + }, { "type": "comment", "name": "gifPlease", diff --git a/.github/workflows/locker.yml b/.github/workflows/locker.yml index 1b560416df5..8b515b58bd0 100644 --- a/.github/workflows/locker.yml +++ b/.github/workflows/locker.yml @@ -23,6 +23,6 @@ jobs: daysSinceClose: 45 appInsightsKey: ${{secrets.TRIAGE_ACTIONS_APP_INSIGHTS}} daysSinceUpdate: 3 - ignoredLabel: "*out-of-scope" + ignoredLabel: "*out-of-scope,accessibility" ignoreLabelUntil: "author-verification-requested" labelUntil: "verified" diff --git a/.vscode/notebooks/api.github-issues b/.vscode/notebooks/api.github-issues index e10b63f33a5..fe64c1bd880 100644 --- a/.vscode/notebooks/api.github-issues +++ b/.vscode/notebooks/api.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"February 2023\"" + "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"April 2023\"" }, { "kind": 1, diff --git a/.vscode/notebooks/endgame.github-issues b/.vscode/notebooks/endgame.github-issues index 4a61518494e..bb708df569a 100644 --- a/.vscode/notebooks/endgame.github-issues +++ b/.vscode/notebooks/endgame.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"February 2023\"" + "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"April 2023\"" }, { "kind": 1, diff --git a/.vscode/notebooks/my-endgame.github-issues b/.vscode/notebooks/my-endgame.github-issues index 57e276cb7f2..7a358287603 100644 --- a/.vscode/notebooks/my-endgame.github-issues +++ b/.vscode/notebooks/my-endgame.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"February 2023\"\n\n$MINE=assignee:@me" + "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"April 2023\"\n\n$MINE=assignee:@me" }, { "kind": 1, diff --git a/.vscode/notebooks/my-work.github-issues b/.vscode/notebooks/my-work.github-issues index 44b690292ea..bbefb9a471e 100644 --- a/.vscode/notebooks/my-work.github-issues +++ b/.vscode/notebooks/my-work.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "// list of repos we work in\r\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-markdown-languageservice\r\n\r\n// current milestone name\r\n$milestone=milestone:\"February 2023\"" + "value": "// list of repos we work in\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-markdown-languageservice\n\n// current milestone name\n$milestone=milestone:\"April 2023\"" }, { "kind": 1, diff --git a/.vscode/settings.json b/.vscode/settings.json index 7ae8bcef6b9..febe34467b8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,10 +24,12 @@ "out-build/**": true, "out-vscode/**": true, "i18n/**": true, + "extensions/**/dist/**": true, "extensions/**/out/**": true, "test/smoke/out/**": true, "test/automation/out/**": true, "test/integration/browser/out/**": true, + "src/vs/base/test/common/filters.perf.data.js": true, "src/vs/base/test/node/uri.test.data.txt": true, "src/vs/workbench/api/test/browser/extHostDocumentData.test.perf-data.ts": true, "src/vs/editor/test/node/diffing/fixtures/**": true, @@ -118,5 +120,9 @@ }, "githubPullRequests.assignCreated": "${user}", "githubPullRequests.defaultMergeMethod": "squash", - "application.experimental.rendererProfiling": true + "githubPullRequests.ignoredPullRequestBranches": [ + "main" + ], + "application.experimental.rendererProfiling": true, + "editor.experimental.asyncTokenization": true } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d690168ddb2..f97b01e8c62 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -260,14 +260,15 @@ // Used for monaco editor playground launch config "label": "Launch Http Server", "type": "shell", - "command": "node_modules/.bin/http-server --cors --port 5001 -a 127.0.0.1 -s -c-1", + "command": "node_modules/.bin/http-server --cors --port 5001 -a 127.0.0.1 -c-1 -s", "isBackground": true, "problemMatcher": { "pattern": { "regexp": "" }, "background": { - "beginsPattern": ".*", + "activeOnStart": true, + "beginsPattern": "never match", "endsPattern": ".*" } }, diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 8ecb93e61c9..ea245ea51e2 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -1191,7 +1191,7 @@ SOFTWARE. --------------------------------------------------------- -jeff-hykin/better-cpp-syntax 1.16.1 - MIT +jeff-hykin/better-cpp-syntax 1.17.4 - MIT https://github.com/jeff-hykin/better-cpp-syntax MIT License @@ -1275,7 +1275,7 @@ SOFTWARE. --------------------------------------------------------- -jeff-hykin/better-shell-syntax 1.2.8 - MIT +jeff-hykin/better-shell-syntax 1.5.0 - MIT https://github.com/jeff-hykin/better-shell-syntax MIT License @@ -1303,7 +1303,7 @@ SOFTWARE. --------------------------------------------------------- -jlelong/vscode-latex-basics 1.4.0 - MIT +jlelong/vscode-latex-basics 1.5.1 - MIT https://github.com/jlelong/vscode-latex-basics Copyright (c) vscode-latex-basics authors @@ -2184,7 +2184,7 @@ THE SOFTWARE. --------------------------------------------------------- -microsoft/vscode-css 0.0.0 - MIT License +microsoft/vscode-css 0.45.1 - MIT License https://github.com/microsoft/vscode-css MIT License @@ -3341,6 +3341,35 @@ SOFTWARE --------------------------------------------------------- +walles/git-commit-message-plus 1.0.0 - MIT +https://github.com/walles/git-commit-message-plus + +The MIT License (MIT) + +Copyright (c) 2023 Johan Walles + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the" +Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + Web Background Synchronization - Apache2 https://github.com/WICG/background-sync diff --git a/build/azure-pipelines/cli/cli-darwin-sign.yml b/build/azure-pipelines/cli/cli-darwin-sign.yml index b8f9e965133..5b4b5ba7f22 100644 --- a/build/azure-pipelines/cli/cli-darwin-sign.yml +++ b/build/azure-pipelines/cli/cli-darwin-sign.yml @@ -6,9 +6,10 @@ parameters: steps: - task: UseDotNet@2 inputs: - version: 2.x + version: 6.x - task: EsrpClientTool@1 + continueOnError: true displayName: Download ESRPClient - ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}: @@ -20,12 +21,12 @@ steps: - script: | set -e - node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" darwin-sign $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Build.ArtifactStagingDirectory)/pkg "*.zip" + node build/azure-pipelines/common/sign $(Agent.ToolsDirectory)/esrpclient/*/*/net6.0/esrpcli.dll darwin-sign $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Build.ArtifactStagingDirectory)/pkg "*.zip" displayName: Codesign - script: | set -e - node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" darwin-notarize $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Build.ArtifactStagingDirectory)/pkg "*.zip" + node build/azure-pipelines/common/sign $(Agent.ToolsDirectory)/esrpclient/*/*/net6.0/esrpcli.dll darwin-notarize $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Build.ArtifactStagingDirectory)/pkg "*.zip" displayName: Notarize - ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}: diff --git a/build/azure-pipelines/cli/cli-win32-sign.yml b/build/azure-pipelines/cli/cli-win32-sign.yml index 810dd2f4467..9037000ce07 100644 --- a/build/azure-pipelines/cli/cli-win32-sign.yml +++ b/build/azure-pipelines/cli/cli-win32-sign.yml @@ -12,9 +12,8 @@ steps: SecretsFilter: "ESRP-PKI,esrp-aad-username,esrp-aad-password" - task: UseDotNet@2 - displayName: "Use .NET" inputs: - version: 3.x + version: 6.x - task: EsrpClientTool@1 displayName: "Use ESRP client" diff --git a/build/azure-pipelines/common/telemetry-config.json b/build/azure-pipelines/common/telemetry-config.json index fcba1e042ba..46c8ef7311d 100644 --- a/build/azure-pipelines/common/telemetry-config.json +++ b/build/azure-pipelines/common/telemetry-config.json @@ -49,16 +49,6 @@ "excludedDirs": [], "applyEndpoints": true }, - { - "eventPrefix": "ms-vscode.node2/", - "sourceDirs": [ - "vscode-chrome-debug-core", - "vscode-node-debug2" - ], - "excludedDirs": [], - "applyEndpoints": true, - "patchDebugEvents": true - }, { "eventPrefix": "ms-vscode.node/", "sourceDirs": [ @@ -69,4 +59,4 @@ "applyEndpoints": true, "patchDebugEvents": true } -] \ No newline at end of file +] diff --git a/build/azure-pipelines/darwin/cli-build-darwin.yml b/build/azure-pipelines/darwin/cli-build-darwin.yml index f4b30758bdd..4feff8423c3 100644 --- a/build/azure-pipelines/darwin/cli-build-darwin.yml +++ b/build/azure-pipelines/darwin/cli-build-darwin.yml @@ -13,7 +13,7 @@ steps: displayName: Download openssl prebuilt inputs: command: custom - customCommand: pack @vscode-internal/openssl-prebuilt@0.0.3 + customCommand: pack @vscode-internal/openssl-prebuilt@0.0.5 customRegistry: useFeed customFeed: 'Monaco/openssl-prebuilt' workingDir: $(Build.ArtifactStagingDirectory) @@ -21,7 +21,7 @@ steps: - script: | set -e mkdir $(Build.ArtifactStagingDirectory)/openssl - tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.3.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl + tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.5.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt - task: NodeTool@0 @@ -53,8 +53,8 @@ steps: VSCODE_CLI_TARGET: x86_64-apple-darwin VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_darwin_x64_cli VSCODE_CLI_ENV: - OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-osx/lib - OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-osx/include + OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-osx/lib + OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-osx/include - ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}: - template: ../cli/cli-compile-and-publish.yml @@ -62,5 +62,5 @@ steps: VSCODE_CLI_TARGET: aarch64-apple-darwin VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_darwin_arm64_cli VSCODE_CLI_ENV: - OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-osx/lib - OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-osx/include + OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-osx/lib + OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-osx/include diff --git a/build/azure-pipelines/darwin/product-build-darwin-sign.yml b/build/azure-pipelines/darwin/product-build-darwin-sign.yml index 4b9fe5487a1..e2b58d74962 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-sign.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-sign.yml @@ -126,19 +126,20 @@ steps: - task: UseDotNet@2 inputs: - version: 2.x + version: 6.x - task: EsrpClientTool@1 + continueOnError: true displayName: Download ESRPClient - script: | set -e - node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" darwin-sign $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive VSCode-darwin-$(VSCODE_ARCH).zip + node build/azure-pipelines/common/sign $(Agent.ToolsDirectory)/esrpclient/*/*/net6.0/esrpcli.dll darwin-sign $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive VSCode-darwin-$(VSCODE_ARCH).zip displayName: Codesign - script: | set -e - node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" darwin-notarize $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive VSCode-darwin-$(VSCODE_ARCH).zip + node build/azure-pipelines/common/sign $(Agent.ToolsDirectory)/esrpclient/*/*/net6.0/esrpcli.dll darwin-notarize $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive VSCode-darwin-$(VSCODE_ARCH).zip displayName: Notarize - script: | diff --git a/build/azure-pipelines/linux/cli-build-linux.yml b/build/azure-pipelines/linux/cli-build-linux.yml index 02c6471d317..41615fe8e1a 100644 --- a/build/azure-pipelines/linux/cli-build-linux.yml +++ b/build/azure-pipelines/linux/cli-build-linux.yml @@ -22,7 +22,7 @@ steps: displayName: Download openssl prebuilt inputs: command: custom - customCommand: pack @vscode-internal/openssl-prebuilt@0.0.3 + customCommand: pack @vscode-internal/openssl-prebuilt@0.0.5 customRegistry: useFeed customFeed: 'Monaco/openssl-prebuilt' workingDir: $(Build.ArtifactStagingDirectory) @@ -30,7 +30,7 @@ steps: - script: | set -e mkdir $(Build.ArtifactStagingDirectory)/openssl - tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.3.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl + tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.5.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt # inspired by: https://github.com/emk/rust-musl-builder/blob/main/Dockerfile @@ -38,7 +38,7 @@ steps: - bash: | set -e sudo apt-get update - sudo apt-get install -yq build-essential musl-dev musl-tools linux-libc-dev pkgconf xutils-dev + sudo apt-get install -yq build-essential musl-dev musl-tools linux-libc-dev pkgconf xutils-dev lld sudo ln -s "/usr/bin/g++" "/usr/bin/musl-g++" || echo "link exists" displayName: Install musl build dependencies @@ -91,8 +91,9 @@ steps: VSCODE_CLI_ENV: CXX_aarch64-unknown-linux-musl: musl-g++ CC_aarch64-unknown-linux-musl: musl-gcc - OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-linux/lib - OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-linux/include + OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-linux-musl/lib + OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-linux-musl/include + OPENSSL_STATIC: '1' - ${{ if eq(parameters.VSCODE_BUILD_ALPINE, true) }}: - template: ../cli/cli-compile-and-publish.yml @@ -102,8 +103,9 @@ steps: VSCODE_CLI_ENV: CXX_aarch64-unknown-linux-musl: musl-g++ CC_aarch64-unknown-linux-musl: musl-gcc - OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-linux/lib - OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-linux/include + OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-linux-musl/lib + OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-linux-musl/include + OPENSSL_STATIC: '1' - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64, true) }}: - template: ../cli/cli-compile-and-publish.yml diff --git a/build/azure-pipelines/linux/product-build-linux-client.yml b/build/azure-pipelines/linux/product-build-linux-client.yml index cb5a5b47147..21700d26a5a 100644 --- a/build/azure-pipelines/linux/product-build-linux-client.yml +++ b/build/azure-pipelines/linux/product-build-linux-client.yml @@ -321,16 +321,17 @@ steps: - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - task: UseDotNet@2 inputs: - version: 2.x + version: 6.x - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - task: EsrpClientTool@1 + continueOnError: true displayName: Download ESRPClient - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - script: | set -e - node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" rpm $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) .build/linux/rpm '*.rpm' + 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' displayName: Codesign rpm - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: diff --git a/build/azure-pipelines/linux/snap-build-linux.yml b/build/azure-pipelines/linux/snap-build-linux.yml index 12829334956..d1c24a33be3 100644 --- a/build/azure-pipelines/linux/snap-build-linux.yml +++ b/build/azure-pipelines/linux/snap-build-linux.yml @@ -45,7 +45,7 @@ steps: x64) SNAPCRAFT_TARGET_ARGS="" ;; *) SNAPCRAFT_TARGET_ARGS="--target-arch $(VSCODE_ARCH)" ;; esac - (cd $SNAP_ROOT/code-* && sudo --preserve-env snapcraft prime $SNAPCRAFT_TARGET_ARGS && snap pack prime --compression=lzo --filename="$SNAP_PATH") + (cd $SNAP_ROOT/code-* && sudo --preserve-env snapcraft snap $SNAPCRAFT_TARGET_ARGS --output "$SNAP_PATH") # Export SNAP_PATH echo "##vso[task.setvariable variable=SNAP_PATH]$SNAP_PATH" diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 6c561a4fb12..f5f207e5203 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -6,7 +6,6 @@ schedules: branches: include: - main - - joao/web trigger: branches: @@ -165,7 +164,8 @@ resources: endpoint: VSCodeHub options: --user 0:0 --cap-add SYS_ADMIN - container: snapcraft - image: snapcore/snapcraft:stable + image: vscodehub.azurecr.io/vscode-linux-build-agent:snapcraft-x64 + endpoint: VSCodeHub stages: - stage: Compile diff --git a/build/azure-pipelines/win32/cli-build-win32.yml b/build/azure-pipelines/win32/cli-build-win32.yml index f75fe59fb1e..7c476519aa6 100644 --- a/build/azure-pipelines/win32/cli-build-win32.yml +++ b/build/azure-pipelines/win32/cli-build-win32.yml @@ -16,14 +16,14 @@ steps: displayName: Download openssl prebuilt inputs: command: custom - customCommand: pack @vscode-internal/openssl-prebuilt@0.0.3 + customCommand: pack @vscode-internal/openssl-prebuilt@0.0.5 customRegistry: useFeed customFeed: 'Monaco/openssl-prebuilt' workingDir: $(Build.ArtifactStagingDirectory) - powershell: | mkdir $(Build.ArtifactStagingDirectory)/openssl - tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.3.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl + tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.5.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt - task: NodeTool@0 @@ -60,6 +60,7 @@ steps: VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-windows-static-md/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-windows-static-md/include + RUSTFLAGS: '-C target-feature=+crt-static' - ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}: - template: ../cli/cli-compile-and-publish.yml @@ -69,6 +70,7 @@ steps: VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-windows-static-md/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-windows-static-md/include + RUSTFLAGS: '-C target-feature=+crt-static' - ${{ if eq(parameters.VSCODE_BUILD_WIN32_32BIT, true) }}: - template: ../cli/cli-compile-and-publish.yml @@ -78,3 +80,4 @@ steps: VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x86-windows-static-md/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x86-windows-static-md/include + RUSTFLAGS: '-C target-feature=+crt-static' diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 472b51d96c8..e9b8f75078b 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -282,7 +282,7 @@ steps: - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - task: UseDotNet@2 inputs: - version: 3.x + version: 6.x condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: diff --git a/build/filters.js b/build/filters.js index 16d4f7dd46f..095cf733f8c 100644 --- a/build/filters.js +++ b/build/filters.js @@ -194,3 +194,7 @@ module.exports.eslintFilter = [ .filter(line => !!line) .map(line => `!${line}`) ]; + +module.exports.stylelintFilter = [ + 'src/**/*.css' +]; diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index fb3a148f9a8..f9f76e4d371 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -85,7 +85,8 @@ const extractEditorSrcTask = task.define('extract-editor-src', () => { }); }); -const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true)); +// Disable mangling for the editor, as it complicates debugging & quite a few users rely on private/protected fields. +const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true, { disableMangle: true })); const optimizeEditorAMDTask = task.define('optimize-editor-amd', optimize.optimizeTask( { diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index 3c5f90f16d6..5fb1407be19 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -58,6 +58,7 @@ const compilations = [ 'media-preview/tsconfig.json', 'merge-conflict/tsconfig.json', 'microsoft-authentication/tsconfig.json', + 'notebook-renderers/tsconfig.json', 'npm/tsconfig.json', 'php-language-features/tsconfig.json', 'search-result/tsconfig.json', diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index e96ab92ecac..28b877f3d8e 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -60,11 +60,12 @@ const vscodeResources = [ 'out-build/bootstrap-window.js', 'out-build/vs/**/*.{svg,png,html,jpg,mp3}', '!out-build/vs/code/browser/**/*.html', + '!out-build/vs/code/**/*-dev.html', '!out-build/vs/editor/standalone/**/*.svg', 'out-build/vs/base/common/performance.js', 'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh,ps.sh}', 'out-build/vs/base/browser/ui/codicons/codicon/**', - 'out-build/vs/base/parts/sandbox/electron-browser/preload.js', + 'out-build/vs/base/parts/sandbox/electron-sandbox/preload.js', 'out-build/vs/workbench/browser/media/*-theme.css', 'out-build/vs/workbench/contrib/debug/**/*.json', 'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt', @@ -126,7 +127,7 @@ const optimizeVSCodeTask = task.define('optimize-vscode', task.series( { src: [...windowBootstrapFiles, 'out-build/vs/code/electron-sandbox/workbench/workbench.js'], out: 'vs/code/electron-sandbox/workbench/workbench.js' }, { src: [...windowBootstrapFiles, 'out-build/vs/code/electron-sandbox/issue/issueReporter.js'], out: 'vs/code/electron-sandbox/issue/issueReporter.js' }, { src: [...windowBootstrapFiles, 'out-build/vs/code/electron-sandbox/processExplorer/processExplorer.js'], out: 'vs/code/electron-sandbox/processExplorer/processExplorer.js' }, - { src: [...windowBootstrapFiles, 'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js'], out: 'vs/code/electron-browser/sharedProcess/sharedProcess.js' } + { src: [...windowBootstrapFiles, 'out-build/vs/code/node/sharedProcess/sharedProcess.js'], out: 'vs/code/node/sharedProcess/sharedProcess.js' } ] } ) @@ -198,7 +199,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op const out = sourceFolderName; const checksums = computeChecksums(out, [ - 'vs/base/parts/sandbox/electron-browser/preload.js', + 'vs/base/parts/sandbox/electron-sandbox/preload.js', 'vs/workbench/workbench.desktop.main.js', 'vs/workbench/workbench.desktop.main.css', 'vs/workbench/api/node/extensionHostProcess.js', diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js index f8305b89d10..553ef6fc496 100644 --- a/build/gulpfile.vscode.web.js +++ b/build/gulpfile.vscode.web.js @@ -83,7 +83,7 @@ const buildDate = new Date().toISOString(); */ const createVSCodeWebProductConfigurationPatcher = (product) => { /** - * @param content {string} The contens of the file + * @param content {string} The contents of the file * @param path {string} The absolute file path, always using `/`, even on Windows */ const result = (content, path) => { @@ -108,7 +108,7 @@ const createVSCodeWebProductConfigurationPatcher = (product) => { */ const createVSCodeWebBuiltinExtensionsPatcher = (extensionsRoot) => { /** - * @param content {string} The contens of the file + * @param content {string} The contents of the file * @param path {string} The absolute file path, always using `/`, even on Windows */ const result = (content, path) => { @@ -128,7 +128,7 @@ const createVSCodeWebBuiltinExtensionsPatcher = (extensionsRoot) => { */ const combineContentPatchers = (...patchers) => { /** - * @param content {string} The contens of the file + * @param content {string} The contents of the file * @param path {string} The absolute file path, always using `/`, even on Windows */ const result = (content, path) => { diff --git a/build/hygiene.js b/build/hygiene.js index 67f074c4ac0..b8881081b2e 100644 --- a/build/hygiene.js +++ b/build/hygiene.js @@ -11,7 +11,7 @@ const path = require('path'); const fs = require('fs'); const pall = require('p-all'); -const { all, copyrightFilter, unicodeFilter, indentationFilter, tsFormattingFilter, eslintFilter } = require('./filters'); +const { all, copyrightFilter, unicodeFilter, indentationFilter, tsFormattingFilter, eslintFilter, stylelintFilter } = require('./filters'); const copyrightHeaderLines = [ '/*---------------------------------------------------------------------------------------------', @@ -22,6 +22,7 @@ const copyrightHeaderLines = [ function hygiene(some, linting = true) { const gulpeslint = require('gulp-eslint'); + const gulpstylelint = require('./stylelint'); const tsfmt = require('typescript-formatter'); let errorCount = 0; @@ -185,6 +186,16 @@ function hygiene(some, linting = true) { }) ) ); + streams.push( + result.pipe(filter(stylelintFilter)).pipe(gulpstylelint(((message, isError) => { + if (isError) { + console.error(message); + errorCount++; + } else { + console.warn(message); + } + }))) + ); } let count = 0; diff --git a/build/lib/compilation.js b/build/lib/compilation.js index 8449e983c88..63ddeb2eabd 100644 --- a/build/lib/compilation.js +++ b/build/lib/compilation.js @@ -91,7 +91,7 @@ function transpileTask(src, out, swc) { }; } exports.transpileTask = transpileTask; -function compileTask(src, out, build) { +function compileTask(src, out, build, options = {}) { return function () { if (os.totalmem() < 4000000000) { throw new Error('compilation requires 4GB of RAM'); @@ -104,9 +104,9 @@ function compileTask(src, out, build) { } // mangle: TypeScript to TypeScript let mangleStream = es.through(); - if (build) { + if (build && !options.disableMangle) { let ts2tsMangler = new mangleTypeScript_1.Mangler(compile.projectPath, (...data) => fancyLog(ansiColors.blue('[mangler]'), ...data)); - const newContentsByFileName = ts2tsMangler.computeNewFileContents(); + const newContentsByFileName = ts2tsMangler.computeNewFileContents(new Set(['saveState'])); mangleStream = es.through(function write(data) { const tsNormalPath = ts.normalizePath(data.path); const newContents = newContentsByFileName.get(tsNormalPath); @@ -281,4 +281,4 @@ exports.watchApiProposalNamesTask = task.define('watch-api-proposal-names', () = .pipe(util.debounce(task)) .pipe(gulp.dest('src')); }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjb21waWxhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyxtQ0FBbUM7QUFDbkMseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qiw2QkFBNkI7QUFDN0IsMENBQTBDO0FBQzFDLDZCQUE2QjtBQUM3Qix5Q0FBNEM7QUFDNUMsK0JBQStCO0FBQy9CLHNDQUFzQztBQUN0QywwQ0FBMEM7QUFDMUMseUJBQXlCO0FBQ3pCLGlDQUFrQztBQUNsQyw4QkFBOEI7QUFDOUIsK0JBQStCO0FBQy9CLHlEQUE2QztBQUU3QyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7QUFHakMsdUVBQXVFO0FBRXZFLE1BQU0sUUFBUSxHQUFHLElBQUEseUJBQWMsR0FBRSxDQUFDO0FBRWxDLFNBQVMsNEJBQTRCLENBQUMsR0FBVztJQUNoRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDckQsTUFBTSxPQUFPLEdBQXVCLEVBQUUsQ0FBQztJQUN2QyxPQUFPLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUN4QixPQUFPLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN6QixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLENBQUMsRUFBRSxFQUFFLHNDQUFzQztRQUMvRSxPQUFPLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztLQUMxQjtJQUNELE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQzFCLE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQzFCLE9BQU8sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3QyxPQUFPLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJ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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjb21waWxhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyxtQ0FBbUM7QUFDbkMseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qiw2QkFBNkI7QUFDN0IsMENBQTBDO0FBQzFDLDZCQUE2QjtBQUM3Qix5Q0FBNEM7QUFDNUMsK0JBQStCO0FBQy9CLHNDQUFzQztBQUN0QywwQ0FBMEM7QUFDMUMseUJBQXlCO0FBQ3pCLGlDQUFrQztBQUNsQyw4QkFBOEI7QUFDOUIsK0JBQStCO0FBQy9CLHlEQUE2QztBQUU3QyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7QUFHakMsdUVBQXVFO0FBRXZFLE1BQU0sUUFBUSxHQUFHLElBQUEseUJBQWMsR0FBRSxDQUFDO0FBRWxDLFNBQVMsNEJBQTRCLENBQUMsR0FBVztJQUNoRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDckQsTUFBTSxPQUFPLEdBQXVCLEVBQUUsQ0FBQztJQUN2QyxPQUFPLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUN4QixPQUFPLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN6QixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLENBQUMsRUFBRSxFQUFFLHNDQUFzQztRQUMvRSxPQUFPLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztLQUMxQjtJQUNELE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQzFCLE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQzFCLE9BQU8sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3QyxPQUFPLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJ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 \ No newline at end of file diff --git a/build/lib/compilation.ts b/build/lib/compilation.ts index 8e2f7bf4585..d5cd1966221 100644 --- a/build/lib/compilation.ts +++ b/build/lib/compilation.ts @@ -106,7 +106,7 @@ export function transpileTask(src: string, out: string, swc: boolean): () => Nod }; } -export function compileTask(src: string, out: string, build: boolean): () => NodeJS.ReadWriteStream { +export function compileTask(src: string, out: string, build: boolean, options: { disableMangle?: boolean } = {}): () => NodeJS.ReadWriteStream { return function () { @@ -123,9 +123,9 @@ export function compileTask(src: string, out: string, build: boolean): () => Nod // mangle: TypeScript to TypeScript let mangleStream = es.through(); - if (build) { + if (build && !options.disableMangle) { let ts2tsMangler = new Mangler(compile.projectPath, (...data) => fancyLog(ansiColors.blue('[mangler]'), ...data)); - const newContentsByFileName = ts2tsMangler.computeNewFileContents(); + const newContentsByFileName = ts2tsMangler.computeNewFileContents(new Set(['saveState'])); mangleStream = es.through(function write(data: File & { sourceMap?: RawSourceMap }) { type TypeScriptExt = typeof ts & { normalizePath(path: string): string }; const tsNormalPath = (ts).normalizePath(data.path); diff --git a/build/lib/electron.js b/build/lib/electron.js index c6cd669e36d..7cebf64d11f 100644 --- a/build/lib/electron.js +++ b/build/lib/electron.js @@ -76,10 +76,10 @@ function darwinBundleDocumentTypes(types, icon) { }); } exports.config = { - version: util.getElectronVersion(), + version: product.electronRepository ? '19.1.11' : util.getElectronVersion(), productAppName: product.nameLong, companyName: 'Microsoft Corporation', - copyright: 'Copyright (C) 2022 Microsoft. All rights reserved', + copyright: 'Copyright (C) 2023 Microsoft. All rights reserved', darwinIcon: 'resources/darwin/code.icns', darwinBundleIdentifier: product.darwinBundleIdentifier, darwinApplicationCategoryType: 'public.app-category.developer-tools', @@ -193,7 +193,7 @@ function getElectron(arch) { }; } async function main(arch = process.arch) { - const version = util.getElectronVersion(); + const version = product.electronRepository ? '19.1.11' : util.getElectronVersion(); const electronPath = path.join(root, '.build', 'electron'); const versionFile = path.join(electronPath, 'version'); const isUpToDate = fs.existsSync(versionFile) && fs.readFileSync(versionFile, 'utf8') === `${version}`; @@ -208,4 +208,4 @@ if (require.main === module) { process.exit(1); }); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlY3Ryb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlbGVjdHJvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLGdDQUFnQztBQUNoQyxzQ0FBc0M7QUFDdEMsZ0NBQWdDO0FBQ2hDLCtCQUErQjtBQUMvQiw2Q0FBMEM7QUFZMUMsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFZO0lBQ3JDLE9BQU8sR0FBRyxLQUFLLFVBQVUsSUFBSSxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsS0FBSyxNQUFNLElBQUksR0FBRyxLQUFLLGFBQWEsQ0FBQztBQUMxRixDQUFDO0FBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDbkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDckYsTUFBTSxNQUFNLEdBQUcsSUFBQSx1QkFBVSxFQUFDLElBQUksQ0FBQyxDQUFDO0FBRWhDLE1BQU0scUJBQXFCLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFFbkk7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILFNBQVMsd0JBQXdCLENBQUMsVUFBb0IsRUFBRSxJQUFZLEVBQUUsWUFBNEMsRUFBRSxJQUFlO0lBQ2xJLDJGQUEyRjtJQUMzRixJQUFJLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFB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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlY3Ryb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlbGVjdHJvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLGdDQUFnQztBQUNoQyxzQ0FBc0M7QUFDdEMsZ0NBQWdDO0FBQ2hDLCtCQUErQjtBQUMvQiw2Q0FBMEM7QUFZMUMsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFZO0lBQ3JDLE9BQU8sR0FBRyxLQUFLLFVBQVUsSUFBSSxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsS0FBSyxNQUFNLElBQUksR0FBRyxLQUFLLGFBQWEsQ0FBQztBQUMxRixDQUFDO0FBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDbkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDckYsTUFBTSxNQUFNLEdBQUcsSUFBQSx1QkFBVSxFQUFDLElBQUksQ0FBQyxDQUFDO0FBRWhDLE1BQU0scUJBQXFCLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFFbkk7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILFNBQVMsd0JBQXdCLENBQUMsVUFBb0IsRUFBRSxJQUFZLEVBQUUsWUFBNEMsRUFBRSxJQUFlO0lBQ2xJLDJGQUEyRjtJQUMzRixJQUFJLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFB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 \ No newline at end of file diff --git a/build/lib/electron.ts b/build/lib/electron.ts index 247de01c563..c84924e9541 100644 --- a/build/lib/electron.ts +++ b/build/lib/electron.ts @@ -91,10 +91,10 @@ function darwinBundleDocumentTypes(types: { [name: string]: string | string[] }, } export const config = { - version: util.getElectronVersion(), + version: product.electronRepository ? '19.1.11' : util.getElectronVersion(), productAppName: product.nameLong, companyName: 'Microsoft Corporation', - copyright: 'Copyright (C) 2022 Microsoft. All rights reserved', + copyright: 'Copyright (C) 2023 Microsoft. All rights reserved', darwinIcon: 'resources/darwin/code.icns', darwinBundleIdentifier: product.darwinBundleIdentifier, darwinApplicationCategoryType: 'public.app-category.developer-tools', @@ -212,7 +212,7 @@ function getElectron(arch: string): () => NodeJS.ReadWriteStream { } async function main(arch = process.arch): Promise { - const version = util.getElectronVersion(); + const version = product.electronRepository ? '19.1.11' : util.getElectronVersion(); const electronPath = path.join(root, '.build', 'electron'); const versionFile = path.join(electronPath, 'version'); const isUpToDate = fs.existsSync(versionFile) && fs.readFileSync(versionFile, 'utf8') === `${version}`; diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 2f29f2ad2c3..de2fab119ba 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -353,20 +353,12 @@ function scanBuiltinExtensions(extensionsRoot, exclude = []) { const children = fs.readdirSync(path.join(extensionsRoot, extensionFolder)); const packageNLSPath = children.filter(child => child === 'package.nls.json')[0]; const packageNLS = packageNLSPath ? JSON.parse(fs.readFileSync(path.join(extensionsRoot, extensionFolder, packageNLSPath)).toString()) : undefined; - let browserNlsMetadataPath; - if (packageJSON.browser) { - const browserEntrypointFolderPath = path.join(extensionFolder, path.dirname(packageJSON.browser)); - if (fs.existsSync(path.join(extensionsRoot, browserEntrypointFolderPath, 'nls.metadata.json'))) { - browserNlsMetadataPath = path.join(browserEntrypointFolderPath, 'nls.metadata.json'); - } - } const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0]; const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0]; scannedExtensions.push({ extensionPath: extensionFolder, packageJSON, packageNLS, - browserNlsMetadataPath, readmePath: readme ? path.join(extensionFolder, readme) : undefined, changelogPath: changelog ? path.join(extensionFolder, changelog) : undefined, }); @@ -517,4 +509,4 @@ async function buildExtensionMedia(isWatch, outputRoot) { }))); } exports.buildExtensionMedia = buildExtensionMedia; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImV4dGVuc2lvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcsbUNBQW1DO0FBQ25DLHlCQUF5QjtBQUN6QixvQ0FBb0M7QUFDcEMsNkJBQTZCO0FBQzdCLDZCQUE2QjtBQUM3Qiw2QkFBNkI7QUFDN0IscUNBQXFDO0FBQ3JDLDZCQUFzQjtBQUV0Qiw4QkFBOEI7QUFDOUIsbUNBQTRDO0FBQzVDLGdDQUFnQztBQUNoQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztBQUN2QyxzQ0FBdUM7QUFDdkMsc0NBQXVDO0FBQ3ZDLHNDQUFzQztBQUN0QywwQ0FBMEM7QUFDMUMsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3RDLDRDQUE0QztBQUU1QyxpREFBMkQ7QUFDM0QsMkRBQXlEO0FBQ3pELDZDQUEwQztBQUUxQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUNuRCxNQUFNLE1BQU0sR0FBRyxJQUFBLHVCQUFVLEVBQUMsSUFBSSxDQUFDLENBQUM7QUFDaEMsTUFBTSxvQkFBb0IsR0FBRyxtREFBbUQsTUFBTSxFQUFFLENBQUM7QUFFekYsU0FBUyx3QkFBd0IsQ0FBQyxLQUFhO0lBQzlDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxDQUFDLFdBQVcsRUFBRSxvQkFBb0IsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDbEYsT0FBTyxLQUFLO1NBQ1YsSUFBSSxDQUFDLFVBQVUsQ0FBQztTQUNoQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDZCxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQU8sRUFBRSxFQUFFO1FBQzVCLE1BQU0sTUFBTSxHQUE2QixFQUFFLENBQUM7UUFDNUMsTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ25HLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDeEIsbUVBQW1FO1lBQ25FLENBQUMsQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7U0FDaEQ7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNWLENBQUMsQ0FBQyxDQUFDO1NBQ0YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM1QixDQUFDO0FBRUQsU0FBUywwQkFBMEIsQ0FBQyxLQUFhLEVBQUUsTUFBMEI7SUFDNUUsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsMkJBQTJCLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNqRixPQUFPLEtBQUs7U0FDVixJQUFJLENBQUMsaUJBQWlCLENBQUM7U0FDdkIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQ2QsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFPLEVBQUUsRUFBRTtRQUM1QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDckQsQ0FBQyxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2RCxPQUFPLENBQUMsQ0FBQztJQUNWLENBQUMsQ0FBQyxDQUFDO1NBQ0YsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxhQUFxQixFQUFFLE1BQWU7SUFDeEQsTUFBTSxxQkFBcUIsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLHFDQUFxQyxDQUFDLENBQUMsQ0FBQyw2QkFBNkIsQ0FBQztJQUU3RyxNQUFNLFdBQVcsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLHFCQUFxQixDQUFDLENBQUMsQ0FBQztJQUNuRixJQUFJLEtBQUssR0FBRyxXQUFXO1FBQ3RCLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUscUJBQXFCLENBQUM7UUFDeEQsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUVsQyxJQUFJLFdBQVcsRUFBRTtRQUNoQixLQUFLLEdBQUcsMEJBQTBCLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBUyxFQUFFLEVBQUU7WUFDdkQsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO1lBQ3BCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztZQUN6QixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUM7WUFDNUIsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO2dCQUNkLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBQ2pEO1lBQ0QsT0FBTyxJQUFJLENBQUM7UUFDYixDQUFDLENBQUMsQ0FBQztLQUNIO0lBRUQsT0FBTyxLQUFLLENBQUM7QUFDZCxDQUFDO0FBR0QsU0FBUyxnQkFBZ0IsQ0FBQyxhQUFxQixFQUFFLHFCQUE2QjtJQUM3RSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFrQyxDQUFDO0lBQ3RFLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNuQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM5QyxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7SUFFNUIsTUFBTSxvQkFBb0IsR0FBYSxFQUFFLENBQUM7SUFDMUMsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQztJQUM1RSxJQUFJLGlCQUFpQixDQUFDLFlBQVksRUFBRTtRQUNuQyxNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDLENBQUM7UUFDbkYsS0FBSyxNQUFNLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxTQUFTLEVBQUU7WUFDOUMsSUFBSSxHQUFHLElBQUksaUJBQWlCLENBQUMsWUFBWSxFQUFFO2dCQUMxQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDL0I7U0FDRDtLQUNEO0lBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUU7UUFDdkgsTUFBTSxLQUFLLEdBQUcsU0FBUzthQUNyQixHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsQ0FBQzthQUNuRCxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksQ0FBQztZQUN6QixJQUFJLEVBQUUsUUFBUTtZQUNkLElBQUksRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztZQUMzQixJQUFJLEVBQUUsYUFBYTtZQUNuQixRQUFRLEVBQUUsRUFBRSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBUTtTQUM5QyxDQUFDLENBQUMsQ0FBQztRQUVMLCtEQUErRDtRQUMvRCw4Q0FBOEM7UUFDOUMsTUFBTSxzQkFBc0IsR0FBYyxJQUFJLENBQUMsSUFBSSxDQUNsRCxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUscUJBQXFCLENBQUMsRUFDckQsRUFBRSxNQUFNLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQzlCLENBQUM7UUFFSCxNQUFNLGNBQWMsR0FBRyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsRUFBRTtZQUV6RSxNQUFNLFdBQVcsR0FBRyxDQUFDLEdBQVEsRUFBRSxLQUFVLEVBQUUsRUFBRTtnQkFDNUMsUUFBUSxDQUFDLHNCQUFzQixVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2pKLElBQUksR0FBRyxFQUFFO29CQUNSLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2lCQUMxQjtnQkFDRCxNQUFNLEVBQUUsV0FBVyxFQUFFLEdBQUcsS0FBSyxDQUFDO2dCQUM5QixJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDbEMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztpQkFDcEQ7Z0JBQ0QsSUFBSSxXQUFXLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7b0JBQ3BDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7aUJBQ3REO1lBQ0YsQ0FBQyxDQUFDO1lBRUYsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDbEQsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDdkYsTUFBTSxhQUFhLEdBQUc7b0JBQ3JCLEdBQUcsTUFBTTtvQkFDVCxHQUFHLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRTtpQkFDekIsQ0FBQztnQkFDRixNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRW5GLE9BQU8sV0FBVyxDQUFDLGFBQWEsRUFBRSxPQUFPLEVBQUUsV0FBVyxDQUFDO3FCQUNyRCxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLElBQUk7b0JBQzlCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7b0JBQzVCLElBQUksQ0FBQyxJQUFJLEdBQUcsYUFBYSxDQUFDO29CQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDekIsQ0FBQyxDQUFDLENBQUM7cUJBQ0YsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBVSxJQUFVO29CQUNwQyx1QkFBdUI7b0JBQ3ZCLDZCQUE2QjtvQkFDN0IsbURBQW1EO29CQUNuRCxNQUFNLFFBQVEsR0FBWSxJQUFJLENBQUMsUUFBUyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDMUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsa0NBQWtDLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRTt3QkFDaEcsT0FBTywwQkFBMEIsb0JBQW9CLGVBQWUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsSUFBSSxrQkFBa0IsSUFBSSxFQUFFLEVBQUUsQ0FBQztvQkFDaEksQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7b0JBRVosSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3pCLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDTixDQUFDLENBQUMsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLGNBQWMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQy9DLHFDQUFxQztZQUNyQyxZQUFZO1lBQ1osd0RBQXdEO1lBQ3hELDRCQUE0QjtZQUM1QixNQUFNO2FBQ0wsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRWhCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUNkLE9BQU8sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDN0IsT0FBTyxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3BDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUEseUJBQWlCLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckUsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLGFBQXFCO0lBQzdDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQWtDLENBQUM7SUFDdEUsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBRTVCLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxHQUFHLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO1NBQzlFLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRTtRQUNqQixNQUFNLEtBQUssR0FBRyxTQUFTO2FBQ3JCLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBQ25ELEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDO1lBQ3pCLElBQUksRUFBRSxRQUFRO1lBQ2QsSUFBSSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1lBQzNCLElBQUksRUFBRSxhQUFhO1lBQ25CLFFBQVEsRUFBRSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFRO1NBQzlDLENBQUMsQ0FBQyxDQUFDO1FBRUwsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbEMsQ0FBQyxDQUFDO1NBQ0QsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUUxQyxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBQSx5QkFBaUIsRUFBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNyRSxDQUFDO0FBRUQsTUFBTSxTQUFTLEdBQUcsY0FBYyxDQUFDO0FBQ2pDLE1BQU0sV0FBVyxHQUFHO0lBQ25CLG9CQUFvQixFQUFFLGNBQWM7SUFDcEMsWUFBWSxFQUFFLFNBQVM7SUFDdkIsa0JBQWtCLEVBQUUsc0NBQXNDO0NBQzFELENBQUM7QUFFRixTQUFnQixlQUFlLENBQUMsVUFBa0IsRUFBRSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBcUI7SUFDaEgsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDaEQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFzQyxDQUFDO0lBRTlFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuRCxNQUFNLEdBQUcsR0FBRyxHQUFHLFVBQVUsZUFBZSxTQUFTLGlCQUFpQixJQUFJLElBQUksT0FBTyxZQUFZLENBQUM7SUFFOUYsUUFBUSxDQUFDLHdCQUF3QixFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxhQUFhLElBQUksT0FBTyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUU1RixNQUFNLE9BQU8sR0FBRztRQUNmLElBQUksRUFBRSxHQUFHO1FBQ1QsY0FBYyxFQUFFO1lBQ2YsSUFBSSxFQUFFLElBQUk7WUFDVixPQUFPLEVBQUUsV0FBVztTQUNwQjtLQUNELENBQUM7SUFFRixNQUFNLGlCQUFpQixHQUFHLE1BQU0sQ0FBQyxjQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUVwRSxPQUFPLE1BQU0sQ0FBQyxFQUFFLEVBQUUsT0FBTyxDQUFDO1NBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7U0FDaEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztTQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsT0FBUSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUN0RSxJQUFJLENBQUMsaUJBQWlCLENBQUM7U0FDdkIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQ2QsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1NBQ3BDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBM0JELDBDQTJCQztBQUVELE1BQU0sWUFBWSxHQUEyQjtJQUM1QyxNQUFNLEVBQUUsZ0NBQWdDO0lBQ3hDLFlBQVksRUFBRSxTQUFTO0NBQ3ZCLENBQUM7QUFDRixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFO0lBQzdCLFlBQVksQ0FBQyxhQUFhLEdBQUcsUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7Q0FDakc7QUFDRCxNQUFNLGlCQUFpQixHQUFHO0lBQ3pCLEdBQUcsWUFBWTtJQUNmLE1BQU0sRUFBRSwwQkFBMEI7Q0FDbEMsQ0FBQztBQUVGLFNBQWdCLFVBQVUsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBcUI7SUFDOUUsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDaEQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFzQyxDQUFDO0lBRTlFLFFBQVEsQ0FBQyxnQ0FBZ0MsRUFBRSxVQUFVLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxJQUFJLE9BQU8sRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFFM0YsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsY0FBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFFcEUsT0FBTyxNQUFNLENBQUMsQ0FBQyxTQUFTLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsbUJBQW1CLE9BQU8sRUFBRSxDQUFDLEVBQUU7UUFDNUUsSUFBSSxFQUFFLHdCQUF3QjtRQUM5QixjQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFO0tBQ3pDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUTtRQUNsRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3JHLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDWCxPQUFPLFFBQVEsQ0FBQyxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsSUFBSSxNQUFNLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztTQUNyRjtRQUVELE1BQU0sR0FBRyxHQUFHLGFBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN4RixJQUFJLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNyQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RCLENBQUMsQ0FBQyxDQUFDO1NBQ0QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQ2QsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1NBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxPQUFRLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQ3RFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztTQUN2QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDZCxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7U0FDcEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUE3QkQsZ0NBNkJDO0FBRUQsTUFBTSxrQkFBa0IsR0FBRztJQUMxQixrQkFBa0I7SUFDbEIsdUJBQXVCO0lBQ3ZCLHNCQUFzQjtJQUN0QixzQkFBc0I7SUFDdEIsdUJBQXVCO0NBQ3ZCLENBQUM7QUFFRixNQUFNLCtCQUErQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQy9DLHNCQUFzQjtJQUN0Qix1QkFBdUI7SUFDdkIsOEJBQThCO0lBQzlCLG9CQUFvQjtJQUNwQixtQ0FBbUM7Q0FDbkMsQ0FBQyxDQUFDO0FBU0gsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLG9CQUFvQixDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUNwRyxNQUFNLGlCQUFpQixHQUF3QixXQUFXLENBQUMsaUJBQWlCLElBQUksRUFBRSxDQUFDO0FBQ25GLE1BQU0sb0JBQW9CLEdBQXdCLFdBQVcsQ0FBQyxvQkFBb0IsSUFBSSxFQUFFLENBQUM7QUFXekY7O0dBRUc7QUFDSCxTQUFTLGNBQWMsQ0FBQyxRQUE0QjtJQUNuRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDOUIsT0FBTyxJQUFJLENBQUM7S0FDWjtJQUNELElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUMzQixPQUFPLEtBQUssQ0FBQztLQUNiO0lBQ0QsMkJBQTJCO0lBQzNCLElBQUksT0FBTyxRQUFRLENBQUMsYUFBYSxLQUFLLFdBQVcsRUFBRTtRQUNsRCxNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDaEgsSUFBSSxhQUFhLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUN0QyxPQUFPLElBQUksQ0FBQztTQUNaO0tBQ0Q7SUFDRCxJQUFJLE9BQU8sUUFBUSxDQUFDLFdBQVcsS0FBSyxXQUFXLEVBQUU7UUFDaEQsS0FBSyxNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxVQUFVLEVBQUUseUJBQXlCLENBQUMsRUFBRTtZQUN0RSxJQUFJLFFBQVEsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUM1QyxPQUFPLEtBQUssQ0FBQzthQUNiO1NBQ0Q7S0FDRDtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2IsQ0FBQztBQUVELFNBQWdCLDRCQUE0QixDQUFDLE1BQWU7SUFDM0QsTUFBTSwyQkFBMkIsR0FBRyxDQUN4QixJQUFJLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFFO1NBQ2hELEdBQUcsQ0FBQyxZQUFZLENBQUMsRUFBRTtRQUNuQixNQUFNLG9CQUFvQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQzNELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztRQUNsRSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ25ELE9BQU8sRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLENBQUM7SUFDekYsQ0FBQyxDQUFDO1NBQ0QsTUFBTSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1NBQzdELE1BQU0sQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUM7U0FDbkUsTUFBTSxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FDdkYsQ0FBQztJQUNGLE1BQU0scUJBQXFCLEdBQUcsd0JBQXdCLENBQ3JELEVBQUUsQ0FBQyxLQUFLLENBQ1AsR0FBRywyQkFBMkIsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEVBQUU7UUFDOUMsT0FBTyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7YUFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsY0FBYyxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUUsQ0FBQyxDQUFDLENBQ0YsQ0FDRCxDQUFDO0lBRUYsSUFBSSxNQUFjLENBQUM7SUFDbkIsSUFBSSxNQUFNLEVBQUU7UUFDWCxNQUFNLEdBQUcscUJBQXFCLENBQUM7S0FDL0I7U0FBTTtRQUNOLDhDQUE4QztRQUM5QyxNQUFNLHNCQUFzQixHQUFHLElBQUEsd0NBQXlCLEVBQUMsYUFBYSxDQUFDLENBQUM7UUFDeEUsTUFBTSxlQUFlLEdBQUcsc0JBQXNCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFOUksTUFBTSxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQ2hCLHFCQUFxQixFQUNyQixJQUFJLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQzthQUN0QyxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUM1RTtJQUVELE9BQU8sQ0FDTixNQUFNO1NBQ0osSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FDM0MsQ0FBQztBQUNILENBQUM7QUF4Q0Qsb0VBd0NDO0FBRUQsU0FBZ0Isa0NBQWtDLENBQUMsTUFBZTtJQUNqRSxNQUFNLGlDQUFpQyxHQUFHO1FBQ3pDLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsK0JBQStCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2RyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0tBQ3ZDLENBQUM7SUFDRixNQUFNLDJCQUEyQixHQUFHLHdCQUF3QixDQUMzRCxFQUFFLENBQUMsS0FBSyxDQUNQLEdBQUcsaUNBQWlDO1NBQ2xDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRTtRQUNoQixNQUFNLEdBQUcsR0FBRyxJQUFBLHNDQUFrQixFQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLGNBQWMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNuRyxPQUFPLDBCQUEwQixDQUFDLEdBQUcsRUFBRSxDQUFDLElBQVMsRUFBRSxFQUFFO1lBQ3BELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUNwQixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUM7WUFDekIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDO1lBQzVCLE9BQU8sSUFBSSxDQUFDO1FBQ2IsQ0FBQyxDQUFDLENBQUM7SUFDSixDQUFDLENBQUMsQ0FDSCxDQUNELENBQUM7SUFFRixPQUFPLENBQ04sMkJBQTJCO1NBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQzNDLENBQUM7QUFDSCxDQUFDO0FBeEJELGdGQXdCQztBQVdELFNBQWdCLHFCQUFxQixDQUFDLGNBQXNCLEVBQUUsVUFBb0IsRUFBRTtJQUNuRixNQUFNLGlCQUFpQixHQUErQixFQUFFLENBQUM7SUFFekQsSUFBSTtRQUNILE1BQU0saUJBQWlCLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN6RCxLQUFLLE1BQU0sZUFBZSxJQUFJLGlCQUFpQixFQUFFO1lBQ2hELElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQzFDLFNBQVM7YUFDVDtZQUNELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLGVBQWUsRUFBRSxjQUFjLENBQUMsQ0FBQztZQUNuRixJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsRUFBRTtnQkFDcEMsU0FBUzthQUNUO1lBQ0QsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGVBQWUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ2xGLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLEVBQUU7Z0JBQ2pDLFNBQVM7YUFDVDtZQUNELE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQztZQUM1RSxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxLQUFLLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakYsTUFBTSxVQUFVLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsZUFBZSxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ25KLElBQUksc0JBQTBDLENBQUM7WUFDL0MsSUFBSSxXQUFXLENBQUMsT0FBTyxFQUFFO2dCQUN4QixNQUFNLDJCQUEyQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ2xHLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSwyQkFBMkIsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDLEVBQUU7b0JBQy9GLHNCQUFzQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsMkJBQTJCLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztpQkFDckY7YUFDRDtZQUNELE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqRixNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFdkYsaUJBQWlCLENBQUMsSUFBSSxDQUFDO2dCQUN0QixhQUFhLEVBQUUsZUFBZTtnQkFDOUIsV0FBVztnQkFDWCxVQUFVO2dCQUNWLHNCQUFzQjtnQkFDdEIsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQ25FLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO2FBQzVFLENBQUMsQ0FBQztTQUNIO1FBQ0QsT0FBTyxpQkFBaUIsQ0FBQztLQUN6QjtJQUFDLE9BQU8sRUFBRSxFQUFFO1FBQ1osT0FBTyxpQkFBaUIsQ0FBQztLQUN6QjtBQUNGLENBQUM7QUEzQ0Qsc0RBMkNDO0FBRUQsU0FBZ0Isb0JBQW9CLENBQUMsV0FBbUIsRUFBRSxjQUFzQjtJQUkvRSxNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLE1BQU0sVUFBVSxHQUFjLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ3JGLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBUSxFQUFFLEVBQUU7UUFDOUIsS0FBSyxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQUU7WUFDdEIsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDdkIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQzthQUN2QjtpQkFBTSxJQUFJLEdBQUcsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUU7Z0JBQzFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNmO2lCQUFNLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEtBQUssV0FBVyxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxXQUFXLEVBQUU7Z0JBQzFILE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzdELElBQUksVUFBVSxFQUFFO29CQUNmLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLFVBQVUsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztpQkFDN0g7YUFDRDtTQUNEO0lBQ0YsQ0FBQyxDQUFDO0lBQ0YsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZCLE9BQU8sV0FBVyxDQUFDO0FBQ3BCLENBQUM7QUF2QkQsb0RBdUJDO0FBRUQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFFckQsaUZBQWlGO0FBQ2pGLE1BQU0sbUJBQW1CLEdBQUc7SUFDM0IsZ0RBQWdEO0lBQ2hELCtDQUErQztJQUMvQywwQkFBMEI7SUFDMUIsK0JBQStCO0lBQy9CLGtCQUFrQjtJQUNsQixtQ0FBbUM7Q0FDbkMsQ0FBQztBQUVLLEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxRQUFnQixFQUFFLE9BQWdCLEVBQUUsc0JBQXFFO0lBQ2hKLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQTZCLENBQUM7SUFFL0QsTUFBTSxjQUFjLEdBQTRCLEVBQUUsQ0FBQztJQUVuRCxLQUFLLE1BQU0sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLElBQUksc0JBQXNCLEVBQUU7UUFDaEUsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUMsU0FBUyxTQUFTLENBQUMsaUJBQTZIO1lBQy9JLEtBQUssTUFBTSxVQUFVLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFO2dCQUNwRyxNQUFNLE1BQU0sR0FBRyxPQUFPLFVBQVUsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztnQkFDbEYsSUFBSSxVQUFVLEVBQUU7b0JBQ2YsTUFBTSxDQUFDLE1BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxNQUFPLENBQUMsSUFBSyxDQUFDLENBQUMsQ0FBQztpQkFDM0c7Z0JBQ0QsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUM1QjtRQUNGLENBQUM7UUFDRCxTQUFTLENBQUMsaUJBQWlCLENBQUMsQ0FBQztLQUM3QjtJQUNELFNBQVMsUUFBUSxDQUFDLFNBQWM7UUFDL0IsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUN0QyxLQUFLLE1BQU0sS0FBSyxJQUFJLFNBQVMsQ0FBQyxRQUFRLEVBQUU7Z0JBQ3ZDLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUM7Z0JBQ3BDLElBQUksVUFBVSxFQUFFO29CQUNmLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxFQUFFLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7b0JBQ25GLE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQztvQkFDL0QsUUFBUSxDQUFDLFlBQVksVUFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxVQUFVLENBQUMsQ0FBQztpQkFDckg7Z0JBQ0QsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRTtvQkFDaEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFVLEVBQUUsRUFBRTt3QkFDbkMsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDdkIsQ0FBQyxDQUFDLENBQUM7aUJBQ0g7Z0JBQ0QsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRTtvQkFDbEMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFZLEVBQUUsRUFBRTt3QkFDdkMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDeEIsQ0FBQyxDQUFDLENBQUM7aUJBQ0g7YUFDRDtTQUNEO0lBQ0YsQ0FBQztJQUNELE9BQU8sSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDNUMsSUFBSSxPQUFPLEVBQUU7WUFDWixPQUFPLENBQUMsY0FBYyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRTtnQkFDaEQsSUFBSSxHQUFHLEVBQUU7b0JBQ1IsTUFBTSxFQUFFLENBQUM7aUJBQ1Q7cUJBQU07b0JBQ04sUUFBUSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO2lCQUMxQjtZQUNGLENBQUMsQ0FBQyxDQUFDO1NBQ0g7YUFBTTtZQUNOLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUU7Z0JBQzFDLElBQUksR0FBRyxFQUFFO29CQUNSLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3BCLE1BQU0sRUFBRSxDQUFDO2lCQUNUO3FCQUFNO29CQUNOLFFBQVEsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztvQkFDMUIsT0FBTyxFQUFFLENBQUM7aUJBQ1Y7WUFDRixDQUFDLENBQUMsQ0FBQztTQUNIO0lBQ0YsQ0FBQyxDQUFDLENBQUM7QUFDSixDQUFDO0FBN0RELDhDQTZEQztBQUVELEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxRQUFnQixFQUFFLE9BQWdCLEVBQUUsT0FBa0Q7SUFDdEgsU0FBUyxRQUFRLENBQUMsUUFBZ0IsRUFBRSxNQUFjO1FBQ2pELE1BQU0sT0FBTyxHQUFHLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBQ2pFLFFBQVEsQ0FBQyxZQUFZLFVBQVUsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksTUFBTSxTQUFTLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMxRyxLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sSUFBSSxFQUFFLEVBQUU7WUFDbEMsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN0QjtJQUNGLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRTtRQUNwRCxPQUFPLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQzVDLE1BQU0sSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEIsSUFBSSxPQUFPLEVBQUU7Z0JBQ1osSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQzthQUNyQjtZQUNELElBQUksVUFBVSxFQUFFO2dCQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2FBQ3RDO1lBQ0QsTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUM5RSxJQUFJLEtBQUssRUFBRTtvQkFDVixPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDckI7Z0JBQ0QsUUFBUSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDekIsSUFBSSxNQUFNLEVBQUU7b0JBQ1gsT0FBTyxNQUFNLEVBQUUsQ0FBQztpQkFDaEI7Z0JBQ0QsT0FBTyxPQUFPLEVBQUUsQ0FBQztZQUNsQixDQUFDLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxNQUFPLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUNoQyxRQUFRLENBQUMsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3JFLENBQUMsQ0FBQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMzQixDQUFDO0FBRU0sS0FBSyxVQUFVLG1CQUFtQixDQUFDLE9BQWdCLEVBQUUsVUFBbUI7SUFDOUUsT0FBTyxpQkFBaUIsQ0FBQyw0QkFBNEIsRUFBRSxPQUFPLEVBQUUsbUJBQW1CLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM3RixNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBQ3BDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7S0FDakYsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNOLENBQUM7QUFMRCxrREFLQyJ9 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImV4dGVuc2lvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcsbUNBQW1DO0FBQ25DLHlCQUF5QjtBQUN6QixvQ0FBb0M7QUFDcEMsNkJBQTZCO0FBQzdCLDZCQUE2QjtBQUM3Qiw2QkFBNkI7QUFDN0IscUNBQXFDO0FBQ3JDLDZCQUFzQjtBQUV0Qiw4QkFBOEI7QUFDOUIsbUNBQTRDO0FBQzVDLGdDQUFnQztBQUNoQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztBQUN2QyxzQ0FBdUM7QUFDdkMsc0NBQXVDO0FBQ3ZDLHNDQUFzQztBQUN0QywwQ0FBMEM7QUFDMUMsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3RDLDRDQUE0QztBQUU1QyxpREFBMkQ7QUFDM0QsMkRBQXlEO0FBQ3pELDZDQUEwQztBQUUxQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUNuRCxNQUFNLE1BQU0sR0FBRyxJQUFBLHVCQUFVLEVBQUMsSUFBSSxDQUFDLENBQUM7QUFDaEMsTUFBTSxvQkFBb0IsR0FBRyxtREFBbUQsTUFBTSxFQUFFLENBQUM7QUFFekYsU0FBUyx3QkFBd0IsQ0FBQyxLQUFhO0lBQzlDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxDQUFDLFdBQVcsRUFBRSxvQkFBb0IsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDbEYsT0FBTyxLQUFLO1NBQ1YsSUFBSSxDQUFDLFVBQVUsQ0FBQztTQUNoQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDZCxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQU8sRUFBRSxFQUFFO1FBQzVCLE1B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 \ No newline at end of file diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 42ea8d79d6f..234238c4ab1 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -416,7 +416,6 @@ export interface IScannedBuiltinExtension { extensionPath: string; packageJSON: any; packageNLS?: any; - browserNlsMetadataPath?: string; readmePath?: string; changelogPath?: string; } @@ -441,13 +440,6 @@ export function scanBuiltinExtensions(extensionsRoot: string, exclude: string[] const children = fs.readdirSync(path.join(extensionsRoot, extensionFolder)); const packageNLSPath = children.filter(child => child === 'package.nls.json')[0]; const packageNLS = packageNLSPath ? JSON.parse(fs.readFileSync(path.join(extensionsRoot, extensionFolder, packageNLSPath)).toString()) : undefined; - let browserNlsMetadataPath: string | undefined; - if (packageJSON.browser) { - const browserEntrypointFolderPath = path.join(extensionFolder, path.dirname(packageJSON.browser)); - if (fs.existsSync(path.join(extensionsRoot, browserEntrypointFolderPath, 'nls.metadata.json'))) { - browserNlsMetadataPath = path.join(browserEntrypointFolderPath, 'nls.metadata.json'); - } - } const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0]; const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0]; @@ -455,7 +447,6 @@ export function scanBuiltinExtensions(extensionsRoot: string, exclude: string[] extensionPath: extensionFolder, packageJSON, packageNLS, - browserNlsMetadataPath, readmePath: readme ? path.join(extensionFolder, readme) : undefined, changelogPath: changelog ? path.join(extensionFolder, changelog) : undefined, }); diff --git a/build/lib/i18n.js b/build/lib/i18n.js index b424d3c04e1..046e48a1980 100644 --- a/build/lib/i18n.js +++ b/build/lib/i18n.js @@ -4,7 +4,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); -exports.prepareIslFiles = exports.prepareI18nPackFiles = exports.createXlfFilesForIsl = exports.createXlfFilesForExtensions = exports.createXlfFilesForCoreBundle = exports.getResource = exports.processNlsFiles = exports.XLF = exports.Line = exports.extraLanguages = exports.defaultLanguages = void 0; +exports.prepareIslFiles = exports.prepareI18nPackFiles = exports.createXlfFilesForIsl = exports.createXlfFilesForExtensions = exports.EXTERNAL_EXTENSIONS = exports.createXlfFilesForCoreBundle = exports.getResource = exports.processNlsFiles = exports.XLF = exports.Line = exports.extraLanguages = exports.defaultLanguages = void 0; const path = require("path"); const fs = require("fs"); const event_stream_1 = require("event-stream"); @@ -567,7 +567,7 @@ function createL10nBundleForExtension(extensionFolderName, prefixWithBuildFolder concatArrays: true })); } -const EXTERNAL_EXTENSIONS = [ +exports.EXTERNAL_EXTENSIONS = [ 'ms-vscode.js-debug', 'ms-vscode.js-debug-companion', 'ms-vscode.vscode-js-profile-table', @@ -598,7 +598,7 @@ function createXlfFilesForExtensions() { } return _l10nMap; } - (0, event_stream_1.merge)(gulp.src([`.build/extensions/${extensionFolderName}/package.nls.json`, `.build/extensions/${extensionFolderName}/**/nls.metadata.json`], { allowEmpty: true }), createL10nBundleForExtension(extensionFolderName, EXTERNAL_EXTENSIONS.includes(extensionId))).pipe((0, event_stream_1.through)(function (file) { + (0, event_stream_1.merge)(gulp.src([`.build/extensions/${extensionFolderName}/package.nls.json`, `.build/extensions/${extensionFolderName}/**/nls.metadata.json`], { allowEmpty: true }), createL10nBundleForExtension(extensionFolderName, exports.EXTERNAL_EXTENSIONS.includes(extensionId))).pipe((0, event_stream_1.through)(function (file) { if (file.isBuffer()) { const buffer = file.contents; const basename = path.basename(file.path); @@ -742,8 +742,12 @@ function prepareI18nPackFiles(resultingTranslationPaths) { const extensionsPacks = {}; const errors = []; return (0, event_stream_1.through)(function (xlf) { - const project = path.basename(path.dirname(path.dirname(xlf.relative))); - const resource = path.basename(xlf.relative, '.xlf'); + let project = path.basename(path.dirname(path.dirname(xlf.relative))); + // strip `-new` since vscode-extensions-loc uses the `-new` suffix to indicate that it's from the new loc pipeline + const resource = path.basename(path.basename(xlf.relative, '.xlf'), '-new'); + if (exports.EXTERNAL_EXTENSIONS.find(e => e === resource)) { + project = extensionsProject; + } const contents = xlf.contents.toString(); log(`Found ${project}: ${resource}`); const parsePromise = (0, l10n_dev_1.getL10nFilesFromXlf)(contents); @@ -874,4 +878,4 @@ function encodeEntities(value) { function decodeEntities(value) { return value.replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&'); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImkxOG4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcsNkJBQTZCO0FBQzdCLHlCQUF5QjtBQUV6QiwrQ0FBa0U7QUFDbEUsNkNBQTZDO0FBQzdDLDhCQUE4QjtBQUM5Qix5QkFBeUI7QUFDekIsaUNBQWlDO0FBQ2pDLDZCQUE2QjtBQUM3QixzQ0FBc0M7QUFDdEMsMENBQTBDO0FBQzFDLGdEQUFnRDtBQUNoRCwrQ0FBaUg7QUFFakgsU0FBUyxHQUFHLENBQUMsT0FBWSxFQUFFLEdBQUcsSUFBVztJQUN4QyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUN4RCxDQUFDO0FBWVksUUFBQSxnQkFBZ0IsR0FBZTtJQUMzQyxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFO0lBQzVELEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUU7SUFDNUQsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVB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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImkxOG4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcsNkJBQTZCO0FBQzdCLHlCQUF5QjtBQUV6QiwrQ0FBa0U7QUFDbEUsNkNBQTZDO0FBQzdDLDhCQUE4QjtBQUM5Qix5QkFBeUI7QUFDekIsaUNBQWlDO0FBQ2pDLDZCQUE2QjtBQUM3QixzQ0FBc0M7QUFDdEMsMENBQTBDO0FBQzFDLGdEQUFnRDtBQUNoRCwrQ0FBaUg7QUFFakgsU0FBUyxHQUFHLENBQUMsT0FBWSxFQUFFLEdBQUcsSUFBVztJQUN4QyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUN4RCxDQUFDO0FBWVksUUFBQSxnQkFBZ0IsR0FBZTtJQUMzQyxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFO0lBQzVELEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUU7SUFDNUQsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7SUFDL0IsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVB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 \ No newline at end of file diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index 49087e64d02..b5ce6c6eabc 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -54,6 +54,10 @@ "name": "vs/workbench/contrib/codeActions", "project": "vscode-workbench" }, + { + "name": "vs/workbench/contrib/commands", + "project": "vscode-workbench" + }, { "name": "vs/workbench/contrib/comments", "project": "vscode-workbench" @@ -154,6 +158,14 @@ "name": "vs/workbench/contrib/notebook", "project": "vscode-workbench" }, + { + "name": "vs/workbench/contrib/interactiveEditor", + "project": "vscode-workbench" + }, + { + "name": "vs/workbench/contrib/interactiveSession", + "project": "vscode-workbench" + }, { "name": "vs/workbench/contrib/quickaccess", "project": "vscode-workbench" @@ -214,6 +226,10 @@ "name": "vs/workbench/contrib/terminal", "project": "vscode-workbench" }, + { + "name": "vs/workbench/contrib/terminalContrib", + "project": "vscode-workbench" + }, { "name": "vs/workbench/contrib/themes", "project": "vscode-workbench" @@ -262,10 +278,6 @@ "name": "vs/workbench/contrib/welcomeGettingStarted", "project": "vscode-workbench" }, - { - "name": "vs/workbench/contrib/welcomeOverlay", - "project": "vscode-workbench" - }, { "name": "vs/workbench/contrib/welcomePage", "project": "vscode-workbench" @@ -374,6 +386,10 @@ "name": "vs/workbench/services/history", "project": "vscode-workbench" }, + { + "name": "vs/workbench/services/hover", + "project": "vscode-workbench" + }, { "name": "vs/workbench/services/log", "project": "vscode-workbench" @@ -493,6 +509,10 @@ { "name": "vs/workbench/services/userDataProfile", "project": "vscode-profiles" + }, + { + "name": "vs/workbench/services/localization", + "project": "vscode-workbench" } ] } diff --git a/build/lib/i18n.ts b/build/lib/i18n.ts index 9b24140fe66..9cadead419f 100644 --- a/build/lib/i18n.ts +++ b/build/lib/i18n.ts @@ -644,7 +644,7 @@ function createL10nBundleForExtension(extensionFolderName: string, prefixWithBui })); } -const EXTERNAL_EXTENSIONS = [ +export const EXTERNAL_EXTENSIONS = [ 'ms-vscode.js-debug', 'ms-vscode.js-debug-companion', 'ms-vscode.vscode-js-profile-table', @@ -843,8 +843,12 @@ export function prepareI18nPackFiles(resultingTranslationPaths: TranslationPath[ const extensionsPacks: Record = {}; const errors: any[] = []; return through(function (this: ThroughStream, xlf: File) { - const project = path.basename(path.dirname(path.dirname(xlf.relative))); - const resource = path.basename(xlf.relative, '.xlf'); + let project = path.basename(path.dirname(path.dirname(xlf.relative))); + // strip `-new` since vscode-extensions-loc uses the `-new` suffix to indicate that it's from the new loc pipeline + const resource = path.basename(path.basename(xlf.relative, '.xlf'), '-new'); + if (EXTERNAL_EXTENSIONS.find(e => e === resource)) { + project = extensionsProject; + } const contents = xlf.contents.toString(); log(`Found ${project}: ${resource}`); const parsePromise = getL10nFilesFromXlf(contents); diff --git a/build/lib/layersChecker.js b/build/lib/layersChecker.js index 7af25afe1a5..4b03048d9e7 100644 --- a/build/lib/layersChecker.js +++ b/build/lib/layersChecker.js @@ -66,7 +66,9 @@ const NATIVE_TYPES = [ 'INativeEnvironmentService', 'AbstractNativeEnvironmentService', 'INativeWindowConfiguration', - 'ICommonNativeHostService' + 'ICommonNativeHostService', + 'INativeHostService', + 'IMainProcessService' ]; const RULES = [ // Tests: skip @@ -291,4 +293,4 @@ for (const sourceFile of program.getSourceFiles()) { if (hasErrors) { process.exit(1); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXJzQ2hlY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxheWVyc0NoZWNrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyxpQ0FBaUM7QUFDakMsMkJBQThDO0FBQzlDLCtCQUE4QztBQUM5Qyx5Q0FBa0M7QUFFbEMsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBQ0YsK0ZBQStGO0FBQy9GLG1EQUFtRDtBQUNuRCw0RUFBNEU7QUFDNUUsaUVBQWlFO0FBQ2pFLEVBQUU7QUFDRixnR0FBZ0c7QUFDaEcsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBRUYsbUZBQW1GO0FBQ25GLHdGQUF3RjtBQUN4RixNQUFNLFVBQVUsR0FBRztJQUNsQixTQUFTO0lBQ1QsWUFBWTtJQUNaLGNBQWM7SUFDZCxhQUFhO0lBQ2IsZUFBZTtJQUNmLFNBQVM7SUFDVCxTQUFTO0lBQ1QsT0FBTztJQUNQLGtCQUFrQjtJQUNsQixRQUFRO0lBQ1IsYUFBYTtJQUNiLGFBQWE7SUFDYixNQUFNO0lBQ04sZ0JBQWdCO0lBQ2hCLE9BQU87SUFDUCxZQUFZO0lBQ1osYUFBYTtJQUNiLGFBQWE7SUFDYixXQUFXO0lBQ1gsWUFBWTtJQUNaLFlBQVk7SUFDWixjQUFjO0lBQ2QsY0FBYztJQUNkLG1CQUFtQjtJQUNuQixnQkFBZ0I7SUFDaEIsZUFBZTtJQUNmLE1BQU07SUFDTixNQUFNO0lBQ04saUJBQWlCO0lBQ2pCLGFBQWE7SUFDYixnQkFBZ0I7SUFDaEIsYUFBYTtJQUNiLEtBQUs7SUFDTCxpQkFBaUI7SUFDakIsZUFBZTtDQUNmLENBQUM7QUFFRixvRUFBb0U7QUFDcEUsb0VBQW9FO0FBQ3BFLE1BQU0sWUFBWSxHQUFHO0lBQ3BCLGtCQUFrQjtJQUNsQiwyQkFBMkI7SUFDM0Isa0NBQWtDO0lBQ2xDLDRCQUE0QjtJQUM1QiwwQkFBMEI7Q0FDMUIsQ0FBQztBQUVGLE1BQU0sS0FBSyxHQUFZO0lBRXRCLGNBQWM7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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXJzQ2hlY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxheWVyc0NoZWNrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyxpQ0FBaUM7QUFDakMsMkJBQThDO0FBQzlDLCtCQUE4QztBQUM5Qyx5Q0FBa0M7QUFFbEMsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBQ0YsK0ZBQStGO0FBQy9GLG1EQUFtRDtBQUNuRCw0RUFBNEU7QUFDNUUsaUVBQWlFO0FBQ2pFLEVBQUU7QUFDRixnR0FBZ0c7QUFDaEcsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBRUYsbUZBQW1GO0FBQ25GLHdGQUF3RjtBQUN4RixNQUFNLFVBQVUsR0FBRztJQUNsQixTQUFTO0lBQ1QsWUFBWTtJQUNaLGNBQWM7SUFDZCxhQUFhO0lBQ2IsZUFBZTtJQUNmLFNBQVM7SUFDVCxTQUFTO0lBQ1QsT0FBTztJQUNQLGtCQUFrQjtJQUNsQixRQUFRO0lBQ1IsYUFBYTtJQUNiLGFBQWE7SUFDYixNQUFNO0lBQ04sZ0JBQWdCO0lBQ2hCLE9BQU87SUFDUCxZQUFZO0lBQ1osYUFBYTtJQUNiLGFBQWE7SUFDYixXQUFXO0lBQ1gsWUFBWTtJQUNaLFlBQVk7SUFDWixjQUFjO0lBQ2QsY0FBYztJQUNkLG1CQUFtQjtJQUNuQixnQkFBZ0I7SUFDaEIsZUFBZTtJQUNmLE1BQU07SUFDTixNQUFNO0lBQ04saUJBQWlCO0lBQ2pCLGFBQWE7SUFDYixnQkFBZ0I7SUFDaEIsYUFBYTtJQUNiLEtBQUs7SUFDTCxpQkFBaUI7SUFDakIsZUFBZTtDQUNmLENBQUM7QUFFRixvRUFBb0U7QUFDcEUsb0VBQW9FO0FBQ3BFLE1BQU0sWUFBWSxHQUFHO0lBQ3BCLGtCQUFrQjtJQUNsQiwyQkFBMkI7SUFDM0Isa0NBQWtDO0lBQ2xDLDRCQUE0QjtJQUM1QiwwQkFBMEI7SUFDMUIsb0JBQW9CO0lBQ3BCLHFCQUFxQjtDQUNyQixDQUFDO0FBRUYs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 \ No newline at end of file diff --git a/build/lib/layersChecker.ts b/build/lib/layersChecker.ts index 44490b6f1f9..f63e0c57ac3 100644 --- a/build/lib/layersChecker.ts +++ b/build/lib/layersChecker.ts @@ -68,7 +68,9 @@ const NATIVE_TYPES = [ 'INativeEnvironmentService', 'AbstractNativeEnvironmentService', 'INativeWindowConfiguration', - 'ICommonNativeHostService' + 'ICommonNativeHostService', + 'INativeHostService', + 'IMainProcessService' ]; const RULES: IRule[] = [ diff --git a/build/lib/mangleTypeScript.js b/build/lib/mangleTypeScript.js index 6b60e7c3774..7948e917e31 100644 --- a/build/lib/mangleTypeScript.js +++ b/build/lib/mangleTypeScript.js @@ -143,7 +143,7 @@ class ClassData { if (parent.fields.get(name)?.type === 1 /* FieldType.Protected */) { const parentPos = parent.node.getSourceFile().getLineAndCharacterOfPosition(parent.fields.get(name).pos); const infoPos = data.node.getSourceFile().getLineAndCharacterOfPosition(info.pos); - reportViolation(`'${name}' from ${parent.fileName}:${parentPos.line + 1}`, `${data.fileName}:${infoPos.line + 1}`); + reportViolation(name, `'${name}' from ${parent.fileName}:${parentPos.line + 1}`, `${data.fileName}:${infoPos.line + 1}`); parent.fields.get(name).type = 0 /* FieldType.Public */; } parent = parent.parent; @@ -309,7 +309,7 @@ class Mangler { this.log = log; this.service = ts.createLanguageService(new StaticLanguageServiceHost(projectPath)); } - computeNewFileContents() { + computeNewFileContents(strictImplicitPublicHandling) { // STEP: find all classes and their field info const visit = (node) => { if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) { @@ -358,8 +358,9 @@ class Mangler { } // STEP: make implicit public (actually protected) field really public const violations = new Map(); + let violationsCauseFailure = false; for (const data of this.allClassDataByKey.values()) { - ClassData.makeImplicitPublicActuallyPublic(data, (what, why) => { + ClassData.makeImplicitPublicActuallyPublic(data, (name, what, why) => { const arr = violations.get(what); if (arr) { arr.push(why); @@ -367,11 +368,19 @@ class Mangler { else { violations.set(what, [why]); } + if (strictImplicitPublicHandling && !strictImplicitPublicHandling.has(name)) { + violationsCauseFailure = true; + } }); } for (const [why, whys] of violations) { this.log(`WARN: ${why} became PUBLIC because of: ${whys.join(' , ')}`); } + if (violationsCauseFailure) { + const message = 'Protected fields have been made PUBLIC. This hurts minification and is therefore not allowed. Review the WARN messages further above'; + this.log(`ERROR: ${message}`); + throw new Error(message); + } // STEP: compute replacement names for each class for (const data of this.allClassDataByKey.values()) { ClassData.fillInReplacement(data); @@ -505,7 +514,7 @@ async function _run() { const projectPath = path.join(__dirname, '../../src/tsconfig.json'); const projectBase = path.dirname(projectPath); const newProjectBase = path.join(path.dirname(projectBase), path.basename(projectBase) + '2'); - for await (const [fileName, contents] of new Mangler(projectPath, console.log).computeNewFileContents()) { + for await (const [fileName, contents] of new Mangler(projectPath, console.log).computeNewFileContents(new Set(['saveState']))) { const newFilePath = path.join(newProjectBase, path.relative(projectBase, fileName)); await fs.promises.mkdir(path.dirname(newFilePath), { recursive: true }); await fs.promises.writeFile(newFilePath, contents.out); @@ -517,4 +526,4 @@ async function _run() { if (__filename === process_1.argv[1]) { _run(); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuZ2xlVHlwZVNjcmlwdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1hbmdsZVR5cGVTY3JpcHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcsaUNBQWlDO0FBQ2pDLDZCQUE2QjtBQUM3Qix5QkFBeUI7QUFDekIscUNBQStCO0FBQy9CLDJDQUF5RDtBQUN6RCw2QkFBb0M7QUFFcEMsTUFBTSxVQUFVO0lBRVAsTUFBTSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVO1FBQzlHLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJO1FBQ25HLFFBQVEsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTztRQUMxRyxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUU1RCxNQUFNLENBQUMsU0FBUyxHQUFHLHNEQUFzRCxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUVwRixNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ0YsWUFBWSxDQUE0QjtJQUV6RCxZQUFZLFdBQXNDO1FBQ2pELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxXQUFXLENBQUMsSUFB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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuZ2xlVHlwZVNjcmlwdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1hbmdsZVR5cGVTY3JpcHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcsaUNBQWlDO0FBQ2pDLDZCQUE2QjtBQUM3Qix5QkFBeUI7QUFDekIscUNBQStCO0FBQy9CLDJDQUF5RDtBQUN6RCw2QkFBb0M7QUFFcEMsTUFBTSxVQUFVO0lBRVAsTUFBTSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVO1FBQzlHLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJO1FBQ25HLFFBQVEsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTztRQUMxRyxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUU1RCxNQUFNLENBQUMsU0FBUyxHQUFHLHNEQUFzRCxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUVwRixNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ0YsWUFBWSxDQUE0QjtJQUV6RCxZQUFZLFdBQXNDO1FBQ2pELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakYsQ0FBQztJQUVELElBQUk7UUFDSCxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZCxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLEVBQUU7WUFDakMsWUFBWTtZQUNaLE9BQU8sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1NBQ25CO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbEIsQ0FBQztJQUVPLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBUztRQUMvQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztRQUNuQyxJQUFJLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDaEIsR0FBRztZQUNGLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDdEIsTUFBTSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDL0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNuQixRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDaEIsT0FBTyxNQUFNLENBQUM7SUFDZixDQUFDOztBQUdGLElBQVcsU0FJVjtBQUpELFdBQVcsU0FBUztJQUNuQiw2Q0FBTSxDQUFBO0lBQ04sbURBQVMsQ0FBQTtJQUNULCtDQUFPLENBQUE7QUFDUixDQUFDLEVBSlUsU0FBUyxLQUFULFNBQVMsUUFJbkI7QUFFRCxNQUFNLFNBQVM7SUFVSjtJQUNBO0lBVFYsTUFBTSxHQUFHLElBQUksR0FBRyxFQUE0QyxDQUFDO0lBRXJELFlBQVksQ0FBa0M7SUFFdEQsTUFBTSxDQUF3QjtJQUM5QixRQUFRLENBQTBCO0lBRWxDLFlBQ1UsUUFBZ0IsRUFDaEIsSUFBOEM7UUFFdkQsZ0ZBQWdGO1FBQ2hGLGdGQUFnRjtRQUp2RSxhQUFRLEdBQVIsUUFBUSxDQUFRO1FBQ2hCLFNBQUksR0FBSixJQUFJLENBQTBDO1FBS3ZELE1BQU0sVUFBVSxHQUE0QixFQUFFLENBQUM7UUFDL0MsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2xDLElBQUksRUFBRSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNuQyxvQkFBb0I7Z0JBQ3BCLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFFeEI7aUJBQU0sSUFBSSxFQUFFLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQzVDLHVCQUF1QjtnQkFDdkIsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUV4QjtpQkFBTSxJQUFJLEVBQUUsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQ3BDLDhCQUE4QjtnQkFDOUIsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUV4QjtpQkFBTSxJQUFJLEVBQUUsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQ3BDLDhCQUE4QjtnQkFDOUIsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUV4QjtpQkFBTSxJQUFJLEVBQUUsQ0FBQyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDL0MsaURBQWlEO2dCQUNqRCxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sQ0FBQyxVQUFVLEVBQUU7b0JBQ3RDLElBQUksV0FBVyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQzsyQkFDaEQsV0FBVyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDOzJCQUNsRCxXQUFXLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDOzJCQUMvQyxXQUFXLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLEVBQ25EO3dCQUNELFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ3ZCO2lCQUNEO2FBQ0Q7U0FDRDtRQUNELEtBQUssTUFBTSxNQUFNLElBQUksVUFBVSxFQUFFO1lBQ2hDLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDL0MsSUFBSSxDQUFDLEtBQUssRUFBRTtnQkFDWCxTQUFTO2FBQ1Q7WUFDRCxNQUFNLElBQUksR0FBRyxTQUFTLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzdDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLElBQUssQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDL0Q7SUFDRixDQUFDO0lBRU8sTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUF5QjtRQUN0RCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNmLE9BQU8sU0FBUyxDQUFDO1NBQ2pCO1FBQ0QsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDM0IsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxVQUFVLENBQUMsb0JBQW9CLEVBQUU7WUFDckQsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsVUFBVSxDQUFDLGFBQWEsRUFBRTtnQkFDekQsK0NBQStDO2dCQUMvQyxPQUFPO2FBQ1A7WUFDRCxVQUFVO1lBQ1YsS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQy9DO1FBRUQsT0FBTyxLQUFLLENBQUM7SUFDZCxDQUFDO0lBRU8sTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFhO1FBQ3pDLElBQUksV0FBVyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxFQUFFO1lBQ3BELGlDQUF5QjtTQUN6QjthQUFNLElBQUksV0FBVyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLEVBQUU7WUFDN0QsbUNBQTJCO1NBQzNCO2FBQU07WUFDTixnQ0FBd0I7U0FDeEI7SUFDRixDQUFDO0lBRUQsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFlO1FBQ25DLE9BQU8sSUFBSSw4QkFBc0I7ZUFDN0IsSUFBSSxnQ0FBd0IsQ0FDOUI7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFDLGdDQUFnQyxDQUFDLElBQWUsRUFBRSxlQUFrRTtRQUMxSCxVQUFVO1FBQ1YsaUZBQWlGO1FBQ2pGLGlGQUFpRjtRQUNqRixLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUN2QyxJQUFJLElBQUksQ0FBQyxJQUFJLDZCQUFxQixFQUFFO2dCQUNuQyxTQUFTO2FBQ1Q7WUFDRCxJQUFJLE1BQU0sR0FBMEIsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUNoRCxPQUFPLE1BQU0sRUFBRTtnQkFDZCxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksZ0NBQXdCLEVBQUU7b0JBQzFELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsNkJBQTZCLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQzFHLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsNkJBQTZCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNsRixlQUFlLENBQUMsSUFBSSxFQUFFLElBQUksSUFBSSxVQUFVLE1BQU0sQ0FBQyxRQUFRLElBQUksU0FBUyxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLElBQUksT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUV6SCxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUUsQ0FBQyxJQUFJLDJCQUFtQixDQUFDO2lCQUNqRDtnQkFDRCxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQzthQUN2QjtTQUNEO0lBQ0YsQ0FBQztJQUVELE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxJQUFlO1FBRXZDLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUN0QixlQUFlO1lBQ2YsT0FBTztTQUNQO1FBRUQsd0JBQXdCO1FBQ3hCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNoQixTQUFTLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ3pDO1FBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBRTlCLE1BQU0sU0FBUyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBRXZDLGdCQUFnQjtZQUNoQixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQzVCLE9BQU8sSUFBSSxDQUFDO2FBQ1o7WUFFRCxVQUFVO1lBQ1YsSUFBSSxNQUFNLEdBQTBCLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDaEQsT0FBTyxNQUFNLEVBQUU7Z0JBQ2QsSUFBSSxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFO29CQUM5QixPQUFPLElBQUksQ0FBQztpQkFDWjtnQkFDRCxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQzthQUN2QjtZQUVELFdBQVc7WUFDWCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ2xCLE1BQU0sS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2pDLE9BQU8sS0FBSyxDQUFDLE1BQU0sRUFBRTtvQkFDcEIsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRyxDQUFDO29CQUMxQixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUU7d0JBQzVCLE9BQU8sSUFBSSxDQUFDO3FCQUNaO29CQUNELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTt3QkFDbEIsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztxQkFDN0I7aUJBQ0Q7YUFDRDtZQUVELE9BQU8sS0FBSyxDQUFDO1FBQ2QsQ0FBQyxDQUFDLENBQUM7UUFFSCxLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUN2QyxJQUFJLFNBQVMsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUN2QyxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQzthQUN2QztTQUNEO0lBQ0YsQ0FBQztJQUVELGtFQUFrRTtJQUNsRSxrREFBa0Q7SUFDMUMsWUFBWSxDQUFDLElBQVk7UUFDaEMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDbkYsZUFBZTtZQUNmLE9BQU8sSUFBSSxDQUFDO1NBQ1o7UUFDRCxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdEIsS0FBSyxNQUFNLFNBQVMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxFQUFFO2dCQUNuRCxJQUFJLFNBQVMsS0FBSyxJQUFJLEVBQUU7b0JBQ3ZCLDZDQUE2QztvQkFDN0MsT0FBTyxJQUFJLENBQUM7aUJBQ1o7YUFDRDtTQUNEO1FBQ0QsSUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRyxDQUFDLFdBQVcsWUFBWSxHQUFHLEVBQUU7WUFDaEUsMkJBQTJCO1lBQzNCLElBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUcsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUMzRCxPQUFPLElBQUksQ0FBQzthQUNaO1NBQ0Q7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNkLENBQUM7SUFFRCxlQUFlLENBQUMsSUFBWTtRQUMzQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUUsQ0FBQztRQUMxQyxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3pCLE9BQU8sTUFBTSxFQUFFO1lBQ2QsSUFBSSxNQUFNLENBQUMsWUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLGdDQUF3QixFQUFFO2dCQUM1RixLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFFLElBQUksS0FBSyxDQUFDO2FBQ2pEO1lBQ0QsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7U0FDdkI7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNkLENBQUM7SUFFRCxzQkFBc0I7SUFFdEIsUUFBUSxDQUFDLEtBQWdCO1FBQ3hCLElBQUksQ0FBQyxRQUFRLEtBQUssRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3JCLENBQUM7Q0FDRDtBQUVELE1BQU0seUJBQXlCO0lBS1Q7SUFISixRQUFRLENBQXVCO0lBQy9CLGdCQUFnQixHQUFvQyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRS9FLFlBQXFCLFdBQW1CO1FBQW5CLGdCQUFXLEdBQVgsV0FBVyxDQUFRO1FBQ3ZDLE1BQU0sZUFBZSxHQUFnQyxFQUFFLENBQUM7UUFDeEQsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLGNBQWMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMvRCxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUU7WUFDakIsTUFBTSxNQUFNLENBQUMsS0FBSyxDQUFDO1NBQ25CO1FBQ0QsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUMsMEJBQTBCLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDakgsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3BDLE1BQU0sTUFBTSxDQUFDLEtBQUssQ0FBQztTQUNuQjtJQUNGLENBQUM7SUFDRCxzQkFBc0I7UUFDckIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztJQUM5QixDQUFDO0lBQ0Qsa0JBQWtCO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7SUFDaEMsQ0FBQztJQUNELGdCQUFnQixDQUFDLFNBQWlCO1FBQ2pDLE9BQU8sR0FBRyxDQUFDO0lBQ1osQ0FBQztJQUNELGlCQUFpQjtRQUNoQixPQUFPLEdBQUcsQ0FBQztJQUNaLENBQUM7SUFDRCxpQkFBaUIsQ0FBQyxRQUFnQjtRQUNqQyxJQUFJLE1BQU0sR0FBbUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqRixJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUU7WUFDekIsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDMUMsSUFBSSxPQUFPLEtBQUssU0FBUyxFQUFFO2dCQUMxQixPQUFPLFNBQVMsQ0FBQzthQUNqQjtZQUNELE1BQU0sR0FBRyxFQUFFLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztTQUM1QztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2YsQ0FBQztJQUNELG1CQUFtQjtRQUNsQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFDRCxxQkFBcUIsQ0FBQyxPQUEyQjtRQUNoRCxPQUFPLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBQ0QsZUFBZSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDO0lBQ3pDLGNBQWMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQztJQUN2QyxVQUFVLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUM7SUFDL0IsUUFBUSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO0lBQzNCLGFBQWEsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQztJQUNyQyxvREFBb0Q7SUFDcEQsUUFBUSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO0NBQzNCO0FBT0Q7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFhLE9BQU87SUFNRTtJQUE4QjtJQUpsQyxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsRUFBcUIsQ0FBQztJQUVqRCxPQUFPLENBQXFCO0lBRTdDLFlBQXFCLFdBQW1CLEVBQVcsTUFBMEIsR0FBRyxFQUFFLEdBQUcsQ0FBQztRQUFqRSxnQkFBVyxHQUFYLFdBQVcsQ0FBUTtRQUFXLFFBQUcsR0FBSCxHQUFHLENBQWdDO1FBQ3JGLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLHFCQUFxQixDQUFDLElBQUkseUJBQXlCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztJQUNyRixDQUFDO0lBRUQsc0JBQXNCLENBQUMsNEJBQTBDO1FBRWhFLDhDQUE4QztRQUU5QyxNQUFNLEtBQUssR0FBRyxDQUFDLElBQWEsRUFBUSxFQUFFO1lBQ3JDLElBQUksRUFBRSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDOUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUM7Z0JBQ2pDLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQztnQkFDcEUsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO29CQUNwQyxNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2lCQUN6QjtnQkFDRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7YUFDcEY7WUFDRCxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM5QixDQUFDLENBQUM7UUFFRixLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFHLENBQUMsY0FBYyxFQUFFLEVBQUU7WUFDL0QsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDNUIsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDN0I7U0FDRDtRQUNELElBQUksQ0FBQyxHQUFHLENBQUMsNEJBQTRCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBR3BFLHFDQUFxQztRQUVyQyxNQUFNLFlBQVksR0FBRyxDQUFDLElBQWUsRUFBRSxFQUFFO1lBQ3hDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNyRyxJQUFJLENBQUMsYUFBYSxFQUFFO2dCQUNuQixvQkFBb0I7Z0JBQ3BCLE9BQU87YUFDUDtZQUVELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQzdHLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7Z0JBQy9CLDJDQUEyQztnQkFDM0MsT0FBTzthQUNQO1lBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDdEIsc0NBQXNDO2dCQUN0QyxPQUFPO2FBQ1A7WUFFRCxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQzFCLE1BQU0sR0FBRyxHQUFHLEdBQUcsVUFBVSxDQUFDLFFBQVEsSUFBSSxVQUFVLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2xFLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDL0MsSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDWixtREFBbUQ7Z0JBQ25ELE9BQU87YUFDUDtZQUNELE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkIsQ0FBQyxDQUFDO1FBQ0YsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDbkQsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ25CO1FBRUQsdUVBQXVFO1FBQ3ZFLE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxFQUFvQixDQUFDO1FBQy9DLElBQUksc0JBQXNCLEdBQUcsS0FBSyxDQUFDO1FBQ25DLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ25ELFNBQVMsQ0FBQyxnQ0FBZ0MsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFZLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUFFO2dCQUM1RSxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNqQyxJQUFJLEdBQUcsRUFBRTtvQkFDUixHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2lCQUNkO3FCQUFNO29CQUNOLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztpQkFDNUI7Z0JBRUQsSUFBSSw0QkFBNEIsSUFBSSxDQUFDLDRCQUE0QixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRTtvQkFDNUUsc0JBQXNCLEdBQUcsSUFBSSxDQUFDO2lCQUM5QjtZQUNGLENBQUMsQ0FBQyxDQUFDO1NBQ0g7UUFDRCxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksVUFBVSxFQUFFO1lBQ3JDLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxHQUFHLDhCQUE4QixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUN2RTtRQUNELElBQUksc0JBQXNCLEVBQUU7WUFDM0IsTUFBTSxPQUFPLEdBQUcsc0lBQXNJLENBQUM7WUFDdkosSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUN6QjtRQUVELGlEQUFpRDtRQUNqRCxLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNuRCxTQUFTLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDbEM7UUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFJdkMsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFFOUMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxRQUFnQixFQUFFLElBQVUsRUFBRSxFQUFFO1lBQ25ELE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLEtBQUssRUFBRTtnQkFDWCxXQUFXLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7YUFDbEM7aUJBQU07Z0JBQ04sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNqQjtRQUNGLENBQUMsQ0FBQztRQUVGLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxFQUFFO1lBRW5ELElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsRUFBRTtnQkFDekQsU0FBUzthQUNUO1lBRUQsTUFBTSxFQUFFLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUMvQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQ3hDLFNBQVMsTUFBTSxDQUFDO2lCQUNoQjtnQkFFRCxvREFBb0Q7Z0JBQ3BELHVEQUF1RDtnQkFDdkQsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztnQkFDekIsT0FBTyxNQUFNLEVBQUU7b0JBQ2QsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLDZCQUFxQixFQUFFO3dCQUN2RCxTQUFTLE1BQU0sQ0FBQztxQkFDaEI7b0JBQ0QsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7aUJBQ3ZCO2dCQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzNDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN0RyxLQUFLLE1BQU0sR0FBRyxJQUFJLFNBQVMsRUFBRTtvQkFDNUIsVUFBVSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUU7d0JBQ3hCLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksRUFBRSxDQUFDLEdBQUcsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUM7d0JBQ2xFLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUs7d0JBQzFCLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLE1BQU07cUJBQzNCLENBQUMsQ0FBQztpQkFDSDthQUNEO1NBQ0Q7UUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLHlCQUF5QixXQUFXLENBQUMsSUFBSSxRQUFRLENBQUMsQ0FBQztRQUU1RCwwQ0FBMEM7UUFDMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQXdCLENBQUM7UUFDL0MsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBRW5CLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUcsQ0FBQyxjQUFjLEVBQUUsRUFBRTtZQUUvRCxNQUFNLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFHLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNoRixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNsRCxNQUFNLGFBQWEsR0FBRyxPQUFPLElBQUksSUFBQSxtQkFBYSxFQUFDLFVBQVUsSUFBSSxVQUFVLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUVwRixjQUFjO1lBQ2QsSUFBSSxTQUF5QyxDQUFDO1lBRTlDLElBQUksV0FBbUIsQ0FBQztZQUN4QixNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsS0FBSyxFQUFFO2dCQUNYLFlBQVk7Z0JBQ1osV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQzthQUVqQztpQkFBTTtnQkFDTix1QkFBdUI7Z0JBQ3ZCLE1BQU0sZ0JBQWdCLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO2dCQUM3RSxNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsRUFBcUIsQ0FBQztnQkFFcEQsZ0JBQWdCO2dCQUNoQixLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzFDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBRWhELElBQUksUUFBMEIsQ0FBQztnQkFFL0IsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7b0JBQ3pCLElBQUksUUFBUSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sRUFBRTt3QkFDaEQsRUFBRTt3QkFDRixJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQyxPQUFPLEVBQUU7NEJBQ3pFLElBQUksQ0FBQyxHQUFHLENBQUMseUJBQXlCLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDOzRCQUN2RSxNQUFNLElBQUksS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUM7eUJBQ3BDOzZCQUFNOzRCQUNOLFNBQVM7eUJBQ1Q7cUJBQ0Q7b0JBQ0QsUUFBUSxHQUFHLElBQUksQ0FBQztvQkFDaEIsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFDdkYsVUFBVSxJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7b0JBRXZELGNBQWM7b0JBQ2QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFHNUQsSUFBSSxRQUFRLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQzVDLElBQUksQ0FBQyxRQUFRLEVBQUU7d0JBQ2QsUUFBUSxHQUFHLEVBQUUsQ0FBQzt3QkFDZCxjQUFjLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7cUJBQ3ZDO29CQUNELFFBQVEsQ0FBQyxPQUFPLENBQUM7d0JBQ2hCLE1BQU0sRUFBRSxnQkFBZ0I7d0JBQ3hCLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLFNBQVMsRUFBRTt3QkFDdkQsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsU0FBUyxFQUFFO3dCQUN4RCxJQUFJLEVBQUUsV0FBVztxQkFDakIsRUFBRTt3QkFDRixNQUFNLEVBQUUsZ0JBQWdCO3dCQUN4QixRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRTt3QkFDckUsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFO3FCQUM5RSxDQUFDLENBQUM7aUJBQ0g7Z0JBRUQsb0VBQW9FO2dCQUNwRSxTQUFTLEdBQUcsSUFBSSwrQkFBa0IsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQztnQkFDdEcsU0FBUyxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO2dCQUNqRSxLQUFLLE1BQU0sQ0FBQyxFQUFFLFFBQVEsQ0FBQyxJQUFJLGNBQWMsRUFBRTtvQkFDMUMsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO29CQUNsQixLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRTt3QkFDL0IsU0FBUyxDQUFDLFVBQVUsQ0FBQzs0QkFDcEIsR0FBRyxPQUFPOzRCQUNWLFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsU0FBUyxFQUFFO3lCQUN6RixDQUFDLENBQUM7d0JBQ0gsU0FBUyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO3FCQUNoRTtpQkFDRDtnQkFFRCxXQUFXLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUNsQztZQUNELE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDbEY7UUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsVUFBVSxHQUFHLElBQUksVUFBVSxDQUFDLENBQUM7UUFDL0MsT0FBTyxNQUFNLENBQUM7SUFDZixDQUFDO0NBQ0Q7QUExT0QsMEJBME9DO0FBRUQsZ0JBQWdCO0FBRWhCLFNBQVMsV0FBVyxDQUFDLElBQWEsRUFBRSxJQUFtQjtJQUN0RCxNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUNoRixPQUFPLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQzdELENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxJQUFZO0lBQzlCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUVELEtBQUssVUFBVSxJQUFJO0lBRWxCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLHlCQUF5QixDQUFDLENBQUM7SUFDcEUsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM5QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztJQUU5RixJQUFJLEtBQUssRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxJQUFJLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsc0JBQXNCLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDOUgsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNwRixNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN4RSxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkQsSUFBSSxRQUFRLENBQUMsU0FBUyxFQUFFO1lBQ3ZCLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLE1BQU0sRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDdEU7S0FDRDtBQUNGLENBQUM7QUFFRCxJQUFJLFVBQVUsS0FBSyxjQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUU7SUFDM0IsSUFBSSxFQUFFLENBQUM7Q0FDUCJ9 \ No newline at end of file diff --git a/build/lib/mangleTypeScript.ts b/build/lib/mangleTypeScript.ts index 7577e460efa..f2707dd3238 100644 --- a/build/lib/mangleTypeScript.ts +++ b/build/lib/mangleTypeScript.ts @@ -145,7 +145,7 @@ class ClassData { ; } - static makeImplicitPublicActuallyPublic(data: ClassData, reportViolation: (what: string, why: string) => void): void { + static makeImplicitPublicActuallyPublic(data: ClassData, reportViolation: (name: string, what: string, why: string) => void): void { // TS-HACK // A subtype can make an inherited protected field public. To prevent accidential // mangling of public fields we mark the original (protected) fields as public... @@ -158,7 +158,7 @@ class ClassData { if (parent.fields.get(name)?.type === FieldType.Protected) { const parentPos = parent.node.getSourceFile().getLineAndCharacterOfPosition(parent.fields.get(name)!.pos); const infoPos = data.node.getSourceFile().getLineAndCharacterOfPosition(info.pos); - reportViolation(`'${name}' from ${parent.fileName}:${parentPos.line + 1}`, `${data.fileName}:${infoPos.line + 1}`); + reportViolation(name, `'${name}' from ${parent.fileName}:${parentPos.line + 1}`, `${data.fileName}:${infoPos.line + 1}`); parent.fields.get(name)!.type = FieldType.Public; } @@ -346,7 +346,7 @@ export class Mangler { this.service = ts.createLanguageService(new StaticLanguageServiceHost(projectPath)); } - computeNewFileContents(): Map { + computeNewFileContents(strictImplicitPublicHandling?: Set): Map { // STEP: find all classes and their field info @@ -405,19 +405,29 @@ export class Mangler { // STEP: make implicit public (actually protected) field really public const violations = new Map(); + let violationsCauseFailure = false; for (const data of this.allClassDataByKey.values()) { - ClassData.makeImplicitPublicActuallyPublic(data, (what, why) => { + ClassData.makeImplicitPublicActuallyPublic(data, (name: string, what, why) => { const arr = violations.get(what); if (arr) { arr.push(why); } else { violations.set(what, [why]); } + + if (strictImplicitPublicHandling && !strictImplicitPublicHandling.has(name)) { + violationsCauseFailure = true; + } }); } for (const [why, whys] of violations) { this.log(`WARN: ${why} became PUBLIC because of: ${whys.join(' , ')}`); } + if (violationsCauseFailure) { + const message = 'Protected fields have been made PUBLIC. This hurts minification and is therefore not allowed. Review the WARN messages further above'; + this.log(`ERROR: ${message}`); + throw new Error(message); + } // STEP: compute replacement names for each class for (const data of this.allClassDataByKey.values()) { @@ -579,7 +589,7 @@ async function _run() { const projectBase = path.dirname(projectPath); const newProjectBase = path.join(path.dirname(projectBase), path.basename(projectBase) + '2'); - for await (const [fileName, contents] of new Mangler(projectPath, console.log).computeNewFileContents()) { + for await (const [fileName, contents] of new Mangler(projectPath, console.log).computeNewFileContents(new Set(['saveState']))) { const newFilePath = path.join(newProjectBase, path.relative(projectBase, fileName)); await fs.promises.mkdir(path.dirname(newFilePath), { recursive: true }); await fs.promises.writeFile(newFilePath, contents.out); diff --git a/build/lib/optimize.js b/build/lib/optimize.js index c80285c3f2e..0a0066973b5 100644 --- a/build/lib/optimize.js +++ b/build/lib/optimize.js @@ -81,7 +81,7 @@ function loader(src, bundledFileHeader, bundleLoader, externalLoaderInfo) { files.push(new VinylFile({ path: 'fake2', base: '.', - contents: Buffer.from(`require.config(${JSON.stringify(externalLoaderInfo, undefined, 2)});`) + contents: Buffer.from(emitExternalLoaderInfo(externalLoaderInfo)) })); } for (const file of files) { @@ -91,6 +91,17 @@ function loader(src, bundledFileHeader, bundleLoader, externalLoaderInfo) { })) .pipe(concat('vs/loader.js'))); } +function emitExternalLoaderInfo(externalLoaderInfo) { + const externalBaseUrl = externalLoaderInfo.baseUrl; + externalLoaderInfo.baseUrl = '$BASE_URL'; + // If defined, use the runtime configured baseUrl. + const code = ` +(function() { + const baseUrl = require.getConfig().baseUrl || ${JSON.stringify(externalBaseUrl)}; + require.config(${JSON.stringify(externalLoaderInfo, undefined, 2)}); +})();`; + return code.replace('"$BASE_URL"', 'baseUrl'); +} function toConcatStream(src, bundledFileHeader, sources, dest, fileContentMapper) { const useSourcemaps = /\.js$/.test(dest) && !/\.nls\.js$/.test(dest); // If a bundle ends up including in any of the sources our copyright, then @@ -249,9 +260,16 @@ function minifyTask(src, sourceMapBaseUrl) { }).then(res => { const jsFile = res.outputFiles.find(f => /\.js$/.test(f.path)); const sourceMapFile = res.outputFiles.find(f => /\.js\.map$/.test(f.path)); - f.contents = Buffer.from(jsFile.contents); - f.sourceMap = JSON.parse(sourceMapFile.text); - cb(undefined, f); + const contents = Buffer.from(jsFile.contents); + const unicodeMatch = contents.toString().match(/[^\x00-\xFF]+/g); + if (unicodeMatch) { + cb(new Error(`Found non-ascii character ${unicodeMatch[0]} in the minified output of ${f.path}. Non-ASCII characters in the output can cause performance problems when loading. Please review if you have introduced a regular expression that esbuild is not automatically converting and convert it to using unicode escape sequences.`)); + } + else { + f.contents = contents; + f.sourceMap = JSON.parse(sourceMapFile.text); + cb(undefined, f); + } }, cb); }), jsFilter.restore, cssFilter, postcss([cssnano({ preset: 'default' })]), cssFilter.restore, svgFilter, svgmin(), svgFilter.restore, sourcemaps.mapSources((sourcePath) => { if (sourcePath === 'bootstrap-fork.js') { @@ -267,4 +285,4 @@ function minifyTask(src, sourceMapBaseUrl) { }; } exports.minifyTask = minifyTask; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW1pemUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJvcHRpbWl6ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyxtQ0FBbUM7QUFDbkMsNkJBQTZCO0FBQzdCLHNDQUFzQztBQUN0QyxzQ0FBc0M7QUFDdEMsc0NBQXNDO0FBQ3RDLDBDQUEwQztBQUMxQyw2QkFBNkI7QUFDN0IsNkJBQTZCO0FBQzdCLG1DQUFtQztBQUNuQyxtQ0FBbUM7QUFDbkMsaUNBQW1EO0FBQ25ELG1DQUE0QztBQUM1QywrQkFBK0I7QUFFL0IsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFFckQsU0FBUyxHQUFHLENBQUMsTUFBYyxFQUFFLE9BQWU7SUFDM0MsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sR0FBRyxHQUFHLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUN4RCxDQUFDO0FBRUQsU0FBZ0IsWUFBWTtJQUMzQixNQUFNLE1BQU0sR0FBUTtRQUNuQixLQUFLLEVBQUU7WUFDTixJQUFJLEVBQUUsY0FBYztZQUNwQixRQUFRLEVBQUUsUUFBUTtTQUNsQjtRQUNELGlCQUFpQixFQUFFLE9BQU87S0FDMUIsQ0FBQztJQUVGLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUU3QyxPQUFPLE1BQU0sQ0FBQztBQUNmLENBQUM7QUFaRCxvQ0FZQztBQUVELE1BQU0sdUJBQXVCLEdBQUcsd0NBQXdDLENBQUM7QUFFekUsU0FBUyxZQUFZLENBQUMsR0FBVyxFQUFFLElBQVksRUFBRSxXQUErQjtJQUMvRSxPQUFPLENBQ04sSUFBSTtTQUNGLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQztTQUNsQixJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLElBQWU7UUFDekMsSUFBSSxXQUFXLEVBQUU7WUFDaEIsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDOUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLFdBQVcsV0FBVyxJQUFJLENBQUMsQ0FBQztZQUN0RSxJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDdEM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN6QixDQUFDLENBQUMsQ0FBQyxDQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxNQUFNLENBQUMsR0FBVyxFQUFFLGlCQUF5QixFQUFFLFlBQXFCLEVBQUUsa0JBQXdCO0lBQ3RHLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLGVBQWUsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN2RSxJQUFJLFlBQVksRUFBRTtRQUNqQixZQUFZLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FDdEIsWUFBWSxFQUNaLFlBQVksQ0FBQyxHQUFHLEdBQUcsWUFBWSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsUUFBUSxDQUFDLEVBQ3BELFlBQVksQ0FBQyxHQUFHLEdBQUcsWUFBWSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQ3BELENBQUM7S0FDRjtJQUVELE1BQU0sS0FBSyxHQUFnQixFQUFFLENBQUM7SUFDOUIsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFZLEVBQUUsRUFBRTtRQUM5QixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ2pDLE9BQU8sQ0FBQyxDQUFDO1NBQ1Q7UUFDRCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQzlCLE9BQU8sQ0FBQyxDQUFDO1NBQ1Q7UUFDRCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQzlCLE9BQU8sQ0FBQyxDQUFDO1NBQ1Q7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNWLENBQUMsQ0FBQztJQUVGLE9BQU8sQ0FDTixZQUFZO1NBQ1YsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBVSxJQUFJO1FBQzlCLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEIsQ0FBQyxFQUFFO1FBQ0YsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNuQixPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQUM7UUFDSCxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksU0FBUyxDQUFDO1lBQzNCLElBQUksRUFBRSxNQUFNO1lBQ1osSUFBSSxFQUFFLEdBQUc7WUFDVCxRQUFRLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztTQUN4QyxDQUFDLENBQUMsQ0FBQztRQUNKLElBQUksa0JBQWtCLEtBQUssU0FBUyxFQUFFO1lBQ3JDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxTQUFTLENBQUM7Z0JBQ3hCLElBQUksRUFBRSxPQUFPO2dCQUNiLElBQUksRUFBRSxHQUFHO2dCQUNULFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLGtCQUFrQixJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDO2FBQzdGLENBQUMsQ0FBQyxDQUFDO1NBQ0o7UUFDRCxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRTtZQUN6QixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztTQUN4QjtRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbEIsQ0FBQyxDQUFDLENBQUM7U0FDRixJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQzlCLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsR0FBVyxFQUFFLGlCQUF5QixFQUFFLE9BQXVCLEVBQUUsSUFBWSxFQUFFLGlCQUE2RDtJQUNuSyxNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVyRSwwRUFBMEU7SUFDMUUsMEVBQTBFO0lBQzFFLElBQUksb0JBQW9CLEdBQUcsS0FBSyxDQUFDO0lBQ2pDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDbkQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUN6QyxJQUFJLHVCQUF1QixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRTtZQUMvQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7WUFDNUIsTUFBTTtTQUNOO0tBQ0Q7SUFFRCxJQUFJLG9CQUFvQixFQUFFO1FBQ3pCLE9BQU8sQ0FBQyxPQUFPLENBQUM7WUFDZixJQUFJLEVBQUUsSUFBSTtZQUNWLFFBQVEsRUFBRSxpQkFBaUI7U0FDM0IsQ0FBQyxDQUFDO0tBQ0g7SUFFRCxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsTUFBTTtRQUNsRCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ25FLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDbEQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUNqRixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO1FBRTFGLE9BQU8sSUFBSSxTQUFTLENBQUM7WUFDcEIsSUFBSSxFQUFFLElBQUk7WUFDVixJQUFJLEVBQUUsSUFBSTtZQUNWLFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztTQUMvQixDQUFDLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUM7U0FDakMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDMUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNsQixJQUFJLENBQUMsSUFBQSx5QkFBaUIsRUFBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ2pDLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxHQUFXLEVBQUUsaUJBQXlCLEVBQUUsT0FBNkIsRUFBRSxpQkFBNkQ7SUFDM0osT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxNQUFNO1FBQzNDLE9BQU8sY0FBYyxDQUFDLEdBQUcsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUMvRixDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQTRDRCxNQUFNLG1CQUFtQixHQUFHO0lBQzNCLDZEQUE2RDtJQUM3RCw4REFBOEQ7SUFDOUQsOERBQThEO0NBQzlELENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBRWIsU0FBUyxlQUFlLENBQUMsSUFBMEI7SUFDbEQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNyQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQ3JDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDakMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztJQUN2QyxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksbUJBQW1CLENBQUM7SUFDN0QsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxDQUFDLFFBQWdCLEVBQUUsS0FBYSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUVwRyxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQXFDLENBQUM7SUFFbEYsTUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsNkNBQTZDO0lBQ2pGLE1BQU0sZUFBZSxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLHlDQUF5QztJQUMvRSxNQUFNLGdCQUFnQixHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLDJDQUEyQztJQUVsRixNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxZQUFZLEVBQUUsVUFBVSxHQUFHLEVBQUUsTUFBTTtRQUM3RCxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUFFLE9BQU8sYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQUU7UUFFaEYsY0FBYyxDQUFDLEdBQUcsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLENBQUMsS0FBSyxFQUFFLGlCQUFpQixDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRTVGLCtCQUErQjtRQUMvQixNQUFNLGlCQUFpQixHQUFHLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM1QyxNQUFNLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLFVBQVUsUUFBUTtZQUNwRCxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsRUFBRTtnQkFDeEMsR0FBRyxDQUFDLFdBQVcsRUFBRSxxQkFBcUIsR0FBRyxRQUFRLENBQUMsQ0FBQzthQUNuRDtZQUNELGlCQUFpQixDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsUUFBUSxDQUFDLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLEVBQUUsSUFBSSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRXhGLE1BQU0sZUFBZSxHQUFnQixFQUFFLENBQUM7UUFDeEMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ3BCLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxTQUFTLENBQUM7Z0JBQ2xDLElBQUksRUFBRSxpQkFBaUI7Z0JBQ3ZCLElBQUksRUFBRSxHQUFHO2dCQUNULFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDcEUsQ0FBQyxDQUFDLENBQUM7U0FDSjtRQUNELEVBQUUsQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDdEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsS0FBSyxDQUN0QixNQUFNLENBQUMsR0FBRyxFQUFFLGlCQUFpQixFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFDOUQsYUFBYSxFQUNiLGVBQWUsRUFDZixnQkFBZ0IsQ0FDaEIsQ0FBQztJQUVGLE9BQU8sTUFBTTtTQUNYLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRTtRQUM1QixVQUFVLEVBQUUsU0FBUztRQUNyQixVQUFVLEVBQUUsSUFBSTtRQUNoQixjQUFjLEVBQUUsSUFBSTtLQUNwQixDQUFDLENBQUM7U0FDRixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBQSxzQkFBZSxFQUFDO1FBQy9ELFVBQVUsRUFBRSxpQkFBaUI7UUFDN0IsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO0tBQ3pCLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDckIsQ0FBQztBQXFCRCxTQUFTLG9CQUFvQixDQUFDLElBQStCO0lBQzVELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQTZCLENBQUM7SUFFL0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNyQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBRXJDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUM7U0FDaEUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxFQUFFLEVBQUU7UUFDM0IsT0FBTyxDQUFDLEtBQUssQ0FBQztZQUNiLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDckIsTUFBTSxFQUFFLElBQUk7WUFDWixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsS0FBSyxFQUFFLEtBQUs7WUFDWixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7U0FDdkIsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUNiLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUUxQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2xCLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNOLENBQUM7QUFjRCxTQUFTLGtCQUFrQixDQUFDLE9BQWtDO0lBQzdELE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDeEMsT0FBTyxJQUFJO2FBQ1QsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7YUFDWixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsY0FBYyxDQUFDLENBQUM7QUFDcEMsQ0FBQztBQUVELFNBQWdCLGtCQUFrQixDQUFDLEdBQVcsRUFBRSxHQUFXLEVBQUUsWUFBcUIsRUFBRSxpQkFBaUIsR0FBRyxFQUFFLEVBQUUsa0JBQXdCO0lBQ25JLE9BQU8sR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3BHLENBQUM7QUFGRCxnREFFQztBQXFCRCxTQUFnQixZQUFZLENBQUMsSUFBdUI7SUFDbkQsT0FBTztRQUNOLE1BQU0sVUFBVSxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQy9DLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNsQixVQUFVLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1NBQ3JEO1FBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2hCLFVBQVUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7U0FDakQ7UUFFRCxPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMxRCxDQUFDLENBQUM7QUFDSCxDQUFDO0FBYkQsb0NBYUM7QUFFRCxTQUFnQixVQUFVLENBQUMsR0FBVyxFQUFFLGdCQUF5QjtJQUNoRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUE2QixDQUFDO0lBQy9ELE1BQU0sZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLEdBQUcsZ0JBQWdCLElBQUksQ0FBQyxDQUFDLFFBQVEsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUU5RyxPQUFPLEVBQUUsQ0FBQyxFQUFFO1FBQ1gsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBNkIsQ0FBQztRQUMvRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFrQyxDQUFDO1FBQ3pFLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBcUMsQ0FBQztRQUNsRixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFpQyxDQUFDO1FBRXRFLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN0RCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsVUFBVSxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDeEQsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFVBQVUsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXhELElBQUksQ0FDSCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLEtBQUssRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLFdBQVcsQ0FBQyxDQUFDLEVBQ2hELFFBQVEsRUFDUixVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQ25DLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDckIsT0FBTyxDQUFDLEtBQUssQ0FBQztnQkFDYixXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO2dCQUNyQixNQUFNLEVBQUUsSUFBSTtnQkFDWixTQUFTLEVBQUUsVUFBVTtnQkFDckIsTUFBTSxFQUFFLEdBQUc7Z0JBQ1gsUUFBUSxFQUFFLE1BQU07Z0JBQ2hCLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFDbEIsS0FBSyxFQUFFLEtBQUs7YUFDWixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUNiLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUUsQ0FBQztnQkFDaEUsTUFBTSxhQUFhLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBRSxDQUFDO2dCQUU1RSxDQUFDLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUMxQyxDQUFDLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUU3QyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2xCLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNSLENBQUMsQ0FBQyxFQUNGLFFBQVEsQ0FBQyxPQUFPLEVBQ2hCLFNBQVMsRUFDVCxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQ3pDLFNBQVMsQ0FBQyxPQUFPLEVBQ2pCLFNBQVMsRUFDVCxNQUFNLEVBQUUsRUFDUixTQUFTLENBQUMsT0FBTyxFQUNYLFVBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxVQUFrQixFQUFFLEVBQUU7WUFDbkQsSUFBSSxVQUFVLEtBQUssbUJBQW1CLEVBQUU7Z0JBQ3ZDLE9BQU8sd0JBQXdCLENBQUM7YUFDaEM7WUFFRCxPQUFPLFVBQVUsQ0FBQztRQUNuQixDQUFDLENBQUMsRUFDRixVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRTtZQUN0QixnQkFBZ0I7WUFDaEIsVUFBVSxFQUFFLFNBQVM7WUFDckIsY0FBYyxFQUFFLElBQUk7WUFDcEIsVUFBVSxFQUFFLElBQUk7U0FDVCxDQUFDLEVBQ1QsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDLEVBQ3ZCLENBQUMsR0FBUSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN6QixDQUFDLENBQUM7QUFDSCxDQUFDO0FBNURELGdDQTREQyJ9 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW1pemUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJvcHRpbWl6ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7OztBQUVoRyxtQ0FBbUM7QUFDbkMsNkJBQTZCO0FBQzdCLHNDQUFzQztBQUN0QyxzQ0FBc0M7QUFDdEMsc0NBQXNDO0FBQ3RDLDBDQUEwQztBQUMxQyw2QkFBNkI7QUFDN0IsNkJBQTZCO0FBQzdCLG1DQUFtQztBQUNuQyxtQ0FBbUM7QUFDbkMsaUNBQW1EO0FBQ25ELG1DQUE0QztBQUM1QywrQkFBK0I7QUFFL0IsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFFckQsU0FBUyxHQUFHLENBQUMsTUFBYyxFQUFFLE9BQWU7SUFDM0MsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sR0FBRyxHQUFHLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUN4RCxDQUFDO0FBRUQsU0FBZ0IsWUFBWTtJQUMzQixNQUFNLE1BQU0sR0FBUTtRQUNuQixLQUFLLEVBQUU7WUFDTixJQUFJLEVBQUUsY0FBYztZQUNwQixRQUFRLEVBQUUsUUFBUTtTQUNsQjtRQUNELGlCQUFpQixFQUFFLE9BQU87S0FDMUIsQ0FBQztJQUVGLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUU3QyxPQUFPLE1BQU0sQ0FBQztBQUNmLENBQUM7QUFaRCxvQ0FZQztBQUVELE1BQU0sdUJBQXVCLEdBQUcsd0NBQXdDLENBQUM7QUFFekUsU0FBUyxZQUFZLENBQUMsR0FBVyxFQUFFLElBQVksRUFBRSxXQUErQjtJQUMvRSxPQUFPLENBQ04sSUFBSTtTQUNGLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQztTQUNsQixJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FB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 \ No newline at end of file diff --git a/build/lib/optimize.ts b/build/lib/optimize.ts index 2e3943d79f9..aebe22a7e0a 100644 --- a/build/lib/optimize.ts +++ b/build/lib/optimize.ts @@ -54,7 +54,7 @@ function loaderPlugin(src: string, base: string, amdModuleId: string | undefined ); } -function loader(src: string, bundledFileHeader: string, bundleLoader: boolean, externalLoaderInfo?: any): NodeJS.ReadWriteStream { +function loader(src: string, bundledFileHeader: string, bundleLoader: boolean, externalLoaderInfo?: util.IExternalLoaderInfo): NodeJS.ReadWriteStream { let loaderStream = gulp.src(`${src}/vs/loader.js`, { base: `${src}` }); if (bundleLoader) { loaderStream = es.merge( @@ -95,7 +95,7 @@ function loader(src: string, bundledFileHeader: string, bundleLoader: boolean, e files.push(new VinylFile({ path: 'fake2', base: '.', - contents: Buffer.from(`require.config(${JSON.stringify(externalLoaderInfo, undefined, 2)});`) + contents: Buffer.from(emitExternalLoaderInfo(externalLoaderInfo)) })); } for (const file of files) { @@ -107,6 +107,19 @@ function loader(src: string, bundledFileHeader: string, bundleLoader: boolean, e ); } +function emitExternalLoaderInfo(externalLoaderInfo: util.IExternalLoaderInfo): string { + const externalBaseUrl = externalLoaderInfo.baseUrl; + externalLoaderInfo.baseUrl = '$BASE_URL'; + + // If defined, use the runtime configured baseUrl. + const code = ` +(function() { + const baseUrl = require.getConfig().baseUrl || ${JSON.stringify(externalBaseUrl)}; + require.config(${JSON.stringify(externalLoaderInfo, undefined, 2)}); +})();`; + return code.replace('"$BASE_URL"', 'baseUrl'); +} + function toConcatStream(src: string, bundledFileHeader: string, sources: bundle.IFile[], dest: string, fileContentMapper: (contents: string, path: string) => string): NodeJS.ReadWriteStream { const useSourcemaps = /\.js$/.test(dest) && !/\.nls\.js$/.test(dest); @@ -170,7 +183,7 @@ export interface IOptimizeAMDTaskOpts { /** * Additional info we append to the end of the loader */ - externalLoaderInfo?: any; + externalLoaderInfo?: util.IExternalLoaderInfo; /** * (true by default - append css and nls to loader) */ @@ -189,7 +202,7 @@ export interface IOptimizeAMDTaskOpts { languages?: Language[]; /** * File contents interceptor - * @param contents The contens of the file + * @param contents The contents of the file * @param path The absolute file path, always using `/`, even on Windows */ fileContentMapper?: (contents: string, path: string) => string; @@ -324,7 +337,7 @@ function optimizeManualTask(options: IOptimizeManualTaskOpts[]): NodeJS.ReadWrit return es.merge(...concatenations); } -export function optimizeLoaderTask(src: string, out: string, bundleLoader: boolean, bundledFileHeader = '', externalLoaderInfo?: any): () => NodeJS.ReadWriteStream { +export function optimizeLoaderTask(src: string, out: string, bundleLoader: boolean, bundledFileHeader = '', externalLoaderInfo?: util.IExternalLoaderInfo): () => NodeJS.ReadWriteStream { return () => loader(src, bundledFileHeader, bundleLoader, externalLoaderInfo).pipe(gulp.dest(out)); } @@ -393,10 +406,16 @@ export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) => const jsFile = res.outputFiles.find(f => /\.js$/.test(f.path))!; const sourceMapFile = res.outputFiles.find(f => /\.js\.map$/.test(f.path))!; - f.contents = Buffer.from(jsFile.contents); - f.sourceMap = JSON.parse(sourceMapFile.text); + const contents = Buffer.from(jsFile.contents); + const unicodeMatch = contents.toString().match(/[^\x00-\xFF]+/g); + if (unicodeMatch) { + cb(new Error(`Found non-ascii character ${unicodeMatch[0]} in the minified output of ${f.path}. Non-ASCII characters in the output can cause performance problems when loading. Please review if you have introduced a regular expression that esbuild is not automatically converting and convert it to using unicode escape sequences.`)); + } else { + f.contents = contents; + f.sourceMap = JSON.parse(sourceMapFile.text); - cb(undefined, f); + cb(undefined, f); + } }, cb); }), jsFilter.restore, diff --git a/build/lib/stylelint/validateVariableNames.js b/build/lib/stylelint/validateVariableNames.js new file mode 100644 index 00000000000..c34a339ccc9 --- /dev/null +++ b/build/lib/stylelint/validateVariableNames.js @@ -0,0 +1,34 @@ +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getVariableNameValidator = void 0; +const fs_1 = require("fs"); +const path = require("path"); +const RE_VAR_PROP = /var\(\s*(--([\w\-\.]+))/g; +let knownVariables; +function getKnownVariableNames() { + if (!knownVariables) { + const knownVariablesFileContent = (0, fs_1.readFileSync)(path.join(__dirname, './vscode-known-variables.json'), 'utf8').toString(); + const knownVariablesInfo = JSON.parse(knownVariablesFileContent); + knownVariables = new Set([...knownVariablesInfo.colors, ...knownVariablesInfo.others]); + } + return knownVariables; +} +function getVariableNameValidator() { + const allVariables = getKnownVariableNames(); + return (value, report) => { + RE_VAR_PROP.lastIndex = 0; // reset lastIndex just to be sure + let match; + while (match = RE_VAR_PROP.exec(value)) { + const variableName = match[1]; + if (variableName && !allVariables.has(variableName)) { + report(variableName); + } + } + }; +} +exports.getVariableNameValidator = getVariableNameValidator; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGVWYXJpYWJsZU5hbWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidmFsaWRhdGVWYXJpYWJsZU5hbWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7O0FBRWhHLDJCQUFrQztBQUNsQyw2QkFBOEI7QUFFOUIsTUFBTSxXQUFXLEdBQUcsMEJBQTBCLENBQUM7QUFFL0MsSUFBSSxjQUF1QyxDQUFDO0FBQzVDLFNBQVMscUJBQXFCO0lBQzdCLElBQUksQ0FBQyxjQUFjLEVBQUU7UUFDcEIsTUFBTSx5QkFBeUIsR0FBRyxJQUFBLGlCQUFZLEVBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsK0JBQStCLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN6SCxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztRQUNqRSxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxHQUFHLGtCQUFrQixDQUFDLE1BQU0sQ0FBYSxDQUFDLENBQUM7S0FDbkc7SUFDRCxPQUFPLGNBQWMsQ0FBQztBQUN2QixDQUFDO0FBTUQsU0FBZ0Isd0JBQXdCO0lBQ3ZDLE1BQU0sWUFBWSxHQUFHLHFCQUFxQixFQUFFLENBQUM7SUFDN0MsT0FBTyxDQUFDLEtBQWEsRUFBRSxNQUF3QyxFQUFFLEVBQUU7UUFDbEUsV0FBVyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQyxrQ0FBa0M7UUFDN0QsSUFBSSxLQUFLLENBQUM7UUFDVixPQUFPLEtBQUssR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ3ZDLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QixJQUFJLFlBQVksSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUU7Z0JBQ3BELE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQzthQUNyQjtTQUNEO0lBQ0YsQ0FBQyxDQUFDO0FBQ0gsQ0FBQztBQVpELDREQVlDIn0= \ No newline at end of file diff --git a/build/lib/stylelint/validateVariableNames.ts b/build/lib/stylelint/validateVariableNames.ts new file mode 100644 index 00000000000..56e5f84a81f --- /dev/null +++ b/build/lib/stylelint/validateVariableNames.ts @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { readFileSync } from 'fs'; +import path = require('path'); + +const RE_VAR_PROP = /var\(\s*(--([\w\-\.]+))/g; + +let knownVariables: Set | undefined; +function getKnownVariableNames() { + if (!knownVariables) { + const knownVariablesFileContent = readFileSync(path.join(__dirname, './vscode-known-variables.json'), 'utf8').toString(); + const knownVariablesInfo = JSON.parse(knownVariablesFileContent); + knownVariables = new Set([...knownVariablesInfo.colors, ...knownVariablesInfo.others] as string[]); + } + return knownVariables; +} + +export interface IValidator { + (value: string, report: (message: string) => void): void; +} + +export function getVariableNameValidator(): IValidator { + const allVariables = getKnownVariableNames(); + return (value: string, report: (unknwnVariable: string) => void) => { + RE_VAR_PROP.lastIndex = 0; // reset lastIndex just to be sure + let match; + while (match = RE_VAR_PROP.exec(value)) { + const variableName = match[1]; + if (variableName && !allVariables.has(variableName)) { + report(variableName); + } + } + }; +} + diff --git a/build/lib/stylelint/vscode-known-variables.json b/build/lib/stylelint/vscode-known-variables.json new file mode 100644 index 00000000000..3e5a1ba4dc1 --- /dev/null +++ b/build/lib/stylelint/vscode-known-variables.json @@ -0,0 +1,732 @@ +{ + "colors": [ + "--vscode-activityBar-activeBackground", + "--vscode-activityBar-activeBorder", + "--vscode-activityBar-activeFocusBorder", + "--vscode-activityBar-background", + "--vscode-activityBar-border", + "--vscode-activityBar-dropBorder", + "--vscode-activityBar-foreground", + "--vscode-activityBar-inactiveForeground", + "--vscode-activityBarBadge-background", + "--vscode-activityBarBadge-foreground", + "--vscode-badge-background", + "--vscode-badge-foreground", + "--vscode-banner-background", + "--vscode-banner-foreground", + "--vscode-banner-iconForeground", + "--vscode-breadcrumb-activeSelectionForeground", + "--vscode-breadcrumb-background", + "--vscode-breadcrumb-focusForeground", + "--vscode-breadcrumb-foreground", + "--vscode-breadcrumbPicker-background", + "--vscode-button-background", + "--vscode-button-border", + "--vscode-button-foreground", + "--vscode-button-hoverBackground", + "--vscode-button-secondaryBackground", + "--vscode-button-secondaryForeground", + "--vscode-button-secondaryHoverBackground", + "--vscode-button-separator", + "--vscode-charts-blue", + "--vscode-charts-foreground", + "--vscode-charts-green", + "--vscode-charts-lines", + "--vscode-charts-orange", + "--vscode-charts-purple", + "--vscode-charts-red", + "--vscode-charts-yellow", + "--vscode-checkbox-background", + "--vscode-checkbox-border", + "--vscode-checkbox-foreground", + "--vscode-checkbox-selectBackground", + "--vscode-checkbox-selectBorder", + "--vscode-commandCenter-activeBackground", + "--vscode-commandCenter-activeBorder", + "--vscode-commandCenter-activeForeground", + "--vscode-commandCenter-background", + "--vscode-commandCenter-border", + "--vscode-commandCenter-foreground", + "--vscode-commandCenter-inactiveBorder", + "--vscode-commandCenter-inactiveForeground", + "--vscode-contrastActiveBorder", + "--vscode-contrastBorder", + "--vscode-debugConsole-errorForeground", + "--vscode-debugConsole-infoForeground", + "--vscode-debugConsole-sourceForeground", + "--vscode-debugConsole-warningForeground", + "--vscode-debugConsoleInputIcon-foreground", + "--vscode-debugExceptionWidget-background", + "--vscode-debugExceptionWidget-border", + "--vscode-debugIcon-breakpointCurrentStackframeForeground", + "--vscode-debugIcon-breakpointDisabledForeground", + "--vscode-debugIcon-breakpointForeground", + "--vscode-debugIcon-breakpointStackframeForeground", + "--vscode-debugIcon-breakpointUnverifiedForeground", + "--vscode-debugIcon-continueForeground", + "--vscode-debugIcon-disconnectForeground", + "--vscode-debugIcon-pauseForeground", + "--vscode-debugIcon-restartForeground", + "--vscode-debugIcon-startForeground", + "--vscode-debugIcon-stepBackForeground", + "--vscode-debugIcon-stepIntoForeground", + "--vscode-debugIcon-stepOutForeground", + "--vscode-debugIcon-stepOverForeground", + "--vscode-debugIcon-stopForeground", + "--vscode-debugTokenExpression-boolean", + "--vscode-debugTokenExpression-error", + "--vscode-debugTokenExpression-name", + "--vscode-debugTokenExpression-number", + "--vscode-debugTokenExpression-string", + "--vscode-debugTokenExpression-value", + "--vscode-debugToolBar-background", + "--vscode-debugToolBar-border", + "--vscode-debugView-exceptionLabelBackground", + "--vscode-debugView-exceptionLabelForeground", + "--vscode-debugView-stateLabelBackground", + "--vscode-debugView-stateLabelForeground", + "--vscode-debugView-valueChangedHighlight", + "--vscode-descriptionForeground", + "--vscode-diffEditor-border", + "--vscode-diffEditor-diagonalFill", + "--vscode-diffEditor-insertedLineBackground", + "--vscode-diffEditor-insertedTextBackground", + "--vscode-diffEditor-insertedTextBorder", + "--vscode-diffEditor-removedLineBackground", + "--vscode-diffEditor-removedTextBackground", + "--vscode-diffEditor-removedTextBorder", + "--vscode-diffEditorGutter-insertedLineBackground", + "--vscode-diffEditorGutter-removedLineBackground", + "--vscode-diffEditorOverview-insertedForeground", + "--vscode-diffEditorOverview-removedForeground", + "--vscode-disabledForeground", + "--vscode-dropdown-background", + "--vscode-dropdown-border", + "--vscode-dropdown-foreground", + "--vscode-dropdown-listBackground", + "--vscode-editor-background", + "--vscode-editor-findMatchBackground", + "--vscode-editor-findMatchBorder", + "--vscode-editor-findMatchHighlightBackground", + "--vscode-editor-findMatchHighlightBorder", + "--vscode-editor-findRangeHighlightBackground", + "--vscode-editor-findRangeHighlightBorder", + "--vscode-editor-focusedStackFrameHighlightBackground", + "--vscode-editor-foldBackground", + "--vscode-editor-foreground", + "--vscode-editor-hoverHighlightBackground", + "--vscode-editor-inactiveSelectionBackground", + "--vscode-editor-inlineValuesBackground", + "--vscode-editor-inlineValuesForeground", + "--vscode-editor-lineHighlightBackground", + "--vscode-editor-lineHighlightBorder", + "--vscode-editor-linkedEditingBackground", + "--vscode-editor-rangeHighlightBackground", + "--vscode-editor-rangeHighlightBorder", + "--vscode-editor-selectionBackground", + "--vscode-editor-selectionForeground", + "--vscode-editor-selectionHighlightBackground", + "--vscode-editor-selectionHighlightBorder", + "--vscode-editor-snippetFinalTabstopHighlightBackground", + "--vscode-editor-snippetFinalTabstopHighlightBorder", + "--vscode-editor-snippetTabstopHighlightBackground", + "--vscode-editor-snippetTabstopHighlightBorder", + "--vscode-editor-stackFrameHighlightBackground", + "--vscode-editor-symbolHighlightBackground", + "--vscode-editor-symbolHighlightBorder", + "--vscode-editor-wordHighlightBackground", + "--vscode-editor-wordHighlightBorder", + "--vscode-editor-wordHighlightStrongBackground", + "--vscode-editor-wordHighlightStrongBorder", + "--vscode-editor-wordHighlightTextBackground", + "--vscode-editor-wordHighlightTextBorder", + "--vscode-editorActiveLineNumber-foreground", + "--vscode-editorBracketHighlight-foreground1", + "--vscode-editorBracketHighlight-foreground2", + "--vscode-editorBracketHighlight-foreground3", + "--vscode-editorBracketHighlight-foreground4", + "--vscode-editorBracketHighlight-foreground5", + "--vscode-editorBracketHighlight-foreground6", + "--vscode-editorBracketHighlight-unexpectedBracket-foreground", + "--vscode-editorBracketMatch-background", + "--vscode-editorBracketMatch-border", + "--vscode-editorBracketPairGuide-activeBackground1", + "--vscode-editorBracketPairGuide-activeBackground2", + "--vscode-editorBracketPairGuide-activeBackground3", + "--vscode-editorBracketPairGuide-activeBackground4", + "--vscode-editorBracketPairGuide-activeBackground5", + "--vscode-editorBracketPairGuide-activeBackground6", + "--vscode-editorBracketPairGuide-background1", + "--vscode-editorBracketPairGuide-background2", + "--vscode-editorBracketPairGuide-background3", + "--vscode-editorBracketPairGuide-background4", + "--vscode-editorBracketPairGuide-background5", + "--vscode-editorBracketPairGuide-background6", + "--vscode-editorCodeLens-foreground", + "--vscode-editorCommentsWidget-rangeActiveBackground", + "--vscode-editorCommentsWidget-rangeActiveBorder", + "--vscode-editorCommentsWidget-rangeBackground", + "--vscode-editorCommentsWidget-rangeBorder", + "--vscode-editorCommentsWidget-resolvedBorder", + "--vscode-editorCommentsWidget-unresolvedBorder", + "--vscode-editorCursor-background", + "--vscode-editorCursor-foreground", + "--vscode-editorError-background", + "--vscode-editorError-border", + "--vscode-editorError-foreground", + "--vscode-editorGhostText-background", + "--vscode-editorGhostText-border", + "--vscode-editorGhostText-foreground", + "--vscode-editorGroup-border", + "--vscode-editorGroup-dropBackground", + "--vscode-editorGroup-dropIntoPromptBackground", + "--vscode-editorGroup-dropIntoPromptBorder", + "--vscode-editorGroup-dropIntoPromptForeground", + "--vscode-editorGroup-emptyBackground", + "--vscode-editorGroup-focusedEmptyBorder", + "--vscode-editorGroupHeader-border", + "--vscode-editorGroupHeader-noTabsBackground", + "--vscode-editorGroupHeader-tabsBackground", + "--vscode-editorGroupHeader-tabsBorder", + "--vscode-editorGutter-addedBackground", + "--vscode-editorGutter-background", + "--vscode-editorGutter-commentGlyphForeground", + "--vscode-editorGutter-commentRangeForeground", + "--vscode-editorGutter-commentUnresolvedGlyphForeground", + "--vscode-editorGutter-deletedBackground", + "--vscode-editorGutter-foldingControlForeground", + "--vscode-editorGutter-modifiedBackground", + "--vscode-editorHint-border", + "--vscode-editorHint-foreground", + "--vscode-editorHoverWidget-background", + "--vscode-editorHoverWidget-border", + "--vscode-editorHoverWidget-foreground", + "--vscode-editorHoverWidget-highlightForeground", + "--vscode-editorHoverWidget-statusBarBackground", + "--vscode-editorIndentGuide-activeBackground", + "--vscode-editorIndentGuide-background", + "--vscode-editorInfo-background", + "--vscode-editorInfo-border", + "--vscode-editorInfo-foreground", + "--vscode-editorInlayHint-background", + "--vscode-editorInlayHint-foreground", + "--vscode-editorInlayHint-parameterBackground", + "--vscode-editorInlayHint-parameterForeground", + "--vscode-editorInlayHint-typeBackground", + "--vscode-editorInlayHint-typeForeground", + "--vscode-editorLightBulb-foreground", + "--vscode-editorLightBulbAutoFix-foreground", + "--vscode-editorLineNumber-activeForeground", + "--vscode-editorLineNumber-dimmedForeground", + "--vscode-editorLineNumber-foreground", + "--vscode-editorLink-activeForeground", + "--vscode-editorMarkerNavigation-background", + "--vscode-editorMarkerNavigationError-background", + "--vscode-editorMarkerNavigationError-headerBackground", + "--vscode-editorMarkerNavigationInfo-background", + "--vscode-editorMarkerNavigationInfo-headerBackground", + "--vscode-editorMarkerNavigationWarning-background", + "--vscode-editorMarkerNavigationWarning-headerBackground", + "--vscode-editorOverviewRuler-addedForeground", + "--vscode-editorOverviewRuler-background", + "--vscode-editorOverviewRuler-border", + "--vscode-editorOverviewRuler-bracketMatchForeground", + "--vscode-editorOverviewRuler-commonContentForeground", + "--vscode-editorOverviewRuler-currentContentForeground", + "--vscode-editorOverviewRuler-deletedForeground", + "--vscode-editorOverviewRuler-errorForeground", + "--vscode-editorOverviewRuler-findMatchForeground", + "--vscode-editorOverviewRuler-incomingContentForeground", + "--vscode-editorOverviewRuler-infoForeground", + "--vscode-editorOverviewRuler-modifiedForeground", + "--vscode-editorOverviewRuler-rangeHighlightForeground", + "--vscode-editorOverviewRuler-selectionHighlightForeground", + "--vscode-editorOverviewRuler-warningForeground", + "--vscode-editorOverviewRuler-wordHighlightForeground", + "--vscode-editorOverviewRuler-wordHighlightStrongForeground", + "--vscode-editorOverviewRuler-wordHighlightTextForeground", + "--vscode-editorPane-background", + "--vscode-editorRuler-foreground", + "--vscode-editorStickyScroll-background", + "--vscode-editorStickyScrollHover-background", + "--vscode-editorSuggestWidget-background", + "--vscode-editorSuggestWidget-border", + "--vscode-editorSuggestWidget-focusHighlightForeground", + "--vscode-editorSuggestWidget-foreground", + "--vscode-editorSuggestWidget-highlightForeground", + "--vscode-editorSuggestWidget-selectedBackground", + "--vscode-editorSuggestWidget-selectedForeground", + "--vscode-editorSuggestWidget-selectedIconForeground", + "--vscode-editorSuggestWidgetStatus-foreground", + "--vscode-editorUnicodeHighlight-background", + "--vscode-editorUnicodeHighlight-border", + "--vscode-editorUnnecessaryCode-border", + "--vscode-editorUnnecessaryCode-opacity", + "--vscode-editorWarning-background", + "--vscode-editorWarning-border", + "--vscode-editorWarning-foreground", + "--vscode-editorWhitespace-foreground", + "--vscode-editorWidget-background", + "--vscode-editorWidget-border", + "--vscode-editorWidget-foreground", + "--vscode-editorWidget-resizeBorder", + "--vscode-errorForeground", + "--vscode-extensionBadge-remoteBackground", + "--vscode-extensionBadge-remoteForeground", + "--vscode-extensionButton-background", + "--vscode-extensionButton-foreground", + "--vscode-extensionButton-hoverBackground", + "--vscode-extensionButton-prominentBackground", + "--vscode-extensionButton-prominentForeground", + "--vscode-extensionButton-prominentHoverBackground", + "--vscode-extensionButton-separator", + "--vscode-extensionIcon-preReleaseForeground", + "--vscode-extensionIcon-sponsorForeground", + "--vscode-extensionIcon-starForeground", + "--vscode-extensionIcon-verifiedForeground", + "--vscode-focusBorder", + "--vscode-foreground", + "--vscode-icon-foreground", + "--vscode-input-background", + "--vscode-input-border", + "--vscode-input-foreground", + "--vscode-input-placeholderForeground", + "--vscode-inputOption-activeBackground", + "--vscode-inputOption-activeBorder", + "--vscode-inputOption-activeForeground", + "--vscode-inputOption-hoverBackground", + "--vscode-inputValidation-errorBackground", + "--vscode-inputValidation-errorBorder", + "--vscode-inputValidation-errorForeground", + "--vscode-inputValidation-infoBackground", + "--vscode-inputValidation-infoBorder", + "--vscode-inputValidation-infoForeground", + "--vscode-inputValidation-warningBackground", + "--vscode-inputValidation-warningBorder", + "--vscode-inputValidation-warningForeground", + "--vscode-interactive-requestBackground", + "--vscode-interactive-requestBorder", + "--vscode-interactiveEditor-border", + "--vscode-interactiveEditor-regionHighlight", + "--vscode-interactiveEditor-shadow", + "--vscode-interactiveEditorInput-background", + "--vscode-interactiveEditorInput-border", + "--vscode-interactiveEditorInput-focusBorder", + "--vscode-interactiveEditorInput-placeholderForeground", + "--vscode-keybindingLabel-background", + "--vscode-keybindingLabel-border", + "--vscode-keybindingLabel-bottomBorder", + "--vscode-keybindingLabel-foreground", + "--vscode-keybindingTable-headerBackground", + "--vscode-keybindingTable-rowsBackground", + "--vscode-list-activeSelectionBackground", + "--vscode-list-activeSelectionForeground", + "--vscode-list-activeSelectionIconForeground", + "--vscode-list-deemphasizedForeground", + "--vscode-list-dropBackground", + "--vscode-list-errorForeground", + "--vscode-list-filterMatchBackground", + "--vscode-list-filterMatchBorder", + "--vscode-list-focusAndSelectionOutline", + "--vscode-list-focusBackground", + "--vscode-list-focusForeground", + "--vscode-list-focusHighlightForeground", + "--vscode-list-focusOutline", + "--vscode-list-highlightForeground", + "--vscode-list-hoverBackground", + "--vscode-list-hoverForeground", + "--vscode-list-inactiveFocusBackground", + "--vscode-list-inactiveFocusOutline", + "--vscode-list-inactiveSelectionBackground", + "--vscode-list-inactiveSelectionForeground", + "--vscode-list-inactiveSelectionIconForeground", + "--vscode-list-invalidItemForeground", + "--vscode-list-warningForeground", + "--vscode-listFilterWidget-background", + "--vscode-listFilterWidget-noMatchesOutline", + "--vscode-listFilterWidget-outline", + "--vscode-listFilterWidget-shadow", + "--vscode-menu-background", + "--vscode-menu-border", + "--vscode-menu-foreground", + "--vscode-menu-selectionBackground", + "--vscode-menu-selectionBorder", + "--vscode-menu-selectionForeground", + "--vscode-menu-separatorBackground", + "--vscode-menubar-selectionBackground", + "--vscode-menubar-selectionBorder", + "--vscode-menubar-selectionForeground", + "--vscode-merge-border", + "--vscode-merge-commonContentBackground", + "--vscode-merge-commonHeaderBackground", + "--vscode-merge-currentContentBackground", + "--vscode-merge-currentHeaderBackground", + "--vscode-merge-incomingContentBackground", + "--vscode-merge-incomingHeaderBackground", + "--vscode-mergeEditor-change-background", + "--vscode-mergeEditor-change-word-background", + "--vscode-mergeEditor-changeBase-background", + "--vscode-mergeEditor-changeBase-word-background", + "--vscode-mergeEditor-conflict-handled-minimapOverViewRuler", + "--vscode-mergeEditor-conflict-handledFocused-border", + "--vscode-mergeEditor-conflict-handledUnfocused-border", + "--vscode-mergeEditor-conflict-input1-background", + "--vscode-mergeEditor-conflict-input2-background", + "--vscode-mergeEditor-conflict-unhandled-minimapOverViewRuler", + "--vscode-mergeEditor-conflict-unhandledFocused-border", + "--vscode-mergeEditor-conflict-unhandledUnfocused-border", + "--vscode-mergeEditor-conflictingLines-background", + "--vscode-minimap-background", + "--vscode-minimap-errorHighlight", + "--vscode-minimap-findMatchHighlight", + "--vscode-minimap-foregroundOpacity", + "--vscode-minimap-selectionHighlight", + "--vscode-minimap-selectionOccurrenceHighlight", + "--vscode-minimap-warningHighlight", + "--vscode-minimapGutter-addedBackground", + "--vscode-minimapGutter-deletedBackground", + "--vscode-minimapGutter-modifiedBackground", + "--vscode-minimapSlider-activeBackground", + "--vscode-minimapSlider-background", + "--vscode-minimapSlider-hoverBackground", + "--vscode-notebook-cellBorderColor", + "--vscode-notebook-cellEditorBackground", + "--vscode-notebook-cellHoverBackground", + "--vscode-notebook-cellInsertionIndicator", + "--vscode-notebook-cellStatusBarItemHoverBackground", + "--vscode-notebook-cellToolbarSeparator", + "--vscode-notebook-editorBackground", + "--vscode-notebook-focusedCellBackground", + "--vscode-notebook-focusedCellBorder", + "--vscode-notebook-focusedEditorBorder", + "--vscode-notebook-inactiveFocusedCellBorder", + "--vscode-notebook-inactiveSelectedCellBorder", + "--vscode-notebook-outputContainerBackgroundColor", + "--vscode-notebook-outputContainerBorderColor", + "--vscode-notebook-selectedCellBackground", + "--vscode-notebook-selectedCellBorder", + "--vscode-notebook-symbolHighlightBackground", + "--vscode-notebookEditorOverviewRuler-runningCellForeground", + "--vscode-notebookScrollbarSlider-activeBackground", + "--vscode-notebookScrollbarSlider-background", + "--vscode-notebookScrollbarSlider-hoverBackground", + "--vscode-notebookStatusErrorIcon-foreground", + "--vscode-notebookStatusRunningIcon-foreground", + "--vscode-notebookStatusSuccessIcon-foreground", + "--vscode-notificationCenter-border", + "--vscode-notificationCenterHeader-background", + "--vscode-notificationCenterHeader-foreground", + "--vscode-notificationLink-foreground", + "--vscode-notificationToast-border", + "--vscode-notifications-background", + "--vscode-notifications-border", + "--vscode-notifications-foreground", + "--vscode-notificationsErrorIcon-foreground", + "--vscode-notificationsInfoIcon-foreground", + "--vscode-notificationsWarningIcon-foreground", + "--vscode-panel-background", + "--vscode-panel-border", + "--vscode-panel-dropBorder", + "--vscode-panelInput-border", + "--vscode-panelSection-border", + "--vscode-panelSection-dropBackground", + "--vscode-panelSectionHeader-background", + "--vscode-panelSectionHeader-border", + "--vscode-panelSectionHeader-foreground", + "--vscode-panelTitle-activeBorder", + "--vscode-panelTitle-activeForeground", + "--vscode-panelTitle-inactiveForeground", + "--vscode-peekView-border", + "--vscode-peekViewEditor-background", + "--vscode-peekViewEditor-matchHighlightBackground", + "--vscode-peekViewEditor-matchHighlightBorder", + "--vscode-peekViewEditorGutter-background", + "--vscode-peekViewEditorStickyScroll-background", + "--vscode-peekViewResult-background", + "--vscode-peekViewResult-fileForeground", + "--vscode-peekViewResult-lineForeground", + "--vscode-peekViewResult-matchHighlightBackground", + "--vscode-peekViewResult-selectionBackground", + "--vscode-peekViewResult-selectionForeground", + "--vscode-peekViewTitle-background", + "--vscode-peekViewTitleDescription-foreground", + "--vscode-peekViewTitleLabel-foreground", + "--vscode-pickerGroup-border", + "--vscode-pickerGroup-foreground", + "--vscode-ports-iconRunningProcessForeground", + "--vscode-problemsErrorIcon-foreground", + "--vscode-problemsInfoIcon-foreground", + "--vscode-problemsWarningIcon-foreground", + "--vscode-profileBadge-background", + "--vscode-profileBadge-foreground", + "--vscode-progressBar-background", + "--vscode-quickInput-background", + "--vscode-quickInput-foreground", + "--vscode-quickInput-list-focusBackground", + "--vscode-quickInputList-focusBackground", + "--vscode-quickInputList-focusForeground", + "--vscode-quickInputList-focusIconForeground", + "--vscode-quickInputTitle-background", + "--vscode-sash-hoverBorder", + "--vscode-scm-providerBorder", + "--vscode-scrollbar-shadow", + "--vscode-scrollbarSlider-activeBackground", + "--vscode-scrollbarSlider-background", + "--vscode-scrollbarSlider-hoverBackground", + "--vscode-search-resultsInfoForeground", + "--vscode-searchEditor-findMatchBackground", + "--vscode-searchEditor-findMatchBorder", + "--vscode-searchEditor-textInputBorder", + "--vscode-selection-background", + "--vscode-settings-checkboxBackground", + "--vscode-settings-checkboxBorder", + "--vscode-settings-checkboxForeground", + "--vscode-settings-dropdownBackground", + "--vscode-settings-dropdownBorder", + "--vscode-settings-dropdownForeground", + "--vscode-settings-dropdownListBorder", + "--vscode-settings-focusedRowBackground", + "--vscode-settings-focusedRowBorder", + "--vscode-settings-headerBorder", + "--vscode-settings-headerForeground", + "--vscode-settings-modifiedItemIndicator", + "--vscode-settings-numberInputBackground", + "--vscode-settings-numberInputBorder", + "--vscode-settings-numberInputForeground", + "--vscode-settings-rowHoverBackground", + "--vscode-settings-sashBorder", + "--vscode-settings-settingsHeaderHoverForeground", + "--vscode-settings-textInputBackground", + "--vscode-settings-textInputBorder", + "--vscode-settings-textInputForeground", + "--vscode-sideBar-background", + "--vscode-sideBar-border", + "--vscode-sideBar-dropBackground", + "--vscode-sideBar-foreground", + "--vscode-sideBarSectionHeader-background", + "--vscode-sideBarSectionHeader-border", + "--vscode-sideBarSectionHeader-foreground", + "--vscode-sideBarTitle-foreground", + "--vscode-sideBySideEditor-horizontalBorder", + "--vscode-sideBySideEditor-verticalBorder", + "--vscode-statusBar-background", + "--vscode-statusBar-border", + "--vscode-statusBar-debuggingBackground", + "--vscode-statusBar-debuggingBorder", + "--vscode-statusBar-debuggingForeground", + "--vscode-statusBar-focusBorder", + "--vscode-statusBar-foreground", + "--vscode-statusBar-noFolderBackground", + "--vscode-statusBar-noFolderBorder", + "--vscode-statusBar-noFolderForeground", + "--vscode-statusBarItem-activeBackground", + "--vscode-statusBarItem-compactHoverBackground", + "--vscode-statusBarItem-errorBackground", + "--vscode-statusBarItem-errorForeground", + "--vscode-statusBarItem-focusBorder", + "--vscode-statusBarItem-hoverBackground", + "--vscode-statusBarItem-prominentBackground", + "--vscode-statusBarItem-prominentForeground", + "--vscode-statusBarItem-prominentHoverBackground", + "--vscode-statusBarItem-remoteBackground", + "--vscode-statusBarItem-remoteForeground", + "--vscode-statusBarItem-warningBackground", + "--vscode-statusBarItem-warningForeground", + "--vscode-symbolIcon-arrayForeground", + "--vscode-symbolIcon-booleanForeground", + "--vscode-symbolIcon-classForeground", + "--vscode-symbolIcon-colorForeground", + "--vscode-symbolIcon-constantForeground", + "--vscode-symbolIcon-constructorForeground", + "--vscode-symbolIcon-enumeratorForeground", + "--vscode-symbolIcon-enumeratorMemberForeground", + "--vscode-symbolIcon-eventForeground", + "--vscode-symbolIcon-fieldForeground", + "--vscode-symbolIcon-fileForeground", + "--vscode-symbolIcon-folderForeground", + "--vscode-symbolIcon-functionForeground", + "--vscode-symbolIcon-interfaceForeground", + "--vscode-symbolIcon-keyForeground", + "--vscode-symbolIcon-keywordForeground", + "--vscode-symbolIcon-methodForeground", + "--vscode-symbolIcon-moduleForeground", + "--vscode-symbolIcon-namespaceForeground", + "--vscode-symbolIcon-nullForeground", + "--vscode-symbolIcon-numberForeground", + "--vscode-symbolIcon-objectForeground", + "--vscode-symbolIcon-operatorForeground", + "--vscode-symbolIcon-packageForeground", + "--vscode-symbolIcon-propertyForeground", + "--vscode-symbolIcon-referenceForeground", + "--vscode-symbolIcon-snippetForeground", + "--vscode-symbolIcon-stringForeground", + "--vscode-symbolIcon-structForeground", + "--vscode-symbolIcon-textForeground", + "--vscode-symbolIcon-typeParameterForeground", + "--vscode-symbolIcon-unitForeground", + "--vscode-symbolIcon-variableForeground", + "--vscode-tab-activeBackground", + "--vscode-tab-activeBorder", + "--vscode-tab-activeBorderTop", + "--vscode-tab-activeForeground", + "--vscode-tab-activeModifiedBorder", + "--vscode-tab-border", + "--vscode-tab-hoverBackground", + "--vscode-tab-hoverBorder", + "--vscode-tab-hoverForeground", + "--vscode-tab-inactiveBackground", + "--vscode-tab-inactiveForeground", + "--vscode-tab-inactiveModifiedBorder", + "--vscode-tab-lastPinnedBorder", + "--vscode-tab-unfocusedActiveBackground", + "--vscode-tab-unfocusedActiveBorder", + "--vscode-tab-unfocusedActiveBorderTop", + "--vscode-tab-unfocusedActiveForeground", + "--vscode-tab-unfocusedActiveModifiedBorder", + "--vscode-tab-unfocusedHoverBackground", + "--vscode-tab-unfocusedHoverBorder", + "--vscode-tab-unfocusedHoverForeground", + "--vscode-tab-unfocusedInactiveBackground", + "--vscode-tab-unfocusedInactiveForeground", + "--vscode-tab-unfocusedInactiveModifiedBorder", + "--vscode-terminal-ansiBlack", + "--vscode-terminal-ansiBlue", + "--vscode-terminal-ansiBrightBlack", + "--vscode-terminal-ansiBrightBlue", + "--vscode-terminal-ansiBrightCyan", + "--vscode-terminal-ansiBrightGreen", + "--vscode-terminal-ansiBrightMagenta", + "--vscode-terminal-ansiBrightRed", + "--vscode-terminal-ansiBrightWhite", + "--vscode-terminal-ansiBrightYellow", + "--vscode-terminal-ansiCyan", + "--vscode-terminal-ansiGreen", + "--vscode-terminal-ansiMagenta", + "--vscode-terminal-ansiRed", + "--vscode-terminal-ansiWhite", + "--vscode-terminal-ansiYellow", + "--vscode-terminal-background", + "--vscode-terminal-border", + "--vscode-terminal-dropBackground", + "--vscode-terminal-findMatchBackground", + "--vscode-terminal-findMatchBorder", + "--vscode-terminal-findMatchHighlightBackground", + "--vscode-terminal-findMatchHighlightBorder", + "--vscode-terminal-foreground", + "--vscode-terminal-hoverHighlightBackground", + "--vscode-terminal-inactiveSelectionBackground", + "--vscode-terminal-selectionBackground", + "--vscode-terminal-selectionForeground", + "--vscode-terminal-tab-activeBorder", + "--vscode-terminalCommandDecoration-defaultBackground", + "--vscode-terminalCommandDecoration-errorBackground", + "--vscode-terminalCommandDecoration-successBackground", + "--vscode-terminalCursor-background", + "--vscode-terminalCursor-foreground", + "--vscode-terminalOverviewRuler-cursorForeground", + "--vscode-terminalOverviewRuler-findMatchForeground", + "--vscode-testing-iconErrored", + "--vscode-testing-iconFailed", + "--vscode-testing-iconPassed", + "--vscode-testing-iconQueued", + "--vscode-testing-iconSkipped", + "--vscode-testing-iconUnset", + "--vscode-testing-message-error-decorationForeground", + "--vscode-testing-message-error-lineBackground", + "--vscode-testing-message-info-decorationForeground", + "--vscode-testing-message-info-lineBackground", + "--vscode-testing-peekBorder", + "--vscode-testing-peekHeaderBackground", + "--vscode-testing-runAction", + "--vscode-textBlockQuote-background", + "--vscode-textBlockQuote-border", + "--vscode-textCodeBlock-background", + "--vscode-textLink-activeForeground", + "--vscode-textLink-foreground", + "--vscode-textPreformat-foreground", + "--vscode-textSeparator-foreground", + "--vscode-titleBar-activeBackground", + "--vscode-titleBar-activeForeground", + "--vscode-titleBar-border", + "--vscode-titleBar-inactiveBackground", + "--vscode-titleBar-inactiveForeground", + "--vscode-toolbar-activeBackground", + "--vscode-toolbar-hoverBackground", + "--vscode-toolbar-hoverOutline", + "--vscode-tree-inactiveIndentGuidesStroke", + "--vscode-tree-indentGuidesStroke", + "--vscode-tree-tableColumnsBorder", + "--vscode-tree-tableOddRowsBackground", + "--vscode-walkThrough-embeddedEditorBackground", + "--vscode-walkthrough-stepTitle-foreground", + "--vscode-welcomePage-background", + "--vscode-welcomePage-progress-background", + "--vscode-welcomePage-progress-foreground", + "--vscode-welcomePage-tileBackground", + "--vscode-welcomePage-tileBorder", + "--vscode-welcomePage-tileHoverBackground", + "--vscode-widget-border", + "--vscode-widget-shadow", + "--vscode-window-activeBorder", + "--vscode-window-inactiveBorder" + ], + "others": [ + "--background-dark", + "--background-light", + "--dropdown-padding-bottom", + "--dropdown-padding-top", + "--insert-border-color", + "--last-tab-margin-right", + "--monaco-monospace-font", + "--monaco-monospace-font", + "--notebook-cell-input-preview-font-family", + "--notebook-cell-input-preview-font-size", + "--notebook-cell-output-font-size", + "--notebook-diff-view-viewport-slider", + "--notebook-find-horizontal-padding", + "--notebook-find-width", + "--outline-element-color", + "--separator-border", + "--status-border-top-color", + "--tab-border-bottom-color", + "--tab-border-top-color", + "--tab-dirty-border-top-color", + "--tabs-border-bottom-color", + "--testMessageDecorationFontFamily", + "--testMessageDecorationFontSize", + "--title-border-bottom-color", + "--vscode-editorCodeLens-fontFamily", + "--vscode-editorCodeLens-fontFamilyDefault", + "--vscode-editorCodeLens-fontFeatureSettings", + "--vscode-editorCodeLens-fontSize", + "--vscode-editorCodeLens-lineHeight", + "--vscode-explorer-align-offset-margin-left", + "--vscode-interactive-result-editor-background-color", + "--vscode-repl-font-family", + "--vscode-repl-font-size-for-twistie", + "--vscode-repl-font-size", + "--vscode-repl-line-height", + "--vscode-sash-hover-size", + "--vscode-sash-size", + "--window-border-color", + "--workspace-trust-check-color", + "--workspace-trust-selected-color", + "--workspace-trust-unselected-color", + "--workspace-trust-x-color", + "--z-index-notebook-cell-bottom-toolbar-container", + "--z-index-notebook-cell-editor-outline", + "--z-index-notebook-cell-expand-part-button", + "--z-index-notebook-cell-output-toolbar", + "--z-index-notebook-cell-status", + "--z-index-notebook-cell-toolbar-dropdown-active", + "--z-index-notebook-cell-toolbar", + "--z-index-notebook-folding-indicator", + "--z-index-notebook-input-collapse-condicon", + "--z-index-notebook-list-insertion-indicator", + "--z-index-notebook-output", + "--z-index-notebook-progress-bar", + "--z-index-notebook-scrollbar", + "--z-index-run-button-container", + "--zoom-factor" + ] +} \ No newline at end of file diff --git a/build/lib/util.js b/build/lib/util.js index dd1ef2685d6..9ac562f4640 100644 --- a/build/lib/util.js +++ b/build/lib/util.js @@ -369,7 +369,7 @@ function createExternalLoaderConfig(webEndpoint, commit, quality) { webEndpoint = webEndpoint + `/${quality}/${commit}`; const nodePaths = acquireWebNodePaths(); Object.keys(nodePaths).map(function (key, _) { - nodePaths[key] = `${webEndpoint}/node_modules/${key}/${nodePaths[key]}`; + nodePaths[key] = `../node_modules/${key}/${nodePaths[key]}`; }); const externalLoaderConfig = { baseUrl: `${webEndpoint}/out`, @@ -400,4 +400,4 @@ function buildWebNodePaths(outDir) { return result; } exports.buildWebNodePaths = buildWebNodePaths; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcsbUNBQW1DO0FBQ25DLHNDQUF1QztBQUN2Qyx1Q0FBdUM7QUFDdkMsc0NBQXNDO0FBQ3RDLDZCQUE2QjtBQUM3Qix5QkFBeUI7QUFDekIsa0NBQWtDO0FBQ2xDLG1DQUFtQztBQUduQyw2QkFBb0M7QUFDcEMsZ0RBQWdEO0FBRWhELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBTW5ELE1BQU0sbUJBQW1CLEdBQXVCLEVBQUUsdUJBQXVCLEVBQUUsR0FBRyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7QUFNekYsU0FBZ0IsV0FBVyxDQUFDLGNBQStCLEVBQUUsT0FBK0IsRUFBRSxvQkFBOEI7SUFDM0gsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzNCLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM1QixJQUFJLEtBQUssR0FBRyxNQUFNLENBQUM7SUFDbkIsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVqQyxNQUFNLEtBQUssR0FBbUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLHVCQUF1QixFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO0lBRXBKLE1BQU0sR0FBRyxHQUFHLENBQUMsS0FBNkIsRUFBRSxhQUFzQixFQUFFLEVBQUU7UUFDckUsS0FBSyxHQUFHLFNBQVMsQ0FBQztRQUVsQixNQUFNLE1BQU0sR0FBRyxDQUFDLG9CQUFvQixDQUFDLENB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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcsbUNBQW1DO0FBQ25DLHNDQUF1QztBQUN2Qyx1Q0FBdUM7QUFDdkMsc0NBQXNDO0FBQ3RDLDZCQUE2QjtBQUM3Qix5QkFBeUI7QUFDekIsa0NBQWtDO0FBQ2xDLG1DQUFtQztBQUduQyw2QkFBb0M7QUFDcEMsZ0RBQWdEO0FBRWhELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBTW5ELE1BQU0sbUJBQW1CLEdBQXVCLEVBQUUsdUJBQXVCLEVBQUUsR0FBRyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7QUFNekYsU0FBZ0IsV0FBVyxDQUFDLGNBQStCLEVBQUUsT0FBK0IsRUFBRSxvQkFBOEI7SUFDM0gsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzNCLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM1QixJQUFJLEtBQUssR0FBRyxNQUFNLENBQUM7SUFDbkIsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVqQyxNQUFNLEtBQUssR0FBbUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLHVCQUF1QixFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO0lBRXBKLE1BQU0sR0FBRyxHQUFHLENBQUMsS0FBNkIsRUFBRSxhQUFzQixFQUFFLEVBQUU7UUFDckUsS0FBSyxHQUFHLFNBQVMsQ0FBQztRQUVsQixNQUFNLE1BQU0sR0FBRyxDQUFDLG9CQUFvQixDQUFDLENB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 \ No newline at end of file diff --git a/build/lib/util.ts b/build/lib/util.ts index bdc2ce388de..004f131e2fb 100644 --- a/build/lib/util.ts +++ b/build/lib/util.ts @@ -440,16 +440,22 @@ export function acquireWebNodePaths() { return nodePaths; } -export function createExternalLoaderConfig(webEndpoint?: string, commit?: string, quality?: string) { +export interface IExternalLoaderInfo { + baseUrl: string; + paths: { [moduleId: string]: string }; + [key: string]: any; +} + +export function createExternalLoaderConfig(webEndpoint?: string, commit?: string, quality?: string): IExternalLoaderInfo | undefined { if (!webEndpoint || !commit || !quality) { return undefined; } webEndpoint = webEndpoint + `/${quality}/${commit}`; const nodePaths = acquireWebNodePaths(); Object.keys(nodePaths).map(function (key, _) { - nodePaths[key] = `${webEndpoint}/node_modules/${key}/${nodePaths[key]}`; + nodePaths[key] = `../node_modules/${key}/${nodePaths[key]}`; }); - const externalLoaderConfig = { + const externalLoaderConfig: IExternalLoaderInfo = { baseUrl: `${webEndpoint}/out`, recordStats: true, paths: nodePaths diff --git a/build/linux/debian/dep-lists.js b/build/linux/debian/dep-lists.js index 128f963ed8f..138c42862b0 100644 --- a/build/linux/debian/dep-lists.js +++ b/build/linux/debian/dep-lists.js @@ -28,11 +28,9 @@ exports.referenceGeneratedDepsByArch = { 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.14)', - 'libc6 (>= 2.15)', 'libc6 (>= 2.17)', 'libc6 (>= 2.2.5)', 'libcairo2 (>= 1.6.0)', - 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', 'libdrm2 (>= 2.4.38)', @@ -65,12 +63,10 @@ exports.referenceGeneratedDepsByArch = { 'libatk-bridge2.0-0 (>= 2.5.3)', 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', - 'libc6 (>= 2.15)', 'libc6 (>= 2.17)', 'libc6 (>= 2.4)', 'libc6 (>= 2.9)', 'libcairo2 (>= 1.6.0)', - 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', 'libdrm2 (>= 2.4.38)', @@ -86,6 +82,7 @@ exports.referenceGeneratedDepsByArch = { 'libpango-1.0-0 (>= 1.14.0)', 'libsecret-1-0 (>= 0.18)', 'libstdc++6 (>= 4.1.1)', + 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', 'libx11-6', @@ -108,7 +105,6 @@ exports.referenceGeneratedDepsByArch = { 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.17)', 'libcairo2 (>= 1.6.0)', - 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.0.2)', 'libdrm2 (>= 2.4.38)', @@ -127,6 +123,7 @@ exports.referenceGeneratedDepsByArch = { 'libpango-1.0-0 (>= 1.14.0)', 'libsecret-1-0 (>= 0.18)', 'libstdc++6 (>= 4.1.1)', + 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', 'libx11-6', @@ -142,4 +139,4 @@ exports.referenceGeneratedDepsByArch = { 'xdg-utils (>= 1.0.2)' ] }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwLWxpc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGVwLWxpc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7O0FBRWhHLGtIQUFrSDtBQUNsSCw0REFBNEQ7QUFDL0MsUUFBQSxjQUFjLEdBQUc7SUFDN0IsaUJBQWlCO0lBQ2pCLHFDQUFxQztJQUNyQyxtQkFBbUI7SUFDbkIsc0RBQXNEO0lBQ3RELHNCQUFzQixDQUFDLGlCQUFpQjtDQUN4QyxDQUFDO0FBRUYsb0hBQW9IO0FBQ3BILDBDQUEwQztBQUMxQyw4REFBOEQ7QUFDakQsUUFBQSxlQUFlLEdBQUc7SUFDOUIsWUFBWSxDQUFDLHlFQUF5RTtDQUN0RixDQUFDO0FBRVcsUUFBQSw0QkFBNEIsR0FBRztJQUMzQyxPQUFPLEVBQUU7UUFDUixpQkFBaUI7UUFDakIsd0JBQXdCO1FBQ3hCLCtCQUErQjtRQUMvQix3QkFBd0I7UUFDeEIsMkJBQTJCO1FBQzNCLGlCQUFpQjtRQUNqQixpQkFBaUI7UUFDakIsaUJBQWlCO1FBQ2pCLGtCQUFrQjtRQUNsQixzQkFBc0I7UUFDdEIscUJBQXFCO1FBQ3JCLHNEQUFzRDtRQUN0RCx5QkFBeUI7UUFDekIscUJBQXFCO1FBQ3JCLHNCQUFzQjtRQUN0QixvQkFBb0I7UUFDcEIsMEJBQTBCO1FBQzFCLDBCQUEwQjtRQUMxQix3QkFBd0I7UUFDeEIscUNBQXFDO1FBQ3JDLHdCQUF3QjtRQUN4QixxQkFBcUI7UUFDckIsbUJBQW1CO1FBQ25CLDRCQUE0QjtRQUM1Qix5QkFBeUI7UUFDekIsVUFBVTtRQUNWLDBCQUEwQjtRQUMxQixvQkFBb0I7UUFDcEIsK0JBQStCO1FBQy9CLHdCQUF3QjtRQUN4QixVQUFVO1FBQ1YsWUFBWTtRQUNaLDBCQUEwQjtRQUMxQixhQUFhO1FBQ2IsWUFBWTtRQUNaLHNCQUFzQjtLQUN0QjtJQUNELE9BQU8sRUFBRTtRQUNSLGlCQUFpQjtRQUNqQix3QkFBd0I7UUFDeEIsK0JBQStCO1FBQy9CLHdCQUF3QjtRQUN4QiwyQkFBMkI7UUFDM0IsaUJBQWlCO1FBQ2pCLGlCQUFpQjtRQUNqQixnQkFBZ0I7UUFDaEIsZ0JBQWdCO1FBQ2hCLHNCQUFzQjtRQUN0QixxQkFBcUI7UUFDckIsc0RBQXNEO1FBQ3RELHlCQUF5QjtRQUN6QixxQkFBcUI7UUFDckIsc0JBQXNCO1FBQ3RCLG9CQUFvQjtRQUNwQiwwQkFBMEI7UUFDMUIsMEJBQTBCO1FBQzFCLHdCQUF3QjtRQUN4QixxQ0FBcUM7UUFDckMsd0JBQXdCO1FBQ3hCLHFCQUFxQjtRQUNyQixtQkFBbUI7UUFDbkIsNEJBQTRCO1FBQzVCLHlCQUF5QjtRQUN6Qix1QkFBdUI7UUFDdkIscUJBQXFCO1FBQ3JCLG1CQUFtQjtRQUNuQixVQUFVO1FBQ1YsMEJBQTBCO1FBQzFCLG9CQUFvQjtRQUNwQiwrQkFBK0I7UUFDL0Isd0JBQXdCO1FBQ3hCLFVBQVU7UUFDVixZQUFZO1FBQ1osMEJBQTBCO1FBQzFCLGFBQWE7UUFDYixZQUFZO1FBQ1osc0JBQXNCO0tBQ3RCO0lBQ0QsT0FBTyxFQUFFO1FBQ1IsaUJBQWlCO1FBQ2pCLHdCQUF3QjtRQUN4QiwrQkFBK0I7UUFDL0Isd0JBQXdCO1FBQ3hCLDJCQUEyQjtRQUMzQixpQkFBaUI7UUFDakIsc0JBQXNCO1FBQ3RCLHFCQUFxQjtRQUNyQixzREFBc0Q7UUFDdEQsd0JBQXdCO1FBQ3hCLHFCQUFxQjtRQUNyQixzQkFBc0I7UUFDdEIsb0JBQW9CO1FBQ3BCLG9CQUFvQjtRQUNwQixvQkFBb0I7UUFDcEIsb0JBQW9CO1FBQ3BCLDBCQUEwQjtRQUMxQiwwQkFBMEI7UUFDMUIsd0JBQXdCO1FBQ3hCLHFDQUFxQztRQUNyQyx3QkFBd0I7UUFDeEIscUJBQXFCO1FBQ3JCLG1CQUFtQjtRQUNuQiw0QkFBNEI7UUFDNUIseUJBQXlCO1FBQ3pCLHVCQUF1QjtRQUN2QixxQkFBcUI7UUFDckIsbUJBQW1CO1FBQ25CLFVBQVU7UUFDViwwQkFBMEI7UUFDMUIsb0JBQW9CO1FBQ3BCLCtCQUErQjtRQUMvQix3QkFBd0I7UUFDeEIsVUFBVTtRQUNWLFlBQVk7UUFDWiwwQkFBMEI7UUFDMUIsYUFBYTtRQUNiLFlBQVk7UUFDWixzQkFBc0I7S0FDdEI7Q0FDRCxDQUFDIn0= \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwLWxpc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGVwLWxpc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7O0FBRWhHLGtIQUFrSDtBQUNsSCw0REFBNEQ7QUFDL0MsUUFBQSxjQUFjLEdBQUc7SUFDN0IsaUJBQWlCO0lBQ2pCLHFDQUFxQztJQUNyQyxtQkFBbUI7SUFDbkIsc0RBQXNEO0lBQ3RELHNCQUFzQixDQUFDLGlCQUFpQjtDQUN4QyxDQUFDO0FBRUYsb0hBQW9IO0FBQ3BILDBDQUEwQztBQUMxQyw4REFBOEQ7QUFDakQsUUFBQSxlQUFlLEdBQUc7SUFDOUIsWUFBWSxDQUFDLHlFQUF5RTtDQUN0RixDQUFDO0FBRVcsUUFBQSw0QkFBNEIsR0FBRztJQUMzQyxPQUFPLEVBQUU7UUFDUixpQkFBaUI7UUFDakIsd0JBQXdCO1FBQ3hCLCtCQUErQjtRQUMvQix3QkFBd0I7UUFDeEIsMkJBQTJCO1FBQzNCLGlCQUFpQjtRQUNqQixpQkFBaUI7UUFDakIsa0JBQWtCO1FBQ2xCLHNCQUFzQjtRQUN0QixzREFBc0Q7UUFDdEQseUJBQXlCO1FBQ3pCLHFCQUFxQjtRQUNyQixzQkFBc0I7UUFDdEIsb0JBQW9CO1FBQ3BCLDBCQUEwQjtRQUMxQiwwQkFBMEI7UUFDMUIsd0JBQXdCO1FBQ3hCLHFDQUFxQztRQUNyQyx3QkFBd0I7UUFDeEIscUJBQXFCO1FBQ3JCLG1CQUFtQjtRQUNuQiw0QkFBNEI7UUFDNUIseUJBQXlCO1FBQ3pCLFVBQVU7UUFDViwwQkFBMEI7UUFDMUIsb0JBQW9CO1FBQ3BCLCtCQUErQjtRQUMvQix3QkFBd0I7UUFDeEIsVUFBVTtRQUNWLFlBQVk7UUFDWiwwQkFBMEI7UUFDMUIsYUFBYTtRQUNiLFlBQVk7UUFDWixzQkFBc0I7S0FDdEI7SUFDRCxPQUFPLEVBQUU7UUFDUixpQkFBaUI7UUFDakIsd0JBQXdCO1FBQ3hCLCtCQUErQjtRQUMvQix3QkFBd0I7UUFDeEIsMkJBQTJCO1FBQzNCLGlCQUFpQjtRQUNqQixnQkFBZ0I7UUFDaEIsZ0JBQWdCO1FBQ2hCLHNCQUFzQjtRQUN0QixzREFBc0Q7UUFDdEQseUJBQXlCO1FBQ3pCLHFCQUFxQjtRQUNyQixzQkFBc0I7UUFDdEIsb0JBQW9CO1FBQ3BCLDBCQUEwQjtRQUMxQiwwQkFBMEI7UUFDMUIsd0JBQXdCO1FBQ3hCLHFDQUFxQztRQUNyQyx3QkFBd0I7UUFDeEIscUJBQXFCO1FBQ3JCLG1CQUFtQjtRQUNuQiw0QkFBNEI7UUFDNUIseUJBQXlCO1FBQ3pCLHVCQUF1QjtRQUN2QixtQkFBbUI7UUFDbkIscUJBQXFCO1FBQ3JCLG1CQUFtQjtRQUNuQixVQUFVO1FBQ1YsMEJBQTBCO1FBQzFCLG9CQUFvQjtRQUNwQiwrQkFBK0I7UUFDL0Isd0JBQXdCO1FBQ3hCLFVBQVU7UUFDVixZQUFZO1FBQ1osMEJBQTBCO1FBQzFCLGFBQWE7UUFDYixZQUFZO1FBQ1osc0JBQXNCO0tBQ3RCO0lBQ0QsT0FBTyxFQUFFO1FBQ1IsaUJBQWlCO1FBQ2pCLHdCQUF3QjtRQUN4QiwrQkFBK0I7UUFDL0Isd0JBQXdCO1FBQ3hCLDJCQUEyQjtRQUMzQixpQkFBaUI7UUFDakIsc0JBQXNCO1FBQ3RCLHNEQUFzRDtRQUN0RCx3QkFBd0I7UUFDeEIscUJBQXFCO1FBQ3JCLHNCQUFzQjtRQUN0QixvQkFBb0I7UUFDcEIsb0JBQW9CO1FBQ3BCLG9CQUFvQjtRQUNwQixvQkFBb0I7UUFDcEIsMEJBQTBCO1FBQzFCLDBCQUEwQjtRQUMxQix3QkFBd0I7UUFDeEIscUNBQXFDO1FBQ3JDLHdCQUF3QjtRQUN4QixxQkFBcUI7UUFDckIsbUJBQW1CO1FBQ25CLDRCQUE0QjtRQUM1Qix5QkFBeUI7UUFDekIsdUJBQXVCO1FBQ3ZCLG1CQUFtQjtRQUNuQixxQkFBcUI7UUFDckIsbUJBQW1CO1FBQ25CLFVBQVU7UUFDViwwQkFBMEI7UUFDMUIsb0JBQW9CO1FBQ3BCLCtCQUErQjtRQUMvQix3QkFBd0I7UUFDeEIsVUFBVTtRQUNWLFlBQVk7UUFDWiwwQkFBMEI7UUFDMUIsYUFBYTtRQUNiLFlBQVk7UUFDWixzQkFBc0I7S0FDdEI7Q0FDRCxDQUFDIn0= \ No newline at end of file diff --git a/build/linux/debian/dep-lists.ts b/build/linux/debian/dep-lists.ts index 2aaa62073b8..63b14bf16f0 100644 --- a/build/linux/debian/dep-lists.ts +++ b/build/linux/debian/dep-lists.ts @@ -28,11 +28,9 @@ export const referenceGeneratedDepsByArch = { 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.14)', - 'libc6 (>= 2.15)', 'libc6 (>= 2.17)', 'libc6 (>= 2.2.5)', 'libcairo2 (>= 1.6.0)', - 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', 'libdrm2 (>= 2.4.38)', @@ -65,12 +63,10 @@ export const referenceGeneratedDepsByArch = { 'libatk-bridge2.0-0 (>= 2.5.3)', 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', - 'libc6 (>= 2.15)', 'libc6 (>= 2.17)', 'libc6 (>= 2.4)', 'libc6 (>= 2.9)', 'libcairo2 (>= 1.6.0)', - 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', 'libdrm2 (>= 2.4.38)', @@ -86,6 +82,7 @@ export const referenceGeneratedDepsByArch = { 'libpango-1.0-0 (>= 1.14.0)', 'libsecret-1-0 (>= 0.18)', 'libstdc++6 (>= 4.1.1)', + 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', 'libx11-6', @@ -108,7 +105,6 @@ export const referenceGeneratedDepsByArch = { 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.17)', 'libcairo2 (>= 1.6.0)', - 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.0.2)', 'libdrm2 (>= 2.4.38)', @@ -127,6 +123,7 @@ export const referenceGeneratedDepsByArch = { 'libpango-1.0-0 (>= 1.14.0)', 'libsecret-1-0 (>= 0.18)', 'libstdc++6 (>= 4.1.1)', + 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', 'libx11-6', diff --git a/build/linux/rpm/dep-lists.js b/build/linux/rpm/dep-lists.js index 304758732d3..b772f23eeb3 100644 --- a/build/linux/rpm/dep-lists.js +++ b/build/linux/rpm/dep-lists.js @@ -53,7 +53,6 @@ exports.referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.8)(64bit)', 'libc.so.6(GLIBC_2.9)(64bit)', 'libcairo.so.2()(64bit)', - 'libcups.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdl.so.2()(64bit)', @@ -134,7 +133,6 @@ exports.referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.8)', 'libc.so.6(GLIBC_2.9)', 'libcairo.so.2', - 'libcups.so.2', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3', 'libdl.so.2', @@ -223,7 +221,6 @@ exports.referenceGeneratedDepsByArch = { 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', 'libcairo.so.2()(64bit)', - 'libcups.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdbus-1.so.3(LIBDBUS_1_3)(64bit)', @@ -292,4 +289,4 @@ exports.referenceGeneratedDepsByArch = { 'xdg-utils' ] }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwLWxpc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGVwLWxpc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7O0FBRWhHLCtHQUErRztBQUMvRywrREFBK0Q7QUFDbEQsUUFBQSxjQUFjLEdBQUc7SUFDN0IsaUJBQWlCO0lBQ2pCLHdCQUF3QjtJQUN4Qiw2QkFBNkI7SUFDN0IsNkJBQTZCO0lBQzdCLGdDQUFnQztJQUNoQyx5QkFBeUI7SUFDekIsdUJBQXVCO0lBQ3ZCLFdBQVcsQ0FBQyxpQkFBaUI7Q0FDN0IsQ0FBQztBQUVXLFFBQUEsNEJBQTRCLEdBQUc7SUFDM0MsUUFBUSxFQUFFO1FBQ1QsaUJBQWlCO1FBQ2pCLCtCQUErQjtRQUMvQiwwQ0FBMEM7UUFDMUMsd0NBQXdDO1FBQ3hDLHNCQUFzQjtRQUN0Qiw2QkFBNkI7UUFDN0IsMEJBQTBCO1FBQzFCLHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIseUJBQXlCO1FBQ3pCLHlCQUF5QjtRQUN6QixpQ0FBaUM7UUFDakMsc0NBQXNDO1FBQ3RDLDBCQUEwQjtRQUMxQixpQ0FBaUM7UUFDakMsd0JBQXdCO1FBQ3hCLG9CQUFvQjtRQUNwQiw4QkFBOEI7UUFDOUIsOEJBQThCO1FBQzlCLDhCQUE4QjtRQUM5Qiw4QkFBOEI7UUFDOUIsOEJBQThCO1FBQzlCLDhCQUE4QjtRQUM5QiwrQkFBK0I7UUFDL0IsNkJBQTZCO1FBQzdCLCtCQUErQjtRQUMvQiwrQkFBK0I7UUFDL0IsK0JBQStCO1FBQy9CLDZCQUE2QjtRQUM3Qiw2QkFBNkI7UUFDN0IsNkJBQTZCO1FBQzdCLDZCQUE2QjtRQUM3Qiw2QkFBNkI7UUFDN0Isd0JBQXdCO1FBQ3hCLHVCQUF1QjtRQUN2Qix1QkFBdUI7UUFDdkIseUJBQXlCO1FBQ3pCLHFCQUFxQjtRQUNyQixnQ0FBZ0M7UUFDaEMsc0JBQXNCO1FBQ3RCLHdCQUF3QjtRQUN4QixzQkFBc0I7UUFDdEIsd0JBQXdCO1FBQ3hCLCtCQUErQjtR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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwLWxpc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGVwLWxpc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O2dHQUdnRzs7O0FBRWhHLCtHQUErRztBQUMvRywrREFBK0Q7QUFDbEQsUUFBQSxjQUFjLEdBQUc7SUFDN0IsaUJBQWlCO0lBQ2pCLHdCQUF3QjtJQUN4Qiw2QkFBNkI7SUFDN0IsNkJBQTZCO0lBQzdCLGdDQUFnQztJQUNoQyx5QkFBeUI7SUFDekIsdUJBQXVCO0lBQ3ZCLFdBQVcsQ0FBQyxpQkFBaUI7Q0FDN0IsQ0FBQztBQUVXLFFBQUEsNEJBQTRCLEdBQUc7SUFDM0MsUUFBUSxFQUFFO1FBQ1QsaUJBQWlCO1FBQ2pCLCtCQUErQjtRQUMvQiwwQ0FBMEM7UUFDMUMsd0NBQXdDO1FBQ3hDLHNCQUFzQjtRQUN0Qiw2QkFBNkI7UUFDN0IsMEJBQTBCO1FBQzFCLHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIseUJBQXlCO1FBQ3pCLHlCQUF5QjtRQUN6QixpQ0FBaUM7UUFDakMsc0NBQXNDO1FBQ3RDLDBCQUEwQjtRQUMxQixpQ0FBaUM7UUFDakMsd0JBQXdCO1FBQ3hCLG9CQUFvQjtRQUNwQiw4QkFBOEI7UUFDOUIsOEJBQThCO1FBQzlCLDhCQUE4QjtRQUM5Qiw4QkFBOEI7UUFDOUIsOEJBQThCO1FBQzlCLDhCQUE4QjtRQUM5QiwrQkFBK0I7UUFDL0IsNkJBQTZCO1FBQzdCLCtCQUErQjtRQUMvQiwrQkFBK0I7UUFDL0IsK0JBQStCO1FBQy9CLDZCQUE2QjtRQUM3Qiw2QkFBNkI7UUFDN0IsNkJBQTZCO1FBQzdCLDZCQUE2QjtRQUM3Qiw2QkFBNkI7UUFDN0Isd0JBQXdCO1FBQ3hCLHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIscUJBQXFCO1FBQ3JCLGdDQUFnQztRQUNoQyxzQkFBc0I7UUFDdEIsd0JBQXdCO1FBQ3hCLHNCQUFzQjtRQUN0Qix3QkFBd0I7UUFDeEIsK0JBQStCO1FBQy9CLDBCQUEwQjtR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 \ No newline at end of file diff --git a/build/linux/rpm/dep-lists.ts b/build/linux/rpm/dep-lists.ts index 7df703fa060..d80c86416a6 100644 --- a/build/linux/rpm/dep-lists.ts +++ b/build/linux/rpm/dep-lists.ts @@ -52,7 +52,6 @@ export const referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.8)(64bit)', 'libc.so.6(GLIBC_2.9)(64bit)', 'libcairo.so.2()(64bit)', - 'libcups.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdl.so.2()(64bit)', @@ -133,7 +132,6 @@ export const referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.8)', 'libc.so.6(GLIBC_2.9)', 'libcairo.so.2', - 'libcups.so.2', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3', 'libdl.so.2', @@ -222,7 +220,6 @@ export const referenceGeneratedDepsByArch = { 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', 'libcairo.so.2()(64bit)', - 'libcups.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdbus-1.so.3(LIBDBUS_1_3)(64bit)', diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index 2e36edaec68..37f23486ca0 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -74,7 +74,8 @@ export interface ICommandHandler { #includeAll(vs/editor/common/model): IScrollEvent #include(vs/editor/common/diff/smartLinesDiffComputer): IChange, ICharChange, ILineChange #include(vs/editor/common/diff/documentDiffProvider): IDocumentDiffProvider, IDocumentDiffProviderOptions, IDocumentDiff -#include(vs/editor/common/diff/linesDiffComputer): LineRangeMapping, LineRange, RangeMapping +#include(vs/editor/common/core/lineRange): LineRange +#include(vs/editor/common/diff/linesDiffComputer): LineRangeMapping, RangeMapping #include(vs/editor/common/core/dimension): IDimension #includeAll(vs/editor/common/editorCommon): IScrollEvent #includeAll(vs/editor/common/textModelEvents): @@ -84,6 +85,7 @@ export interface ICommandHandler { #include(vs/editor/browser/config/editorConfiguration): IEditorConstructionOptions #includeAll(vs/editor/browser/editorBrowser;editorCommon.=>): #include(vs/editor/common/config/fontInfo): FontInfo, BareFontInfo +#include(vs/editor/common/config/editorZoom): EditorZoom, IEditorZoom //compatibility: export type IReadOnlyModel = ITextModel; diff --git a/build/npm/update-localization-extension.js b/build/npm/update-localization-extension.js index b78674a7099..6274323f747 100644 --- a/build/npm/update-localization-extension.js +++ b/build/npm/update-localization-extension.js @@ -23,6 +23,10 @@ function update(options) { if (location !== undefined && !fs.existsSync(location)) { throw new Error(`${location} doesn't exist.`); } + let externalExtensionsLocation = options.externalExtensionsLocation; + if (externalExtensionsLocation !== undefined && !fs.existsSync(externalExtensionsLocation)) { + throw new Error(`${externalExtensionsLocation} doesn't exist.`); + } let locExtFolder = idOrPath; if (/^\w{2,3}(-\w+)?$/.test(idOrPath)) { locExtFolder = path.join('..', 'vscode-loc', 'i18n', `vscode-language-pack-${idOrPath}`); @@ -67,7 +71,10 @@ function update(options) { console.log(`Importing translations for ${languageId} form '${location}' to '${translationDataFolder}' ...`); let translationPaths = []; - gulp.src(path.join(location, '**', languageId, '*.xlf'), { silent: false }) + gulp.src([ + path.join(location, '**', languageId, '*.xlf'), + ...i18n.EXTERNAL_EXTENSIONS.map(extensionId => path.join(externalExtensionsLocation, extensionId, languageId, '*-new.xlf')) + ], { silent: false }) .pipe(i18n.prepareI18nPackFiles(translationPaths)) .on('error', (error) => { console.log(`Error occurred while importing translations:`); @@ -94,7 +101,7 @@ function update(options) { } if (path.basename(process.argv[1]) === 'update-localization-extension.js') { var options = minimist(process.argv.slice(2), { - string: 'location' + string: ['location', 'externalExtensionsLocation'] }); update(options); } diff --git a/build/stylelint.js b/build/stylelint.js new file mode 100644 index 00000000000..5b1668ea2e4 --- /dev/null +++ b/build/stylelint.js @@ -0,0 +1,57 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const es = require('event-stream'); +const vfs = require('vinyl-fs'); +const { stylelintFilter } = require('./filters'); +const { getVariableNameValidator } = require('./lib/stylelint/validateVariableNames'); + +module.exports = gulpstylelint; + +/** use regex on lines */ +function gulpstylelint(reporter) { + const variableValidator = getVariableNameValidator(); + let errorCount = 0; + return es.through(function (file) { + const lines = file.__lines || file.contents.toString('utf8').split(/\r\n|\r|\n/); + file.__lines = lines; + + lines.forEach((line, i) => { + variableValidator(line, unknownVariable => { + reporter(file.relative + '(' + (i + 1) + ',1): Unknown variable: ' + unknownVariable, true); + errorCount++; + }); + }); + + this.emit('data', file); + }, function () { + if (errorCount > 0) { + reporter('All valid variable names are in `build/lib/stylelint/vscode-known-variables.json`\nTo update that file, run `./scripts/test-documentation.sh|bat.`', false); + } + this.emit('end'); + } + ); +} + +function stylelint() { + return vfs + .src(stylelintFilter, { base: '.', follow: true, allowEmpty: true }) + .pipe(gulpstylelint((message, isError) => { + if (isError) { + console.error(message); + } else { + console.info(message); + } + })) + .pipe(es.through(function () { /* noop, important for the stream to end */ })); +} + +if (require.main === module) { + stylelint().on('error', (err) => { + console.error(); + console.error(err); + process.exit(1); + }); +} diff --git a/build/win32/i18n/messages.es.isl b/build/win32/i18n/messages.es.isl index f8ac2ff85b2..0ba4d0c44f2 100644 --- a/build/win32/i18n/messages.es.isl +++ b/build/win32/i18n/messages.es.isl @@ -6,4 +6,4 @@ AddToPath=Agregar a PATH (disponible despu RunAfter=Ejecutar %1 después de la instalación Other=Otros: SourceFile=Archivo de origen %1 -OpenWithCodeContextMenu=Abrir &con %1 +OpenWithCodeContextMenu=Abrir &con %1 diff --git a/cglicenses.json b/cglicenses.json index 0d45a0899b6..754489e3306 100644 --- a/cglicenses.json +++ b/cglicenses.json @@ -335,8 +335,12 @@ "name": "const_format", "fullLicenseTextUri": "https://raw.githubusercontent.com/rodrimati1992/const_format_crates/b2207af46bfbd9f1a6bd12dbffd10feeea3d9fd7/LICENSE-ZLIB.md" }, - { // License is MIT/Apache and tool doesn't understand this syntax + { // License is MIT/Apache and tool doesn't look in subfolders "name": "toml", "fullLicenseTextUri": "https://raw.githubusercontent.com/toml-rs/toml/main/crates/toml/LICENSE-MIT" + }, + { // License is MIT/Apache and tool doesn't look in subfolders + "name": "dirs-sys-next", + "fullLicenseTextUri": "https://raw.githubusercontent.com/xdg-rs/dirs/master/dirs-sys/LICENSE-MIT" } ] diff --git a/cgmanifest.json b/cgmanifest.json index fb038bde0c3..232f7131b00 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "chromium", "repositoryUrl": "https://chromium.googlesource.com/chromium/src", - "commitHash": "a8a8309404d39efa9c624d7aee0e27562721e522" + "commitHash": "61305fe71c4357662f161ba689fd9a1828d5e4f7" } }, "licenseDetail": [ @@ -40,7 +40,7 @@ "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ], "isOnlyProductionDependency": true, - "version": "102.0.5005.194" + "version": "102.0.5005.196" }, { "component": { diff --git a/cli/.cargo/config.toml b/cli/.cargo/config.toml deleted file mode 100644 index 35c67ad3d28..00000000000 --- a/cli/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[target.'cfg(all(windows, target_env = "msvc"))'] -rustflags = ["-C", "target-feature=+crt-static"] diff --git a/cli/Cargo.lock b/cli/Cargo.lock index c17ffe06926..45d0f478db1 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -230,9 +230,11 @@ dependencies = [ "async-trait", "atty", "base64", + "cfg-if", "chrono", "clap", "clap_lex", + "console", "const_format", "core-foundation", "dialoguer", @@ -249,6 +251,7 @@ dependencies = [ "open", "opentelemetry", "opentelemetry-application-insights", + "pin-project", "rand 0.8.5", "regex", "reqwest", @@ -261,6 +264,7 @@ dependencies = [ "sysinfo", "tar", "tempfile", + "thiserror", "tokio", "tokio-util", "tunnels", @@ -293,16 +297,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c" +checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" dependencies = [ "encode_unicode", "lazy_static", "libc", - "terminal_size", "unicode-width", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -475,11 +478,12 @@ dependencies = [ [[package]] name = "dialoguer" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92e7e37ecef6857fdc0c0c5d42fd5b0938e46590c2183cc92dd310a6d078eb1" +checksum = "af3c796f3b0b408d9fd581611b47fa850821fcb84aa640b83a3c1a5be2d691f2" dependencies = [ "console", + "shell-words", "tempfile", "zeroize", ] @@ -587,6 +591,27 @@ dependencies = [ "syn", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1007,6 +1032,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] + [[package]] name = "ipnet" version = "2.5.0" @@ -1061,6 +1096,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "lock_api" version = "0.4.9" @@ -1303,9 +1344,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.42" +version = "0.10.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" +checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2" dependencies = [ "bitflags", "cfg-if", @@ -1333,25 +1374,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "111.22.0+1.1.1q" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f31f0d509d1c1ae9cada2f9539ff8f37933831fd5098879e482aa687d659853" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" -version = "0.9.76" +version = "0.9.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" +checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b" dependencies = [ "autocfg", "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -1506,6 +1537,26 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1738,15 +1789,6 @@ version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "reqwest" version = "0.11.12" @@ -1871,6 +1913,20 @@ dependencies = [ "yasna", ] +[[package]] +name = "rustix" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.42.0", +] + [[package]] name = "ryu" version = "1.0.11" @@ -1908,7 +1964,7 @@ checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" [[package]] name = "secret-service" version = "2.0.2" -source = "git+https://github.com/microsoft/vscode-secret-service-rs?rev=30f0414108a122d6f2bfc28a5425d0dac9738518#30f0414108a122d6f2bfc28a5425d0dac9738518" +source = "git+https://github.com/microsoft/vscode-secret-service-rs?rev=fbbaf222de10546609be26bb043e64356e855edb#fbbaf222de10546609be26bb043e64356e855edb" dependencies = [ "lazy_static", "num", @@ -2046,6 +2102,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -2137,16 +2199,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" dependencies = [ "cfg-if", "fastrand", - "libc", "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys 0.42.0", ] [[package]] @@ -2158,16 +2219,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "terminal_size" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "textwrap" version = "0.15.1" @@ -2176,18 +2227,18 @@ checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" dependencies = [ "proc-macro2", "quote", @@ -2377,11 +2428,12 @@ dependencies = [ [[package]] name = "tunnels" version = "0.1.0" -source = "git+https://github.com/microsoft/dev-tunnels?rev=3870e9133dfb9557774521bb447827f19b26e55d#3870e9133dfb9557774521bb447827f19b26e55d" +source = "git+https://github.com/microsoft/dev-tunnels?rev=730aa86f8ccd9e2dd4541693fbce763357da93f4#730aa86f8ccd9e2dd4541693fbce763357da93f4" dependencies = [ "async-trait", "chrono", "futures", + "hyper", "log", "reqwest", "russh", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index a1fc80b596a..c7b6c3746a6 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -15,7 +15,7 @@ name = "code" futures = "0.3" clap = { version = "3.0", features = ["derive", "env"] } open = { version = "2.1.0" } -reqwest = { version = "0.11.9", default-features = false, features = ["json", "stream", "native-tls-vendored"] } +reqwest = { version = "0.11.9", default-features = false, features = ["json", "stream", "native-tls"] } tokio = { version = "1.24.2", features = ["full"] } tokio-util = { version = "0.7", features = ["compat"] } flate2 = { version = "1.0.22" } @@ -31,17 +31,17 @@ dirs = "4.0.0" rand = "0.8.5" atty = "0.2.14" opentelemetry = { version = "0.18.0", features = ["rt-tokio"] } -opentelemetry-application-insights = { version = "0.22.0", features = ["reqwest-client-vendored-tls"] } +opentelemetry-application-insights = { version = "0.22.0", features = ["reqwest-client"] } serde_bytes = "0.11.5" chrono = { version = "0.4", features = ["serde"] } gethostname = "0.2.3" libc = "0.2" -tunnels = { git = "https://github.com/microsoft/dev-tunnels", rev = "3870e9133dfb9557774521bb447827f19b26e55d", default-features = false, features = ["connections", "vendored-openssl"] } +tunnels = { git = "https://github.com/microsoft/dev-tunnels", rev = "730aa86f8ccd9e2dd4541693fbce763357da93f4", default-features = false, features = ["connections"] } keyring = "1.1" dialoguer = "0.10" hyper = "0.14" indicatif = "0.16" -tempfile = "3.3" +tempfile = "3.4" clap_lex = "0.2" url = "2.3" async-trait = "0.1" @@ -50,6 +50,10 @@ const_format = "0.2" sha2 = "0.10" base64 = "0.13" shell-escape = "0.1.5" +thiserror = "1.0" +cfg-if = "1.0.0" +pin-project = "1.0" +console = "0.15" [build-dependencies] serde = { version = "1.0" } @@ -70,7 +74,7 @@ zbus = { version = "3.4", default-features = false, features = ["tokio"] } russh = { git = "https://github.com/microsoft/vscode-russh", branch = "main" } russh-cryptovec = { git = "https://github.com/microsoft/vscode-russh", branch = "main" } russh-keys = { git = "https://github.com/microsoft/vscode-russh", branch = "main" } -secret-service = { git = "https://github.com/microsoft/vscode-secret-service-rs", rev = "30f0414108a122d6f2bfc28a5425d0dac9738518" } +secret-service = { git = "https://github.com/microsoft/vscode-secret-service-rs", rev = "fbbaf222de10546609be26bb043e64356e855edb" } [profile.release] strip = true diff --git a/cli/src/async_pipe.rs b/cli/src/async_pipe.rs new file mode 100644 index 00000000000..dcbe0d16017 --- /dev/null +++ b/cli/src/async_pipe.rs @@ -0,0 +1,183 @@ +/*--------------------------------------------------------------------------------------------- + * 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::APPLICATION_NAME, util::errors::CodeError}; +use std::path::{Path, PathBuf}; +use uuid::Uuid; + +// todo: we could probably abstract this into some crate, if one doesn't already exist + +cfg_if::cfg_if! { + if #[cfg(unix)] { + pub type AsyncPipe = tokio::net::UnixStream; + pub type AsyncPipeWriteHalf = tokio::net::unix::OwnedWriteHalf; + pub type AsyncPipeReadHalf = tokio::net::unix::OwnedReadHalf; + + pub async fn get_socket_rw_stream(path: &Path) -> Result { + tokio::net::UnixStream::connect(path) + .await + .map_err(CodeError::AsyncPipeFailed) + } + + pub async fn listen_socket_rw_stream(path: &Path) -> Result { + tokio::net::UnixListener::bind(path) + .map(AsyncPipeListener) + .map_err(CodeError::AsyncPipeListenerFailed) + } + + pub struct AsyncPipeListener(tokio::net::UnixListener); + + impl AsyncPipeListener { + pub async fn accept(&mut self) -> Result { + self.0.accept().await.map_err(CodeError::AsyncPipeListenerFailed).map(|(s, _)| s) + } + } + + pub fn socket_stream_split(pipe: AsyncPipe) -> (AsyncPipeReadHalf, AsyncPipeWriteHalf) { + pipe.into_split() + } + } else { + use tokio::{time::sleep, io::{AsyncRead, AsyncWrite, ReadBuf}}; + use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions, NamedPipeClient, NamedPipeServer}; + use std::{time::Duration, pin::Pin, task::{Context, Poll}, io}; + use pin_project::pin_project; + + #[pin_project(project = AsyncPipeProj)] + pub enum AsyncPipe { + PipeClient(#[pin] NamedPipeClient), + PipeServer(#[pin] NamedPipeServer), + } + + impl AsyncRead for AsyncPipe { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + match self.project() { + AsyncPipeProj::PipeClient(c) => c.poll_read(cx, buf), + AsyncPipeProj::PipeServer(c) => c.poll_read(cx, buf), + } + } + } + + impl AsyncWrite for AsyncPipe { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + match self.project() { + AsyncPipeProj::PipeClient(c) => c.poll_write(cx, buf), + AsyncPipeProj::PipeServer(c) => c.poll_write(cx, buf), + } + } + + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[io::IoSlice<'_>], + ) -> Poll> { + match self.project() { + AsyncPipeProj::PipeClient(c) => c.poll_write_vectored(cx, bufs), + AsyncPipeProj::PipeServer(c) => c.poll_write_vectored(cx, bufs), + } + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.project() { + AsyncPipeProj::PipeClient(c) => c.poll_flush(cx), + AsyncPipeProj::PipeServer(c) => c.poll_flush(cx), + } + } + + fn is_write_vectored(&self) -> bool { + match self { + AsyncPipe::PipeClient(c) => c.is_write_vectored(), + AsyncPipe::PipeServer(c) => c.is_write_vectored(), + } + } + + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.project() { + AsyncPipeProj::PipeClient(c) => c.poll_shutdown(cx), + AsyncPipeProj::PipeServer(c) => c.poll_shutdown(cx), + } + } + } + + pub type AsyncPipeWriteHalf = tokio::io::WriteHalf; + pub type AsyncPipeReadHalf = tokio::io::ReadHalf; + + pub async fn get_socket_rw_stream(path: &Path) -> Result { + // Tokio says we can need to try in a loop. Do so. + // https://docs.rs/tokio/latest/tokio/net/windows/named_pipe/struct.NamedPipeClient.html + let client = loop { + match ClientOptions::new().open(path) { + Ok(client) => break client, + // ERROR_PIPE_BUSY https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499- + Err(e) if e.raw_os_error() == Some(231) => sleep(Duration::from_millis(100)).await, + Err(e) => return Err(CodeError::AsyncPipeFailed(e)), + } + }; + + Ok(AsyncPipe::PipeClient(client)) + } + + pub struct AsyncPipeListener { + path: PathBuf, + server: NamedPipeServer + } + + impl AsyncPipeListener { + pub async fn accept(&mut self) -> Result { + // see https://docs.rs/tokio/latest/tokio/net/windows/named_pipe/struct.NamedPipeServer.html + // this is a bit weird in that the server becomes the client once + // they get a connection, and we create a new client. + + self.server + .connect() + .await + .map_err(CodeError::AsyncPipeListenerFailed)?; + + // Construct the next server to be connected before sending the one + // we already have of onto a task. This ensures that the server + // isn't closed (after it's done in the task) before a new one is + // available. Otherwise the client might error with + // `io::ErrorKind::NotFound`. + let next_server = ServerOptions::new() + .create(&self.path) + .map_err(CodeError::AsyncPipeListenerFailed)?; + + + Ok(AsyncPipe::PipeServer(std::mem::replace(&mut self.server, next_server))) + } + } + + pub async fn listen_socket_rw_stream(path: &Path) -> Result { + let server = ServerOptions::new() + .first_pipe_instance(true) + .create(path) + .map_err(CodeError::AsyncPipeListenerFailed)?; + + Ok(AsyncPipeListener { path: path.to_owned(), server }) + } + + pub fn socket_stream_split(pipe: AsyncPipe) -> (AsyncPipeReadHalf, AsyncPipeWriteHalf) { + tokio::io::split(pipe) + } + } +} + +/// Gets a random name for a pipe/socket on the paltform +pub fn get_socket_name() -> PathBuf { + cfg_if::cfg_if! { + if #[cfg(unix)] { + std::env::temp_dir().join(format!("{}-{}", APPLICATION_NAME, Uuid::new_v4())) + } else { + PathBuf::from(format!(r"\\.\pipe\{}-{}", APPLICATION_NAME, Uuid::new_v4())) + } + } +} diff --git a/cli/src/auth.rs b/cli/src/auth.rs index b7008ca13bd..a27850b6242 100644 --- a/cli/src/auth.rs +++ b/cli/src/auth.rs @@ -183,6 +183,9 @@ where T: Serialize + ?Sized, { let dec = serde_json::to_string(value).expect("expected to serialize"); + if std::env::var("VSCODE_CLI_DISABLE_KEYCHAIN_ENCRYPT").is_ok() { + return dec; + } encrypt(&dec) } @@ -191,7 +194,7 @@ fn unseal(value: &str) -> Option where T: DeserializeOwned, { - // small back-compat for old unencrypted values + // small back-compat for old unencrypted values, or if VSCODE_CLI_DISABLE_KEYCHAIN_ENCRYPT set if let Ok(v) = serde_json::from_str::(value) { return Some(v); } diff --git a/cli/src/bin/code/main.rs b/cli/src/bin/code/main.rs index 6bc991b4f5a..dcf41b60bd7 100644 --- a/cli/src/bin/code/main.rs +++ b/cli/src/bin/code/main.rs @@ -10,7 +10,7 @@ use clap::Parser; use cli::{ commands::{args, internal_wsl, tunnels, update, version, CommandContext}, constants::get_default_user_agent, - desktop, log as own_log, + desktop, log, state::LauncherPaths, util::{ errors::{wrap, AnyError}, @@ -22,8 +22,6 @@ use legacy_args::try_parse_legacy; use opentelemetry::sdk::trace::TracerProvider as SdkTracerProvider; use opentelemetry::trace::TracerProvider; -use log::{Level, Metadata, Record}; - #[tokio::main] async fn main() -> Result<(), std::convert::Infallible> { let raw_args = std::env::args_os().collect::>(); @@ -38,44 +36,56 @@ async fn main() -> Result<(), std::convert::Infallible> { }); let core = parsed.core(); - let context = CommandContext { + let context_paths = LauncherPaths::new(&core.global_options.cli_data_dir).unwrap(); + let context_args = core.clone(); + + // gets a command context without installing the global logger + let context_no_logger = || CommandContext { http: reqwest::ClientBuilder::new() .user_agent(get_default_user_agent()) .build() .unwrap(), - paths: LauncherPaths::new(&core.global_options.cli_data_dir).unwrap(), - log: make_logger(core), - args: core.clone(), + paths: context_paths, + log: make_logger(&context_args), + args: context_args, }; - log::set_logger(Box::leak(Box::new(RustyLogger(context.log.clone())))) - .map(|()| log::set_max_level(log::LevelFilter::Debug)) - .expect("expected to make logger"); + // gets a command context with the global logger installer. Usually what most commands want. + macro_rules! context { + () => {{ + let context = context_no_logger(); + log::install_global_logger(context.log.clone()); + context + }}; + } let result = match parsed { args::AnyCli::Standalone(args::StandaloneCli { subcommand: Some(cmd), .. }) => match cmd { - args::StandaloneCommands::Update(args) => update::update(context, args).await, + args::StandaloneCommands::Update(args) => update::update(context!(), args).await, args::StandaloneCommands::Wsl(args) => match args.command { - args::WslCommands::Serve => internal_wsl::serve(context).await, + args::WslCommands::Serve => internal_wsl::serve(context!()).await, }, }, args::AnyCli::Standalone(args::StandaloneCli { core: c, .. }) | args::AnyCli::Integrated(args::IntegratedCli { core: c, .. }) => match c.subcommand { None => { + let context = context!(); let ca = context.args.get_base_code_args(); start_code(context, ca).await } Some(args::Commands::Extension(extension_args)) => { + let context = context!(); let mut ca = context.args.get_base_code_args(); extension_args.add_code_args(&mut ca); start_code(context, ca).await } Some(args::Commands::Status) => { + let context = context!(); let mut ca = context.args.get_base_code_args(); ca.push("--status".to_string()); start_code(context, ca).await @@ -83,24 +93,27 @@ async fn main() -> Result<(), std::convert::Infallible> { Some(args::Commands::Version(version_args)) => match version_args.subcommand { args::VersionSubcommand::Use(use_version_args) => { - version::switch_to(context, use_version_args).await + version::switch_to(context!(), use_version_args).await } - args::VersionSubcommand::Show => version::show(context).await, + args::VersionSubcommand::Show => version::show(context!()).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, + Some(args::TunnelSubcommand::Prune) => tunnels::prune(context!()).await, + Some(args::TunnelSubcommand::Unregister) => tunnels::unregister(context!()).await, + Some(args::TunnelSubcommand::Kill) => tunnels::kill(context!()).await, + Some(args::TunnelSubcommand::Restart) => tunnels::restart(context!()).await, + Some(args::TunnelSubcommand::Status) => tunnels::status(context!()).await, Some(args::TunnelSubcommand::Rename(rename_args)) => { - tunnels::rename(context, rename_args).await + tunnels::rename(context!(), rename_args).await } Some(args::TunnelSubcommand::User(user_command)) => { - tunnels::user(context, user_command).await + tunnels::user(context!(), user_command).await } Some(args::TunnelSubcommand::Service(service_args)) => { - tunnels::service(context, service_args).await + tunnels::service(context_no_logger(), service_args).await } - None => tunnels::serve(context, tunnel_args.serve_args).await, + None => tunnels::serve(context_no_logger(), tunnel_args.serve_args).await, }, }, }; @@ -111,18 +124,17 @@ async fn main() -> Result<(), std::convert::Infallible> { } } -fn make_logger(core: &args::CliCore) -> own_log::Logger { +fn make_logger(core: &args::CliCore) -> log::Logger { let log_level = if core.global_options.verbose { - own_log::Level::Trace + log::Level::Trace } else { - core.global_options.log.unwrap_or(own_log::Level::Info) + core.global_options.log.unwrap_or(log::Level::Info) }; let tracer = SdkTracerProvider::builder().build().tracer("codecli"); - let mut log = own_log::Logger::new(tracer, log_level); + let mut log = log::Logger::new(tracer, log_level); if let Some(f) = &core.global_options.log_to_file { - log = - log.tee(own_log::FileLogSink::new(log_level, f).expect("expected to make file logger")) + log = log.tee(log::FileLogSink::new(log_level, f).expect("expected to make file logger")) } log @@ -132,7 +144,7 @@ fn print_and_exit(err: E) -> ! where E: std::fmt::Display, { - own_log::emit(own_log::Level::Error, "", &format!("{}", err)); + log::emit(log::Level::Error, "", &format!("{}", err)); std::process::exit(1); } @@ -164,40 +176,3 @@ async fn start_code(context: CommandContext, args: Vec) -> Result bool { - metadata.level() <= Level::Debug - } - - fn log(&self, record: &Record) { - if !self.enabled(record.metadata()) { - return; - } - - // exclude noisy log modules: - let src = match record.module_path() { - Some("russh::cipher") => return, - Some("russh::negotiation") => return, - Some(s) => s, - None => "", - }; - - self.0.emit( - match record.level() { - log::Level::Debug => own_log::Level::Debug, - log::Level::Error => own_log::Level::Error, - log::Level::Info => own_log::Level::Info, - log::Level::Trace => own_log::Level::Trace, - log::Level::Warn => own_log::Level::Warn, - }, - &format!("[{}] {}", src, record.args()), - ); - } - - fn flush(&self) {} -} diff --git a/cli/src/commands.rs b/cli/src/commands.rs index 32b1ac3592b..082031af201 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -6,8 +6,8 @@ mod context; pub mod args; +pub mod internal_wsl; pub mod tunnels; pub mod update; pub mod version; -pub mod internal_wsl; pub use context::CommandContext; diff --git a/cli/src/commands/args.rs b/cli/src/commands/args.rs index 4c4b4f532f3..49c07803a8e 100644 --- a/cli/src/commands/args.rs +++ b/cli/src/commands/args.rs @@ -200,10 +200,7 @@ pub struct ExtensionArgs { impl ExtensionArgs { pub fn add_code_args(&self, target: &mut Vec) { - if let Some(ed) = &self.desktop_code_options.extensions_dir { - target.push(ed.to_string()); - } - + self.desktop_code_options.add_code_args(target); self.subcommand.add_code_args(target); } } @@ -627,6 +624,15 @@ pub enum TunnelSubcommand { /// Delete all servers which are currently not running. Prune, + /// Stops any running tunnel on the system. + Kill, + + /// Restarts any running tunnel on the system. + Restart, + + /// Gets whether there is a tunnel running on the current machineiou. + Status, + /// Rename the name of this machine associated with port forwarding service. Rename(TunnelRenameArgs), @@ -644,7 +650,7 @@ pub enum TunnelSubcommand { #[derive(Subcommand, Debug, Clone)] pub enum TunnelServiceSubCommands { /// Installs or re-installs the tunnel service on the machine. - Install, + Install(TunnelServiceInstallArgs), /// Uninstalls and stops the tunnel service. Uninstall, @@ -657,6 +663,13 @@ pub enum TunnelServiceSubCommands { InternalRun, } +#[derive(Args, Debug, Clone)] +pub struct TunnelServiceInstallArgs { + /// 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, +} + #[derive(Args, Debug, Clone)] pub struct TunnelRenameArgs { /// The name you'd like to rename your machine to. diff --git a/cli/src/commands/internal_wsl.rs b/cli/src/commands/internal_wsl.rs index 9912b59428b..483ee52c6aa 100644 --- a/cli/src/commands/internal_wsl.rs +++ b/cli/src/commands/internal_wsl.rs @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ use crate::{ - tunnels::{serve_wsl, shutdown_signal::ShutdownSignal}, + tunnels::{serve_wsl, shutdown_signal::ShutdownRequest}, util::{errors::AnyError, prereqs::PreReqChecker}, }; use super::CommandContext; pub async fn serve(ctx: CommandContext) -> Result { - let signal = ShutdownSignal::create_rx(&[ShutdownSignal::CtrlC]); + let signal = ShutdownRequest::create_rx([ShutdownRequest::CtrlC]); let platform = spanf!( ctx.log, ctx.log.span("prereq"), diff --git a/cli/src/commands/tunnels.rs b/cli/src/commands/tunnels.rs index 01e5aa280d9..20394daa5ae 100644 --- a/cli/src/commands/tunnels.rs +++ b/cli/src/commands/tunnels.rs @@ -5,7 +5,7 @@ use async_trait::async_trait; use sha2::{Digest, Sha256}; -use std::str::FromStr; +use std::{str::FromStr, time::Duration}; use sysinfo::Pid; use tokio::sync::mpsc; @@ -17,21 +17,38 @@ use super::{ CommandContext, }; -use crate::tunnels::shutdown_signal::ShutdownSignal; -use crate::tunnels::{dev_tunnels::ActiveTunnel, SleepInhibitor}; use crate::{ + async_pipe::socket_stream_split, auth::Auth, - log::{self, Logger}, + constants::APPLICATION_NAME, + json_rpc::{new_json_rpc, start_json_rpc}, + log, + singleton::connect_as_client, state::LauncherPaths, tunnels::{ - code_server::CodeServerArgs, create_service_manager, dev_tunnels, legal, - paths::get_all_servers, ServiceContainer, ServiceManager, + code_server::CodeServerArgs, + create_service_manager, dev_tunnels, legal, + paths::get_all_servers, + protocol, + shutdown_signal::ShutdownRequest, + singleton_server::{ + make_singleton_server, start_singleton_server, BroadcastLogSink, SingletonServerArgs, + }, + Next, ServiceContainer, ServiceManager, }, util::{ - errors::{wrap, AnyError}, + errors::{wrap, AnyError, CodeError}, prereqs::PreReqChecker, }, }; +use crate::{ + singleton::{acquire_singleton, SingletonConnection}, + tunnels::{ + dev_tunnels::ActiveTunnel, + singleton_client::{start_singleton_client, SingletonClientArgs}, + SleepInhibitor, + }, +}; impl From for crate::auth::AuthProvider { fn from(auth_provider: AuthProvider) -> Self { @@ -75,7 +92,6 @@ impl ServiceContainer for TunnelServiceContainer { &mut self, log: log::Logger, launcher_paths: LauncherPaths, - shutdown_rx: mpsc::UnboundedReceiver, ) -> Result<(), AnyError> { let csa = (&self.args).into(); serve_with_csa( @@ -86,7 +102,6 @@ impl ServiceContainer for TunnelServiceContainer { ..Default::default() }, csa, - Some(shutdown_rx), ) .await?; Ok(()) @@ -99,14 +114,14 @@ pub async fn service( ) -> Result { let manager = create_service_manager(ctx.log.clone(), &ctx.paths); match service_args { - TunnelServiceSubCommands::Install => { + TunnelServiceSubCommands::Install(args) => { // ensure logged in, otherwise subsequent serving will fail Auth::new(&ctx.paths, ctx.log.clone()) .get_credential() .await?; // likewise for license consent - legal::require_consent(&ctx.paths, false)?; + legal::require_consent(&ctx.paths, args.accept_server_license_terms)?; let current_exe = std::env::current_exe().map_err(|e| wrap(e, "could not get current exe"))?; @@ -124,7 +139,7 @@ pub async fn service( ], ) .await?; - ctx.log.result("Service successfully installed! You can use `code tunnel service log` to monitor it, and `code tunnel service uninstall` to remove it."); + ctx.log.result(format!("Service successfully installed! You can use `{} tunnel service log` to monitor it, and `{} tunnel service uninstall` to remove it.", APPLICATION_NAME, APPLICATION_NAME)); } TunnelServiceSubCommands::Uninstall => { manager.unregister().await?; @@ -189,6 +204,79 @@ pub async fn unregister(ctx: CommandContext) -> Result { Ok(0) } +async fn do_single_rpc_call< + P: serde::Serialize, + R: serde::de::DeserializeOwned + Send + 'static, +>( + ctx: &CommandContext, + method: &'static str, + params: P, +) -> Result { + let client = match connect_as_client(&ctx.paths.tunnel_lockfile()).await { + Ok(p) => p, + Err(CodeError::SingletonLockfileOpenFailed(_)) + | Err(CodeError::SingletonLockedProcessExited(_)) => { + return Err(CodeError::NoRunningTunnel.into()); + } + Err(e) => return Err(e.into()), + }; + + let (msg_tx, msg_rx) = mpsc::unbounded_channel(); + let mut rpc = new_json_rpc(); + let caller = rpc.get_caller(msg_tx); + let (read, write) = socket_stream_split(client); + let log = ctx.log.clone(); + + let rpc = tokio::spawn(async move { + start_json_rpc( + rpc.methods(()).build(log), + read, + write, + msg_rx, + ShutdownRequest::create_rx([ShutdownRequest::CtrlC]), + ) + .await + .unwrap(); + }); + + let r = caller.call(method, params).await.unwrap(); + rpc.abort(); + r.map_err(|err| CodeError::TunnelRpcCallFailed(err).into()) +} + +pub async fn restart(ctx: CommandContext) -> Result { + do_single_rpc_call::<_, ()>( + &ctx, + protocol::singleton::METHOD_RESTART, + protocol::EmptyObject {}, + ) + .await + .map(|_| 0) +} + +pub async fn kill(ctx: CommandContext) -> Result { + do_single_rpc_call::<_, ()>( + &ctx, + protocol::singleton::METHOD_SHUTDOWN, + protocol::EmptyObject {}, + ) + .await + .map(|_| 0) +} + +pub async fn status(ctx: CommandContext) -> Result { + let status: protocol::singleton::Status = do_single_rpc_call( + &ctx, + protocol::singleton::METHOD_STATUS, + protocol::EmptyObject {}, + ) + .await?; + + ctx.log.result(serde_json::to_string(&status).unwrap()); + + Ok(0) +} + /// Removes unused servers. pub async fn prune(ctx: CommandContext) -> Result { get_all_servers(&ctx.paths) @@ -227,7 +315,7 @@ pub async fn serve(ctx: CommandContext, gateway_args: TunnelServeArgs) -> Result legal::require_consent(&paths, gateway_args.accept_server_license_terms)?; let csa = (&args).into(); - let result = serve_with_csa(paths, log, gateway_args, csa, None).await; + let result = serve_with_csa(paths, log, gateway_args, csa).await; drop(no_sleep); result @@ -242,59 +330,103 @@ fn get_connection_token(tunnel: &ActiveTunnel) -> String { async fn serve_with_csa( paths: LauncherPaths, - log: Logger, + mut log: log::Logger, gateway_args: TunnelServeArgs, mut csa: CodeServerArgs, - shutdown_rx: Option>, ) -> Result { + let log_broadcast = BroadcastLogSink::new(); + log = log.tee(log_broadcast.clone()); + log::install_global_logger(log.clone()); // re-install so that library logs are captured + + let shutdown = match gateway_args + .parent_process_id + .and_then(|p| Pid::from_str(&p).ok()) + { + Some(pid) => ShutdownRequest::create_rx([ + ShutdownRequest::CtrlC, + ShutdownRequest::ParentProcessKilled(pid), + ]), + None => ShutdownRequest::create_rx([ShutdownRequest::CtrlC]), + }; + // Intentionally read before starting the server. If the server updated and // respawn is requested, the old binary will get renamed, and then // current_exe will point to the wrong path. let current_exe = std::env::current_exe().unwrap(); + let server = loop { + if shutdown.is_open() { + return Ok(0); + } + + match acquire_singleton(paths.tunnel_lockfile()).await { + Ok(SingletonConnection::Client(stream)) => { + debug!(log, "starting as client to singleton"); + let should_exit = start_singleton_client(SingletonClientArgs { + log: log.clone(), + shutdown: shutdown.clone(), + stream, + }) + .await; + if should_exit { + return Ok(0); + } + } + Ok(SingletonConnection::Singleton(server)) => break server, + Err(e) => { + warning!(log, "error access singleton, retrying: {}", e); + tokio::time::sleep(Duration::from_secs(2)).await + } + } + }; + + debug!(log, "starting as new singleton"); + + let mut server = + make_singleton_server(log_broadcast.clone(), log.clone(), server, shutdown.clone()); let platform = spanf!(log, log.span("prereq"), PreReqChecker::new().verify())?; let auth = Auth::new(&paths, log.clone()); let mut dt = dev_tunnels::DevTunnels::new(&log, auth, &paths); - let tunnel = if let Some(d) = gateway_args.tunnel.clone().into() { - dt.start_existing_tunnel(d).await - } else { - dt.start_new_launcher_tunnel(gateway_args.name, gateway_args.random_name) - .await - }?; + loop { + let tunnel = if let Some(d) = gateway_args.tunnel.clone().into() { + dt.start_existing_tunnel(d).await + } else { + dt.start_new_launcher_tunnel(gateway_args.name.as_deref(), gateway_args.random_name) + .await + }?; - csa.connection_token = Some(get_connection_token(&tunnel)); + csa.connection_token = Some(get_connection_token(&tunnel)); - let shutdown_tx = if let Some(tx) = shutdown_rx { - tx - } else if let Some(pid) = gateway_args - .parent_process_id - .and_then(|p| Pid::from_str(&p).ok()) - { - ShutdownSignal::create_rx(&[ - ShutdownSignal::CtrlC, - ShutdownSignal::ParentProcessKilled(pid), - ]) - } else { - ShutdownSignal::create_rx(&[ShutdownSignal::CtrlC]) - }; + let mut r = start_singleton_server(SingletonServerArgs { + log: log.clone(), + tunnel, + paths: &paths, + code_server_args: &csa, + platform, + log_broadcast: &log_broadcast, + shutdown: shutdown.clone(), + server: &mut server, + }) + .await?; + r.tunnel.close().await.ok(); - let mut r = crate::tunnels::serve(&log, tunnel, &paths, &csa, platform, shutdown_tx).await?; - r.tunnel.close().await.ok(); + match r.next { + Next::Respawn => { + warning!(log, "respawn requested, starting new server"); + // reuse current args, but specify no-forward since tunnels will + // already be running in this process, and we cannot do a login + let args = std::env::args().skip(1).collect::>(); + let exit = std::process::Command::new(current_exe) + .args(args) + .spawn() + .map_err(|e| wrap(e, "error respawning after update"))? + .wait() + .map_err(|e| wrap(e, "error waiting for child"))?; - if r.respawn { - warning!(log, "respawn requested, starting new server"); - // reuse current args, but specify no-forward since tunnels will - // already be running in this process, and we cannot do a login - let args = std::env::args().skip(1).collect::>(); - let exit = std::process::Command::new(current_exe) - .args(args) - .spawn() - .map_err(|e| wrap(e, "error respawning after update"))? - .wait() - .map_err(|e| wrap(e, "error waiting for child"))?; - - return Ok(exit.code().unwrap_or(1)); + return Ok(exit.code().unwrap_or(1)); + } + Next::Exit => return Ok(0), + Next::Restart => continue, + } } - - Ok(0) } diff --git a/cli/src/constants.rs b/cli/src/constants.rs index b3adb020260..634ddde7ff2 100644 --- a/cli/src/constants.rs +++ b/cli/src/constants.rs @@ -73,6 +73,8 @@ pub fn get_default_user_agent() -> String { ) } +const NO_COLOR_ENV: &str = "NO_COLOR"; + lazy_static! { pub static ref TUNNEL_SERVICE_USER_AGENT: String = match std::env::var(TUNNEL_SERVICE_USER_AGENT_ENV_VAR) { @@ -101,5 +103,11 @@ lazy_static! { option_env!("VSCODE_CLI_SERVER_NAME_MAP").and_then(|s| serde_json::from_str(s).unwrap()); /// Whether i/o interactions are allowed in the current CLI. - pub static ref IS_INTERACTIVE_CLI: bool = atty::is(atty::Stream::Stdin) && std::env::var(NONINTERACTIVE_VAR).is_err(); + pub static ref IS_A_TTY: bool = atty::is(atty::Stream::Stdin); + + /// Whether i/o interactions are allowed in the current CLI. + pub static ref COLORS_ENABLED: bool = *IS_A_TTY && std::env::var(NO_COLOR_ENV).is_err(); + + /// Whether i/o interactions are allowed in the current CLI. + pub static ref IS_INTERACTIVE_CLI: bool = *IS_A_TTY && std::env::var(NONINTERACTIVE_VAR).is_err(); } diff --git a/cli/src/json_rpc.rs b/cli/src/json_rpc.rs index 9cc5ad1ade1..083c4316542 100644 --- a/cli/src/json_rpc.rs +++ b/cli/src/json_rpc.rs @@ -5,12 +5,16 @@ use tokio::{ io::{AsyncBufReadExt, AsyncRead, AsyncWrite, AsyncWriteExt, BufReader}, + pin, sync::mpsc, }; use crate::{ rpc::{self, MaybeSync, Serialization}, - util::errors::InvalidRpcDataError, + util::{ + errors::InvalidRpcDataError, + sync::{Barrier, Receivable}, + }, }; use std::io; @@ -39,37 +43,41 @@ pub fn new_json_rpc() -> rpc::RpcBuilder { } #[allow(dead_code)] -pub async fn start_json_rpc( +pub async fn start_json_rpc( dispatcher: rpc::RpcDispatcher, read: impl AsyncRead + Unpin, mut write: impl AsyncWrite + Unpin, - mut msg_rx: mpsc::UnboundedReceiver>, - mut shutdown_rx: mpsc::UnboundedReceiver, + mut msg_rx: impl Receivable>, + mut shutdown_rx: Barrier, ) -> io::Result> { let (write_tx, mut write_rx) = mpsc::unbounded_channel::>(); let mut read = BufReader::new(read); let mut read_buf = String::new(); + let shutdown_fut = shutdown_rx.wait(); + pin!(shutdown_fut); loop { tokio::select! { - r = shutdown_rx.recv() => return Ok(r), + r = &mut shutdown_fut => return Ok(r.ok()), Some(w) = write_rx.recv() => { write.write_all(&w).await?; }, - Some(w) = msg_rx.recv() => { + Some(w) = msg_rx.recv_msg() => { write.write_all(&w).await?; }, n = read.read_line(&mut read_buf) => { let r = match n { Ok(0) => return Ok(None), - Ok(n) => dispatcher.dispatch(read_buf[..n].as_bytes()), + Ok(n) => dispatcher.dispatch(read_buf[..n].as_bytes()), Err(e) => return Err(e) }; + read_buf.truncate(0); + match r { MaybeSync::Sync(Some(v)) => { - write_tx.send(v).ok(); + write.write_all(&v).await?; }, MaybeSync::Sync(None) => continue, MaybeSync::Future(fut) => { diff --git a/cli/src/lib.rs b/cli/src/lib.rs index fd0917843ba..0fe65c9d8c8 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -18,6 +18,8 @@ pub mod tunnels; pub mod update_service; pub mod util; -mod rpc; +mod async_pipe; mod json_rpc; mod msgpack_rpc; +mod rpc; +mod singleton; diff --git a/cli/src/log.rs b/cli/src/log.rs index a008a1ba06d..7162432062d 100644 --- a/cli/src/log.rs +++ b/cli/src/log.rs @@ -8,14 +8,15 @@ use opentelemetry::{ sdk::trace::{Tracer, TracerProvider}, trace::{SpanBuilder, Tracer as TraitTracer, TracerProvider as TracerProviderTrait}, }; +use serde::{Deserialize, Serialize}; use std::fmt; -use std::{env, path::Path, sync::Arc}; use std::{ io::Write, sync::atomic::{AtomicU32, Ordering}, }; +use std::{path::Path, sync::Arc}; -const NO_COLOR_ENV: &str = "NO_COLOR"; +use crate::constants::COLORS_ENABLED; static INSTANCE_COUNTER: AtomicU32 = AtomicU32::new(0); @@ -25,7 +26,7 @@ pub fn next_counter() -> u32 { } // Log level -#[derive(clap::ArgEnum, PartialEq, Eq, PartialOrd, Clone, Copy, Debug)] +#[derive(clap::ArgEnum, PartialEq, Eq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize)] pub enum Level { Trace = 0, Debug, @@ -70,7 +71,7 @@ impl Level { } pub fn color_code(&self) -> Option<&str> { - if env::var(NO_COLOR_ENV).is_ok() || !atty::is(atty::Stream::Stdout) { + if !*COLORS_ENABLED { return None; } @@ -177,7 +178,7 @@ impl LogSink for FileLogSink { return; } - let line = format(level, prefix, message); + let line = format(level, prefix, message, false); // ignore any errors, not much we can do if logging fails... self.file.lock().unwrap().write_all(line.as_bytes()).ok(); @@ -294,24 +295,26 @@ impl<'a> crate::util::io::ReportCopyProgress for DownloadLogger<'a> { } } -pub fn format(level: Level, prefix: &str, message: &str) -> String { +fn format(level: Level, prefix: &str, message: &str, use_colors: bool) -> String { let current = Local::now(); let timestamp = current.format("%Y-%m-%d %H:%M:%S").to_string(); let name = level.name().unwrap(); - if let Some(c) = level.color_code() { - format!( - "\x1b[2m[{}]\x1b[0m {}{}\x1b[0m {}{}\n", - timestamp, c, name, prefix, message - ) - } else { - format!("[{}] {} {}{}\n", timestamp, name, prefix, message) + if use_colors { + if let Some(c) = level.color_code() { + return format!( + "\x1b[2m[{}]\x1b[0m {}{}\x1b[0m {}{}\n", + timestamp, c, name, prefix, message + ); + } } + + format!("[{}] {} {}{}\n", timestamp, name, prefix, message) } pub fn emit(level: Level, prefix: &str, message: &str) { - let line = format(level, prefix, message); + let line = format(level, prefix, message, true); if level == Level::Trace { print!("\x1b[2m{}\x1b[0m", line); } else { @@ -319,6 +322,51 @@ pub fn emit(level: Level, prefix: &str, message: &str) { } } +/// Installs the logger instance as the global logger for the 'log' service. +/// Replaces any existing registered logger. Note that the logger will be leaked/ +pub fn install_global_logger(log: Logger) { + log::set_logger(Box::leak(Box::new(RustyLogger(log)))) + .map(|()| log::set_max_level(log::LevelFilter::Debug)) + .expect("expected to make logger"); +} + +/// Logger that uses the common rust "log" crate and directs back to one of +/// our managed loggers. +struct RustyLogger(Logger); + +impl log::Log for RustyLogger { + fn enabled(&self, metadata: &log::Metadata) -> bool { + metadata.level() <= log::Level::Debug + } + + fn log(&self, record: &log::Record) { + if !self.enabled(record.metadata()) { + return; + } + + // exclude noisy log modules: + let src = match record.module_path() { + Some("russh::cipher") => return, + Some("russh::negotiation") => return, + Some(s) => s, + None => "", + }; + + self.0.emit( + match record.level() { + log::Level::Debug => Level::Debug, + log::Level::Error => Level::Error, + log::Level::Info => Level::Info, + log::Level::Trace => Level::Trace, + log::Level::Warn => Level::Warn, + }, + &format!("[{}] {}", src, record.args()), + ); + } + + fn flush(&self) {} +} + #[macro_export] macro_rules! error { ($logger:expr, $str:expr) => { diff --git a/cli/src/msgpack_rpc.rs b/cli/src/msgpack_rpc.rs index b00b4c11ed8..de46e738da8 100644 --- a/cli/src/msgpack_rpc.rs +++ b/cli/src/msgpack_rpc.rs @@ -5,12 +5,16 @@ use tokio::{ io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader}, + pin, sync::mpsc, }; use crate::{ rpc::{self, MaybeSync, Serialization}, - util::errors::{AnyError, InvalidRpcDataError}, + util::{ + errors::{AnyError, InvalidRpcDataError}, + sync::{Barrier, Receivable}, + }, }; use std::io; @@ -35,17 +39,20 @@ pub fn new_msgpack_rpc() -> rpc::RpcBuilder { } #[allow(clippy::read_zero_byte_vec)] // false positive -pub async fn start_msgpack_rpc( +pub async fn start_msgpack_rpc( dispatcher: rpc::RpcDispatcher, read: impl AsyncRead + Unpin, mut write: impl AsyncWrite + Unpin, - mut msg_rx: mpsc::UnboundedReceiver>, - mut shutdown_rx: mpsc::UnboundedReceiver, + mut msg_rx: impl Receivable>, + mut shutdown_rx: Barrier, ) -> io::Result> { let (write_tx, mut write_rx) = mpsc::unbounded_channel::>(); let mut read = BufReader::new(read); let mut decode_buf = vec![]; + let shutdown_fut = shutdown_rx.wait(); + pin!(shutdown_fut); + loop { tokio::select! { u = read.read_u32() => { @@ -66,16 +73,16 @@ pub async fn start_msgpack_rpc( }); } }, - r = shutdown_rx.recv() => return Ok(r), + r = &mut shutdown_fut => return Ok(r.ok()), }; }, Some(m) = write_rx.recv() => { write.write_all(&m).await?; }, - Some(m) = msg_rx.recv() => { + Some(m) = msg_rx.recv_msg() => { write.write_all(&m).await?; }, - r = shutdown_rx.recv() => return Ok(r), + r = &mut shutdown_fut => return Ok(r.ok()), } write.flush().await?; diff --git a/cli/src/rpc.rs b/cli/src/rpc.rs index 2249e5b7cf1..b5e5b53ee69 100644 --- a/cli/src/rpc.rs +++ b/cli/src/rpc.rs @@ -204,30 +204,34 @@ pub struct RpcCaller { } impl RpcCaller { + pub fn serialize_notify(serializer: &S, method: M, params: A) -> Vec + where + S: Serialization, + M: AsRef + serde::Serialize, + A: Serialize, + { + serializer.serialize(&FullRequest { + id: None, + method, + params, + }) + } + /// Enqueues an outbound call. Returns whether the message was enqueued. pub fn notify(&self, method: M, params: A) -> bool where - M: Into, + M: AsRef + serde::Serialize, A: Serialize, { - let body = self.serializer.serialize(&FullRequest { - id: None, - method: method.into(), - params, - }); - - self.sender.send(body).is_ok() + self.sender + .send(Self::serialize_notify(&self.serializer, method, params)) + .is_ok() } /// Enqueues an outbound call, returning its result. - #[allow(dead_code)] - pub async fn call( - &self, - method: M, - params: A, - ) -> oneshot::Receiver> + pub fn call(&self, method: M, params: A) -> oneshot::Receiver> where - M: Into, + M: AsRef + serde::Serialize, A: Serialize, R: DeserializeOwned + Send + 'static, { @@ -235,7 +239,7 @@ impl RpcCaller { let id = next_message_id(); let body = self.serializer.serialize(&FullRequest { id: Some(id), - method: method.into(), + method, params, }); @@ -321,13 +325,11 @@ impl RpcDispatcher { cb(Outcome::Error(err)); } MaybeSync::Sync(None) - } else if partial.result.is_some() { + } else { if let Some(cb) = self.calls.lock().unwrap().remove(&id.unwrap()) { cb(Outcome::Success(body.to_vec())); } MaybeSync::Sync(None) - } else { - MaybeSync::Sync(None) } } @@ -345,13 +347,12 @@ struct PartialIncoming { pub id: Option, pub method: Option, pub error: Option, - pub result: Option<()>, } #[derive(Serialize)] -pub struct FullRequest

{ +pub struct FullRequest, P> { pub id: Option, - pub method: String, + pub method: M, pub params: P, } @@ -372,7 +373,7 @@ struct ErrorResponse { pub error: ResponseError, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug)] pub struct ResponseError { pub code: i32, pub message: String, diff --git a/cli/src/self_update.rs b/cli/src/self_update.rs index 7a5b41e83a7..62228a5b3d1 100644 --- a/cli/src/self_update.rs +++ b/cli/src/self_update.rs @@ -106,7 +106,7 @@ fn validate_cli_is_good(exe_path: &Path) -> Result<(), AnyError> { if !o.status.success() { let msg = format!( - "could not execute new binary, aborting. Stdout:\r\n\r\n{}\r\n\r\nStderr:\r\n\r\n{}", + "could not execute new binary, aborting. Stdout:\n\n{}\n\nStderr:\n\n{}", String::from_utf8_lossy(&o.stdout), String::from_utf8_lossy(&o.stderr), ); diff --git a/cli/src/singleton.rs b/cli/src/singleton.rs new file mode 100644 index 00000000000..0ea9cda2a8a --- /dev/null +++ b/cli/src/singleton.rs @@ -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. + *--------------------------------------------------------------------------------------------*/ + +use serde::{Deserialize, Serialize}; +use std::{ + fs::{File, OpenOptions}, + io::{Seek, SeekFrom, Write}, + path::{Path, PathBuf}, + time::Duration, +}; +use sysinfo::{Pid, PidExt}; + +use crate::{ + async_pipe::{ + get_socket_name, get_socket_rw_stream, listen_socket_rw_stream, AsyncPipe, + AsyncPipeListener, + }, + util::{ + errors::CodeError, + file_lock::{FileLock, Lock, PREFIX_LOCKED_BYTES}, + machine::wait_until_process_exits, + }, +}; + +pub struct SingletonServer { + server: AsyncPipeListener, + _lock: FileLock, +} + +impl SingletonServer { + pub async fn accept(&mut self) -> Result { + self.server.accept().await + } +} + +pub enum SingletonConnection { + /// This instance got the singleton lock. It started listening on a socket + /// and has the read/write pair. If this gets dropped, the lock is released. + Singleton(SingletonServer), + /// Another instance is a singleton, and this client connected to it. + Client(AsyncPipe), +} + +/// Contents of the lock file; the listening socket ID and process ID +/// doing the listening. +#[derive(Deserialize, Serialize)] +struct LockFileMatter { + socket_path: String, + pid: u32, +} + +/// Tries to acquire the singleton homed at the given lock file, either starting +/// a new singleton if it doesn't exist, or connecting otherwise. +pub async fn acquire_singleton(lock_file: PathBuf) -> Result { + let file = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(&lock_file) + .map_err(CodeError::SingletonLockfileOpenFailed)?; + + match FileLock::acquire(file) { + Ok(Lock::AlreadyLocked(mut file)) => connect_as_client_with_file(&mut file) + .await + .map(SingletonConnection::Client), + Ok(Lock::Acquired(lock)) => start_singleton_server(lock) + .await + .map(SingletonConnection::Singleton), + Err(e) => Err(e), + } +} + +/// Tries to connect to the singleton homed at the given file as a client. +pub async fn connect_as_client(lock_file: &Path) -> Result { + let mut file = OpenOptions::new() + .read(true) + .open(lock_file) + .map_err(CodeError::SingletonLockfileOpenFailed)?; + + connect_as_client_with_file(&mut file).await +} + +async fn start_singleton_server(mut lock: FileLock) -> Result { + let socket_path = get_socket_name(); + + let mut vec = Vec::with_capacity(128); + let _ = vec.write(&[0; PREFIX_LOCKED_BYTES]); + let _ = rmp_serde::encode::write( + &mut vec, + &LockFileMatter { + socket_path: socket_path.to_string_lossy().to_string(), + pid: std::process::id(), + }, + ); + + lock.file_mut() + .write_all(&vec) + .map_err(CodeError::SingletonLockfileOpenFailed)?; + + let server = listen_socket_rw_stream(&socket_path).await?; + Ok(SingletonServer { + server, + _lock: lock, + }) +} + +const MAX_CLIENT_ATTEMPTS: i32 = 10; + +async fn connect_as_client_with_file(mut file: &mut File) -> Result { + // retry, since someone else could get a lock and we could read it before + // the JSON info was finished writing out + let mut attempt = 0; + loop { + let _ = file.seek(SeekFrom::Start(PREFIX_LOCKED_BYTES as u64)); + let r = match rmp_serde::from_read::<_, LockFileMatter>(&mut file) { + Ok(prev) => { + let socket_path = PathBuf::from(prev.socket_path); + + tokio::select! { + p = retry_get_socket_rw_stream(&socket_path, 5, Duration::from_millis(500)) => p, + _ = wait_until_process_exits(Pid::from_u32(prev.pid), 500) => return Err(CodeError::SingletonLockedProcessExited(prev.pid)), + } + } + Err(e) => Err(CodeError::SingletonLockfileReadFailed(e)), + }; + + if r.is_ok() || attempt == MAX_CLIENT_ATTEMPTS { + return r; + } + + attempt += 1; + tokio::time::sleep(Duration::from_millis(500)).await; + } +} + +async fn retry_get_socket_rw_stream( + path: &Path, + max_tries: usize, + interval: Duration, +) -> Result { + for i in 0.. { + match get_socket_rw_stream(path).await { + Ok(s) => return Ok(s), + Err(e) if i == max_tries => return Err(e), + Err(_) => tokio::time::sleep(interval).await, + } + } + + unreachable!() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_acquires_singleton() { + let dir = tempfile::tempdir().expect("expected to make temp dir"); + let s = acquire_singleton(dir.path().join("lock")) + .await + .expect("expected to acquire"); + + match s { + SingletonConnection::Singleton(_) => {} + _ => panic!("expected to be singleton"), + } + } + + #[tokio::test] + async fn test_acquires_client() { + let dir = tempfile::tempdir().expect("expected to make temp dir"); + let lockfile = dir.path().join("lock"); + let s1 = acquire_singleton(lockfile.clone()) + .await + .expect("expected to acquire1"); + match s1 { + SingletonConnection::Singleton(mut l) => tokio::spawn(async move { + l.accept().await.expect("expected to accept"); + }), + _ => panic!("expected to be singleton"), + }; + + let s2 = acquire_singleton(lockfile) + .await + .expect("expected to acquire2"); + match s2 { + SingletonConnection::Client(_) => {} + _ => panic!("expected to be client"), + } + } +} diff --git a/cli/src/state.rs b/cli/src/state.rs index 3e55e139b1b..296d1b535d8 100644 --- a/cli/src/state.rs +++ b/cli/src/state.rs @@ -13,7 +13,10 @@ use std::{ use serde::{de::DeserializeOwned, Serialize}; -use crate::util::errors::{wrap, AnyError, NoHomeForLauncherError, WrappedError}; +use crate::{ + constants::VSCODE_CLI_QUALITY, + util::errors::{wrap, AnyError, NoHomeForLauncherError, WrappedError}, +}; const HOME_DIR_ALTS: [&str; 2] = ["$HOME", "~"]; @@ -137,6 +140,14 @@ impl LauncherPaths { &self.root } + /// Lockfile for the running tunnel + pub fn tunnel_lockfile(&self) -> PathBuf { + self.root.join(format!( + "tunnel-{}.lock", + VSCODE_CLI_QUALITY.unwrap_or("oss") + )) + } + /// Suggested path for tunnel service logs, when using file logs pub fn service_log_file(&self) -> PathBuf { self.root.join("tunnel-service.log") diff --git a/cli/src/tunnels.rs b/cli/src/tunnels.rs index 73c5ffeb907..ebab9475988 100644 --- a/cli/src/tunnels.rs +++ b/cli/src/tunnels.rs @@ -8,6 +8,9 @@ pub mod dev_tunnels; pub mod legal; pub mod paths; pub mod shutdown_signal; +pub mod singleton_client; +pub mod singleton_server; +pub mod protocol; mod control_server; mod nosleep; @@ -18,9 +21,6 @@ mod nosleep_macos; #[cfg(target_os = "windows")] mod nosleep_windows; mod port_forwarder; -mod protocol; -#[cfg_attr(unix, path = "tunnels/server_bridge_unix.rs")] -#[cfg_attr(windows, path = "tunnels/server_bridge_windows.rs")] mod server_bridge; mod server_multiplexer; mod service; @@ -33,7 +33,7 @@ mod service_windows; mod socket_signal; mod wsl_server; -pub use control_server::serve; +pub use control_server::{serve, Next}; pub use nosleep::SleepInhibitor; pub use service::{ create_service_manager, ServiceContainer, ServiceManager, SERVICE_LOG_FILE_NAME, diff --git a/cli/src/tunnels/code_server.rs b/cli/src/tunnels/code_server.rs index 357f04750ba..1f9eb4ea85c 100644 --- a/cli/src/tunnels/code_server.rs +++ b/cli/src/tunnels/code_server.rs @@ -3,7 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ use super::paths::{InstalledServer, LastUsedServers, ServerPaths}; -use crate::constants::{APPLICATION_NAME, QUALITYLESS_PRODUCT_NAME, QUALITYLESS_SERVER_NAME}; +use crate::async_pipe::get_socket_name; +use crate::constants::{ + APPLICATION_NAME, EDITOR_WEB_URL, QUALITYLESS_PRODUCT_NAME, QUALITYLESS_SERVER_NAME, +}; use crate::options::{Quality, TelemetryLevel}; use crate::state::LauncherPaths; use crate::update_service::{ @@ -32,7 +35,6 @@ use tokio::io::{AsyncBufReadExt, BufReader}; use tokio::process::{Child, Command}; use tokio::sync::oneshot::Receiver; use tokio::time::{interval, timeout}; -use uuid::Uuid; lazy_static! { static ref LISTENING_PORT_RE: Regex = @@ -539,12 +541,7 @@ impl<'a, Http: SimpleHttp + Send + Sync + Clone + 'static> ServerBuilder<'a, Htt } pub async fn listen_on_default_socket(&self) -> Result { - let requested_file = if cfg!(target_os = "windows") { - PathBuf::from(format!(r"\\.\pipe\vscode-server-{}", Uuid::new_v4())) - } else { - std::env::temp_dir().join(format!("vscode-server-{}", Uuid::new_v4())) - }; - + let requested_file = get_socket_name(); self.listen_on_socket(&requested_file).await } @@ -802,3 +799,40 @@ fn parse_port_from(text: &str) -> Option { .and_then(|path| path.as_str().parse::().ok()) }) } + +pub fn print_listening(log: &log::Logger, tunnel_name: &str) { + debug!( + log, + "{} is listening for incoming connections", QUALITYLESS_SERVER_NAME + ); + + let home_dir = dirs::home_dir().unwrap_or_else(|| PathBuf::from("")); + let current_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("")); + + let dir = if home_dir == current_dir { + PathBuf::from("") + } else { + current_dir + }; + + let base_web_url = match EDITOR_WEB_URL { + Some(u) => u, + None => return, + }; + + let mut addr = url::Url::parse(base_web_url).unwrap(); + { + let mut ps = addr.path_segments_mut().unwrap(); + ps.push("tunnel"); + ps.push(tunnel_name); + for segment in &dir { + let as_str = segment.to_string_lossy(); + if !(as_str.len() == 1 && as_str.starts_with(std::path::MAIN_SEPARATOR)) { + ps.push(as_str.as_ref()); + } + } + } + + let message = &format!("\nOpen this link in your browser {}\n", addr); + log.result(message); +} diff --git a/cli/src/tunnels/control_server.rs b/cli/src/tunnels/control_server.rs index aec9309ace8..8c2d1a76d1a 100644 --- a/cli/src/tunnels/control_server.rs +++ b/cli/src/tunnels/control_server.rs @@ -2,7 +2,8 @@ * 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::{CONTROL_PORT, EDITOR_WEB_URL, QUALITYLESS_SERVER_NAME}; +use crate::async_pipe::get_socket_rw_stream; +use crate::constants::CONTROL_PORT; use crate::log; use crate::rpc::{MaybeSync, RpcBuilder, RpcDispatcher, Serialization}; use crate::self_update::SelfUpdate; @@ -24,13 +25,10 @@ use opentelemetry::trace::SpanKind; use opentelemetry::KeyValue; use std::collections::HashMap; -use std::env; -use std::path::PathBuf; use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering}; use std::sync::Arc; use std::time::Instant; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader}; -use tokio::pin; use tokio::sync::{mpsc, Mutex}; use super::code_server::{ @@ -45,7 +43,7 @@ use super::protocol::{ ServerMessageParams, ToClientRequest, UnforwardParams, UpdateParams, UpdateResult, VersionParams, }; -use super::server_bridge::{get_socket_rw_stream, ServerBridge}; +use super::server_bridge::ServerBridge; use super::server_multiplexer::ServerMultiplexer; use super::shutdown_signal::ShutdownSignal; use super::socket_signal::{ @@ -103,47 +101,18 @@ enum ServerSignal { Respawn, } -pub struct ServerTermination { +pub enum Next { /// Whether the server should be respawned in a new binary (see ServerSignal.Respawn). - pub respawn: bool, - pub tunnel: ActiveTunnel, + Respawn, + /// Whether the tunnel should be restarted + Restart, + /// Whether the process should exit + Exit, } -fn print_listening(log: &log::Logger, tunnel_name: &str) { - debug!( - log, - "{} is listening for incoming connections", QUALITYLESS_SERVER_NAME - ); - - let home_dir = dirs::home_dir().unwrap_or_else(|| PathBuf::from("")); - let current_dir = env::current_dir().unwrap_or_else(|_| PathBuf::from("")); - - let dir = if home_dir == current_dir { - PathBuf::from("") - } else { - current_dir - }; - - let base_web_url = match EDITOR_WEB_URL { - Some(u) => u, - None => return, - }; - - let mut addr = url::Url::parse(base_web_url).unwrap(); - { - let mut ps = addr.path_segments_mut().unwrap(); - ps.push("tunnel"); - ps.push(tunnel_name); - for segment in &dir { - let as_str = segment.to_string_lossy(); - if !(as_str.len() == 1 && as_str.starts_with(std::path::MAIN_SEPARATOR)) { - ps.push(as_str.as_ref()); - } - } - } - - let message = &format!("\nOpen this link in your browser {}\n", addr); - log.result(message); +pub struct ServerTermination { + pub next: Next, + pub tunnel: ActiveTunnel, } // Runs the launcher server. Exits on a ctrl+c or when requested by a user. @@ -155,24 +124,23 @@ pub async fn serve( launcher_paths: &LauncherPaths, code_server_args: &CodeServerArgs, platform: Platform, - shutdown_rx: mpsc::UnboundedReceiver, + mut shutdown_rx: Barrier, ) -> Result { let mut port = tunnel.add_port_direct(CONTROL_PORT).await?; - print_listening(log, &tunnel.name); - let mut forwarding = PortForwardingProcessor::new(); let (tx, mut rx) = mpsc::channel::(4); let (exit_barrier, signal_exit) = new_barrier(); - pin!(shutdown_rx); - loop { tokio::select! { - Some(r) = shutdown_rx.recv() => { - info!(log, "Shutting down: {}", r ); + Ok(reason) = shutdown_rx.wait() => { + info!(log, "Shutting down: {}", reason); drop(signal_exit); return Ok(ServerTermination { - respawn: false, + next: match reason { + ShutdownSignal::RpcRestartRequested => Next::Restart, + _ => Next::Exit, + }, tunnel, }); }, @@ -180,7 +148,7 @@ pub async fn serve( if let Some(ServerSignal::Respawn) = c { drop(signal_exit); return Ok(ServerTermination { - respawn: true, + next: Next::Respawn, tunnel, }); } @@ -194,7 +162,7 @@ pub async fn serve( None => { warning!(log, "ssh tunnel disposed, tearing down"); return Ok(ServerTermination { - respawn: false, + next: Next::Restart, tunnel, }); } diff --git a/cli/src/tunnels/dev_tunnels.rs b/cli/src/tunnels/dev_tunnels.rs index e489806c587..010afbdb433 100644 --- a/cli/src/tunnels/dev_tunnels.rs +++ b/cli/src/tunnels/dev_tunnels.rs @@ -317,12 +317,13 @@ impl DevTunnels { persisted: PersistedTunnel, name: &str, ) -> Result<(Tunnel, PersistedTunnel), AnyError> { - self.check_is_name_free(name).await?; + let name = name.to_ascii_lowercase(); + self.check_is_name_free(&name).await?; debug!(self.log, "Tunnel name changed, applying updates..."); let (mut full_tunnel, mut persisted, is_new) = self - .get_or_create_tunnel(persisted, Some(name), NO_REQUEST_OPTIONS) + .get_or_create_tunnel(persisted, Some(&name), NO_REQUEST_OPTIONS) .await?; if is_new { return Ok((full_tunnel, persisted)); @@ -337,7 +338,7 @@ impl DevTunnels { ) .map_err(|e| wrap(e, "failed to rename tunnel"))?; - persisted.name = name.to_string(); + persisted.name = name; self.launcher_tunnel.save(Some(persisted.clone()))?; Ok((new_tunnel, persisted)) @@ -378,15 +379,15 @@ impl DevTunnels { /// this attempts to reuse or create a tunnel of a preferred name or of a generated friendly tunnel name. pub async fn start_new_launcher_tunnel( &mut self, - preferred_name: Option, + preferred_name: Option<&str>, use_random_name: bool, ) -> Result { let (mut tunnel, persisted) = match self.launcher_tunnel.load() { Some(mut persisted) => { - if let Some(name) = preferred_name { - if persisted.name.ne(&name) { - (_, persisted) = self.update_tunnel_name(persisted, &name).await?; - } + let as_lowercase = persisted.name.to_ascii_lowercase(); + let preferred_name = preferred_name.unwrap_or(&as_lowercase); + if persisted.name != preferred_name { + (_, persisted) = self.update_tunnel_name(persisted, preferred_name).await?; } let (tunnel, persisted, _) = self @@ -631,7 +632,7 @@ impl DevTunnels { async fn get_name_for_tunnel( &mut self, - preferred_name: Option, + preferred_name: Option<&str>, mut use_random_name: bool, ) -> Result { let existing_tunnels = self.list_all_server_tunnels().await?; @@ -645,7 +646,7 @@ impl DevTunnels { }; if let Some(machine_name) = preferred_name { - let name = machine_name; + let name = machine_name.to_ascii_lowercase(); if let Err(e) = is_valid_name(&name) { info!(self.log, "{} is an invalid name", e); return Err(AnyError::from(wrap(e, "invalid name"))); @@ -662,6 +663,8 @@ impl DevTunnels { let mut placeholder_name = clean_hostname_for_tunnel(&gethostname::gethostname().to_string_lossy()); + placeholder_name.make_ascii_lowercase(); + if !is_name_free(&placeholder_name) { for i in 2.. { let fixed_name = format!("{}{}", placeholder_name, i); @@ -677,11 +680,13 @@ impl DevTunnels { } loop { - let name = prompt_placeholder( + let mut name = prompt_placeholder( "What would you like to call this machine?", &placeholder_name, )?; + name.make_ascii_lowercase(); + if let Err(e) = is_valid_name(&name) { info!(self.log, "{}", e); continue; diff --git a/cli/src/tunnels/legal.rs b/cli/src/tunnels/legal.rs index 1e3d7b1bac3..84b72bf8e69 100644 --- a/cli/src/tunnels/legal.rs +++ b/cli/src/tunnels/legal.rs @@ -41,7 +41,10 @@ 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()) + return Err(MissingLegalConsent( + "Run this command again with --accept-server-license-terms to indicate your agreement." + .to_string(), + ) .into()); } else { match prompt_yn(prompt) { diff --git a/cli/src/tunnels/protocol.rs b/cli/src/tunnels/protocol.rs index f2d6dd65dae..ef033415d93 100644 --- a/cli/src/tunnels/protocol.rs +++ b/cli/src/tunnels/protocol.rs @@ -4,7 +4,10 @@ *--------------------------------------------------------------------------------------------*/ use std::collections::HashMap; -use crate::{constants::{VSCODE_CLI_VERSION, PROTOCOL_VERSION}, options::Quality}; +use crate::{ + constants::{PROTOCOL_VERSION, VSCODE_CLI_VERSION}, + options::Quality, +}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Debug)] @@ -154,3 +157,42 @@ impl Default for VersionParams { } } } + +pub mod singleton { + use crate::log; + use serde::{Deserialize, Serialize}; + + pub const METHOD_RESTART: &str = "restart"; + pub const METHOD_SHUTDOWN: &str = "shutdown"; + pub const METHOD_STATUS: &str = "status"; + pub const METHOD_LOG: &str = "log"; + pub const METHOD_LOG_REPLY_DONE: &str = "log_done"; + + #[derive(Serialize)] + pub struct LogMessage<'a> { + pub level: Option, + pub prefix: &'a str, + pub message: &'a str, + } + + #[derive(Deserialize)] + pub struct LogMessageOwned { + pub level: Option, + pub prefix: String, + pub message: String, + } + + #[derive(Serialize, Deserialize)] + pub struct Status { + pub tunnel: TunnelState, + } + + #[derive(Deserialize, Serialize, Debug)] + pub struct LogReplayFinished {} + + #[derive(Deserialize, Serialize, Debug)] + pub enum TunnelState { + Disconnected, + Connected { name: String }, + } +} diff --git a/cli/src/tunnels/server_bridge_unix.rs b/cli/src/tunnels/server_bridge.rs similarity index 75% rename from cli/src/tunnels/server_bridge_unix.rs rename to cli/src/tunnels/server_bridge.rs index c7be34cf5d0..50dde8e7303 100644 --- a/cli/src/tunnels/server_bridge_unix.rs +++ b/cli/src/tunnels/server_bridge.rs @@ -2,36 +2,19 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -use std::path::Path; - -use tokio::{ - io::{AsyncReadExt, AsyncWriteExt}, - net::{unix::OwnedWriteHalf, UnixStream}, -}; - -use crate::util::errors::{wrap, AnyError}; - use super::socket_signal::{ClientMessageDecoder, ServerMessageSink}; +use crate::{ + async_pipe::{get_socket_rw_stream, socket_stream_split, AsyncPipeWriteHalf}, + util::errors::AnyError, +}; +use std::path::Path; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; pub struct ServerBridge { - write: OwnedWriteHalf, + write: AsyncPipeWriteHalf, decoder: ClientMessageDecoder, } -pub async fn get_socket_rw_stream(path: &Path) -> Result { - let s = UnixStream::connect(path).await.map_err(|e| { - wrap( - e, - format!( - "error connecting to vscode server socket in {}", - path.display() - ), - ) - })?; - - Ok(s) -} - const BUFFER_SIZE: usize = 65536; impl ServerBridge { @@ -41,7 +24,7 @@ impl ServerBridge { decoder: ClientMessageDecoder, ) -> Result { let stream = get_socket_rw_stream(path).await?; - let (mut read, write) = stream.into_split(); + let (mut read, write) = socket_stream_split(stream); tokio::spawn(async move { let mut read_buf = vec![0; BUFFER_SIZE]; diff --git a/cli/src/tunnels/server_bridge_windows.rs b/cli/src/tunnels/server_bridge_windows.rs deleted file mode 100644 index ca604468518..00000000000 --- a/cli/src/tunnels/server_bridge_windows.rs +++ /dev/null @@ -1,132 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -use std::{path::Path, time::Duration}; - -use tokio::{ - io::{self, Interest}, - net::windows::named_pipe::{ClientOptions, NamedPipeClient}, - sync::mpsc, - time::sleep, -}; - -use crate::util::errors::{wrap, AnyError}; - -use super::socket_signal::{ClientMessageDecoder, ServerMessageSink}; - -pub struct ServerBridge { - write_tx: mpsc::Sender>, - decoder: ClientMessageDecoder, -} - -const BUFFER_SIZE: usize = 65536; - -pub async fn get_socket_rw_stream(path: &Path) -> Result { - // Tokio says we can need to try in a loop. Do so. - // https://docs.rs/tokio/latest/tokio/net/windows/named_pipe/struct.NamedPipeClient.html - let client = loop { - match ClientOptions::new().open(path) { - Ok(client) => break client, - // ERROR_PIPE_BUSY https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499- - Err(e) if e.raw_os_error() == Some(231) => sleep(Duration::from_millis(100)).await, - Err(e) => { - return Err(AnyError::WrappedError(wrap( - e, - format!( - "error connecting to vscode server socket in {}", - path.display() - ), - ))) - } - } - }; - - Ok(client) -} - -impl ServerBridge { - pub async fn new( - path: &Path, - mut target: ServerMessageSink, - decoder: ClientMessageDecoder, - ) -> Result { - let client = get_socket_rw_stream(path).await?; - let (write_tx, mut write_rx) = mpsc::channel(4); - tokio::spawn(async move { - let mut read_buf = vec![0; BUFFER_SIZE]; - let mut pending_recv: Option> = None; - - // See https://docs.rs/tokio/1.17.0/tokio/net/windows/named_pipe/struct.NamedPipeClient.html#method.ready - // With additional complications. If there's nothing queued to write, we wait for the - // pipe to be readable, or for something to come in. If there is something to - // write, wait until the pipe is either readable or writable. - loop { - let ready_result = if pending_recv.is_none() { - tokio::select! { - msg = write_rx.recv() => match msg { - Some(msg) => { - pending_recv = Some(msg); - client.ready(Interest::READABLE | Interest::WRITABLE).await - }, - None => return - }, - r = client.ready(Interest::READABLE) => r, - } - } else { - client.ready(Interest::READABLE | Interest::WRITABLE).await - }; - - let ready = match ready_result { - Ok(r) => r, - Err(_) => return, - }; - - if ready.is_readable() { - match client.try_read(&mut read_buf) { - Ok(0) => return, // EOF - Ok(s) => { - let send = target.server_message(&read_buf[..s]).await; - if send.is_err() { - return; - } - } - Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => { - continue; - } - Err(_) => return, - } - } - - if let Some(msg) = &pending_recv { - if ready.is_writable() { - match client.try_write(msg) { - Ok(n) if n == msg.len() => pending_recv = None, - Ok(n) => pending_recv = Some(msg[n..].to_vec()), - Err(e) if e.kind() == io::ErrorKind::WouldBlock => { - continue; - } - Err(_) => return, - } - } - } - } - }); - - Ok(ServerBridge { write_tx, decoder }) - } - - pub async fn write(&mut self, b: Vec) -> std::io::Result<()> { - let dec = self.decoder.decode(&b)?; - if !dec.is_empty() { - self.write_tx.send(dec.to_vec()).await.ok(); - } - Ok(()) - } - - pub async fn close(self) -> std::io::Result<()> { - drop(self.write_tx); - Ok(()) - } -} diff --git a/cli/src/tunnels/service.rs b/cli/src/tunnels/service.rs index a0a2129bef9..31bf6890996 100644 --- a/cli/src/tunnels/service.rs +++ b/cli/src/tunnels/service.rs @@ -6,15 +6,12 @@ use std::path::{Path, PathBuf}; use async_trait::async_trait; -use tokio::sync::mpsc; use crate::log; use crate::state::LauncherPaths; use crate::util::errors::{wrap, AnyError}; use crate::util::io::{tailf, TailEvent}; -use super::shutdown_signal::ShutdownSignal; - pub const SERVICE_LOG_FILE_NAME: &str = "tunnel-service.log"; #[async_trait] @@ -23,7 +20,6 @@ pub trait ServiceContainer: Send { &mut self, log: log::Logger, launcher_paths: LauncherPaths, - shutdown_rx: mpsc::UnboundedReceiver, ) -> Result<(), AnyError>; } diff --git a/cli/src/tunnels/service_linux.rs b/cli/src/tunnels/service_linux.rs index 022d4cee409..725b72a8d6d 100644 --- a/cli/src/tunnels/service_linux.rs +++ b/cli/src/tunnels/service_linux.rs @@ -10,7 +10,6 @@ use std::{ process::Command, }; -use super::shutdown_signal::ShutdownSignal; use async_trait::async_trait; use zbus::{dbus_proxy, zvariant, Connection}; @@ -119,8 +118,7 @@ impl ServiceManager for SystemdService { launcher_paths: crate::state::LauncherPaths, mut handle: impl 'static + super::ServiceContainer, ) -> Result<(), crate::util::errors::AnyError> { - let rx = ShutdownSignal::create_rx(&[ShutdownSignal::CtrlC]); - handle.run_service(self.log, launcher_paths, rx).await + handle.run_service(self.log, launcher_paths).await } async fn show_logs(&self) -> Result<(), AnyError> { diff --git a/cli/src/tunnels/service_macos.rs b/cli/src/tunnels/service_macos.rs index 6c83af0f039..7344f34b0ac 100644 --- a/cli/src/tunnels/service_macos.rs +++ b/cli/src/tunnels/service_macos.rs @@ -9,7 +9,6 @@ use std::{ path::{Path, PathBuf}, }; -use super::shutdown_signal::ShutdownSignal; use async_trait::async_trait; use crate::{ @@ -73,8 +72,7 @@ impl ServiceManager for LaunchdService { launcher_paths: crate::state::LauncherPaths, mut handle: impl 'static + super::ServiceContainer, ) -> Result<(), crate::util::errors::AnyError> { - let rx = ShutdownSignal::create_rx(&[ShutdownSignal::CtrlC]); - handle.run_service(self.log, launcher_paths, rx).await + handle.run_service(self.log, launcher_paths).await } async fn unregister(&self) -> Result<(), crate::util::errors::AnyError> { diff --git a/cli/src/tunnels/service_windows.rs b/cli/src/tunnels/service_windows.rs index 7d839ccf330..d230d2e454f 100644 --- a/cli/src/tunnels/service_windows.rs +++ b/cli/src/tunnels/service_windows.rs @@ -17,7 +17,6 @@ use crate::{ constants::TUNNEL_ACTIVITY_NAME, log, state::LauncherPaths, - tunnels::shutdown_signal::ShutdownSignal, util::errors::{wrap, wrapdbg, AnyError}, }; @@ -90,8 +89,7 @@ impl CliServiceManager for WindowsService { launcher_paths: LauncherPaths, mut handle: impl 'static + ServiceContainer, ) -> Result<(), AnyError> { - let rx = ShutdownSignal::create_rx(&[ShutdownSignal::CtrlC]); - handle.run_service(self.log, launcher_paths, rx).await + handle.run_service(self.log, launcher_paths).await } async fn unregister(&self) -> Result<(), AnyError> { diff --git a/cli/src/tunnels/shutdown_signal.rs b/cli/src/tunnels/shutdown_signal.rs index 9e185770058..2ffbd341d3f 100644 --- a/cli/src/tunnels/shutdown_signal.rs +++ b/cli/src/tunnels/shutdown_signal.rs @@ -3,16 +3,23 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -use std::{fmt, time::Duration}; +use futures::{stream::FuturesUnordered, StreamExt}; +use std::fmt; +use sysinfo::Pid; -use sysinfo::{Pid, SystemExt}; -use tokio::{sync::mpsc, time::sleep}; +use crate::util::{ + machine::wait_until_process_exits, + sync::{new_barrier, Barrier, Receivable}, +}; /// Describes the signal to manully stop the server +#[derive(Copy, Clone)] pub enum ShutdownSignal { CtrlC, ParentProcessKilled(Pid), ServiceStopped, + RpcShutdownRequested, + RpcRestartRequested, } impl fmt::Display for ShutdownSignal { @@ -23,41 +30,52 @@ impl fmt::Display for ShutdownSignal { write!(f, "Parent process {} no longer exists", p) } ShutdownSignal::ServiceStopped => write!(f, "Service stopped"), + ShutdownSignal::RpcShutdownRequested => write!(f, "RPC client requested shutdown"), + ShutdownSignal::RpcRestartRequested => { + write!(f, "RPC client requested a tunnel restart") + } } } } -impl ShutdownSignal { +pub enum ShutdownRequest { + CtrlC, + ParentProcessKilled(Pid), + Derived(Box + Send>), +} + +impl ShutdownRequest { + async fn wait(self) -> Option { + match self { + ShutdownRequest::CtrlC => { + let ctrl_c = tokio::signal::ctrl_c(); + ctrl_c.await.ok(); + Some(ShutdownSignal::CtrlC) + } + ShutdownRequest::ParentProcessKilled(pid) => { + wait_until_process_exits(pid, 2000).await; + Some(ShutdownSignal::ParentProcessKilled(pid)) + } + ShutdownRequest::Derived(mut rx) => rx.recv_msg().await, + } + } /// Creates a receiver channel sent to once any of the signals are received. /// Note: does not handle ServiceStopped - pub fn create_rx(signals: &[ShutdownSignal]) -> mpsc::UnboundedReceiver { - let (tx, rx) = mpsc::unbounded_channel(); - for signal in signals { - let tx = tx.clone(); - match signal { - ShutdownSignal::CtrlC => { - let ctrl_c = tokio::signal::ctrl_c(); - tokio::spawn(async move { - ctrl_c.await.ok(); - tx.send(ShutdownSignal::CtrlC).ok(); - }); - } - ShutdownSignal::ParentProcessKilled(pid) => { - let pid = *pid; - let tx = tx.clone(); - tokio::spawn(async move { - let mut s = sysinfo::System::new(); - while s.refresh_process(pid) { - sleep(Duration::from_millis(2000)).await; - } - tx.send(ShutdownSignal::ParentProcessKilled(pid)).ok(); - }); - } - ShutdownSignal::ServiceStopped => { - unreachable!("Cannot use ServiceStopped in ShutdownSignal::create_rx"); - } + pub fn create_rx( + signals: impl IntoIterator, + ) -> Barrier { + let (barrier, opener) = new_barrier(); + let futures = signals + .into_iter() + .map(|s| s.wait()) + .collect::>(); + + tokio::spawn(async move { + if let Some(s) = futures.filter_map(futures::future::ready).next().await { + opener.open(s); } - } - rx + }); + + barrier } } diff --git a/cli/src/tunnels/singleton_client.rs b/cli/src/tunnels/singleton_client.rs new file mode 100644 index 00000000000..3a04daa4939 --- /dev/null +++ b/cli/src/tunnels/singleton_client.rs @@ -0,0 +1,144 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +use std::{ + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + thread, +}; + +use const_format::concatcp; +use tokio::sync::mpsc; + +use crate::{ + async_pipe::{socket_stream_split, AsyncPipe}, + constants::IS_INTERACTIVE_CLI, + json_rpc::{new_json_rpc, start_json_rpc, JsonRpcSerializer}, + log, + rpc::RpcCaller, + tunnels::{code_server::print_listening, protocol::EmptyObject}, + util::sync::Barrier, +}; + +use super::{protocol, shutdown_signal::ShutdownSignal}; + +pub struct SingletonClientArgs { + pub log: log::Logger, + pub stream: AsyncPipe, + pub shutdown: Barrier, +} + +struct SingletonServerContext { + log: log::Logger, + exit_entirely: Arc, + caller: RpcCaller, +} + +const CONTROL_INSTRUCTIONS_COMMON: &str = + "Connected to an existing tunnel process running on this machine. You can press: + +- \"x\" + Enter to stop the tunnel and exit +- \"r\" + Enter to restart the tunnel +"; + +const CONTROL_INSTRUCTIONS_INTERACTIVE: &str = concatcp!( + CONTROL_INSTRUCTIONS_COMMON, + "- Ctrl+C to detach +" +); + +/// Serves a client singleton. Returns true if the process should exit after +/// this returns, instead of trying to start a tunnel. +pub async fn start_singleton_client(args: SingletonClientArgs) -> bool { + let mut rpc = new_json_rpc(); + let (msg_tx, msg_rx) = mpsc::unbounded_channel(); + let exit_entirely = Arc::new(AtomicBool::new(false)); + + debug!( + args.log, + "An existing tunnel is running on this machine, connecting to it..." + ); + + let stdin_handle = rpc.get_caller(msg_tx.clone()); + thread::spawn(move || { + let mut input = String::new(); + loop { + input.truncate(0); + + match std::io::stdin().read_line(&mut input) { + Err(_) | Ok(0) => return, // EOF or not a tty + _ => {} + }; + + match input.chars().next().map(|c| c.to_ascii_lowercase()) { + Some('x') => { + stdin_handle.notify(protocol::singleton::METHOD_SHUTDOWN, EmptyObject {}); + return; + } + Some('r') => { + stdin_handle.notify(protocol::singleton::METHOD_RESTART, EmptyObject {}); + } + Some(_) | None => {} + } + } + }); + + let caller = rpc.get_caller(msg_tx); + let mut rpc = rpc.methods(SingletonServerContext { + log: args.log.clone(), + exit_entirely: exit_entirely.clone(), + caller, + }); + + rpc.register_sync(protocol::singleton::METHOD_SHUTDOWN, |_: EmptyObject, c| { + c.exit_entirely.store(true, Ordering::SeqCst); + Ok(()) + }); + + rpc.register_async( + protocol::singleton::METHOD_LOG_REPLY_DONE, + |_: EmptyObject, c| async move { + c.log.result(if *IS_INTERACTIVE_CLI { + CONTROL_INSTRUCTIONS_INTERACTIVE + } else { + CONTROL_INSTRUCTIONS_COMMON + }); + + let res = c.caller.call::<_, _, protocol::singleton::Status>( + protocol::singleton::METHOD_STATUS, + protocol::EmptyObject {}, + ); + + // we want to ensure the "listening" string always gets printed for + // consumers (i.e. VS Code). Ask for it. If the tunnel is not currently + // connected though, it will be soon, and that'll be in the log replays. + if let Ok(Ok(s)) = res.await { + if let protocol::singleton::TunnelState::Connected { name } = s.tunnel { + print_listening(&c.log, &name); + } + } + + Ok(()) + }, + ); + + rpc.register_sync( + protocol::singleton::METHOD_LOG, + |log: protocol::singleton::LogMessageOwned, c| { + match log.level { + Some(level) => c.log.emit(level, &format!("{}{}", log.prefix, log.message)), + None => c.log.result(format!("{}{}", log.prefix, log.message)), + } + Ok(()) + }, + ); + + let (read, write) = socket_stream_split(args.stream); + let _ = start_json_rpc(rpc.build(args.log), read, write, msg_rx, args.shutdown).await; + + exit_entirely.load(Ordering::SeqCst) +} diff --git a/cli/src/tunnels/singleton_server.rs b/cli/src/tunnels/singleton_server.rs new file mode 100644 index 00000000000..703c09f5120 --- /dev/null +++ b/cli/src/tunnels/singleton_server.rs @@ -0,0 +1,263 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +use std::{ + pin::Pin, + sync::{Arc, Mutex}, +}; + +use super::{ + code_server::CodeServerArgs, + control_server::ServerTermination, + dev_tunnels::ActiveTunnel, + protocol, + shutdown_signal::{ShutdownRequest, ShutdownSignal}, +}; +use crate::{ + async_pipe::socket_stream_split, + json_rpc::{new_json_rpc, start_json_rpc, JsonRpcSerializer}, + log, + rpc::{RpcCaller, RpcDispatcher}, + singleton::SingletonServer, + state::LauncherPaths, + tunnels::code_server::print_listening, + update_service::Platform, + util::{ + errors::{AnyError, CodeError}, + ring_buffer::RingBuffer, + sync::{Barrier, ConcatReceivable}, + }, +}; +use futures::future::Either; +use tokio::{ + pin, + sync::{broadcast, mpsc}, + task::JoinHandle, +}; + +pub struct SingletonServerArgs<'a> { + pub server: &'a mut RpcServer, + pub log: log::Logger, + pub tunnel: ActiveTunnel, + pub paths: &'a LauncherPaths, + pub code_server_args: &'a CodeServerArgs, + pub platform: Platform, + pub shutdown: Barrier, + pub log_broadcast: &'a BroadcastLogSink, +} + +#[derive(Clone)] +struct SingletonServerContext { + log: log::Logger, + shutdown_tx: broadcast::Sender, + broadcast_tx: broadcast::Sender>, + current_name: Arc>>, +} + +pub struct RpcServer { + fut: JoinHandle>, + shutdown_broadcast: broadcast::Sender, + current_name: Arc>>, +} + +pub fn make_singleton_server( + log_broadcast: BroadcastLogSink, + log: log::Logger, + server: SingletonServer, + shutdown_rx: Barrier, +) -> RpcServer { + let (shutdown_broadcast, _) = broadcast::channel(4); + let rpc = new_json_rpc(); + + let current_name = Arc::new(Mutex::new(None)); + let mut rpc = rpc.methods(SingletonServerContext { + log: log.clone(), + shutdown_tx: shutdown_broadcast.clone(), + broadcast_tx: log_broadcast.get_brocaster(), + current_name: current_name.clone(), + }); + + rpc.register_sync( + protocol::singleton::METHOD_RESTART, + |_: protocol::EmptyObject, ctx| { + info!(ctx.log, "restarting tunnel after client request"); + let _ = ctx.shutdown_tx.send(ShutdownSignal::RpcRestartRequested); + Ok(()) + }, + ); + + rpc.register_sync( + protocol::singleton::METHOD_STATUS, + |_: protocol::EmptyObject, c| { + Ok(protocol::singleton::Status { + tunnel: match c.current_name.lock().unwrap().clone() { + Some(name) => protocol::singleton::TunnelState::Connected { name }, + None => protocol::singleton::TunnelState::Disconnected, + }, + }) + }, + ); + + rpc.register_sync( + protocol::singleton::METHOD_SHUTDOWN, + |_: protocol::EmptyObject, ctx| { + info!( + ctx.log, + "closing tunnel and all clients after a shutdown request" + ); + let _ = ctx.broadcast_tx.send(RpcCaller::serialize_notify( + &JsonRpcSerializer {}, + protocol::singleton::METHOD_SHUTDOWN, + protocol::EmptyObject {}, + )); + let _ = ctx.shutdown_tx.send(ShutdownSignal::RpcShutdownRequested); + Ok(()) + }, + ); + + // we tokio spawn instead of keeping a future, since we want it to progress + // even outside of the start_singleton_server loop (i.e. while the tunnel restarts) + let fut = tokio::spawn(async move { + serve_singleton_rpc(log_broadcast, server, rpc.build(log), shutdown_rx).await + }); + RpcServer { + shutdown_broadcast, + current_name, + fut, + } +} + +pub async fn start_singleton_server<'a>( + args: SingletonServerArgs<'_>, +) -> Result { + let shutdown_rx = ShutdownRequest::create_rx([ + ShutdownRequest::Derived(Box::new(args.server.shutdown_broadcast.subscribe())), + ShutdownRequest::Derived(Box::new(args.shutdown.clone())), + ]); + + { + print_listening(&args.log, &args.tunnel.name); + let mut name = args.server.current_name.lock().unwrap(); + *name = Some(args.tunnel.name.clone()) + } + + let serve_fut = super::serve( + &args.log, + args.tunnel, + args.paths, + args.code_server_args, + args.platform, + shutdown_rx, + ); + + pin!(serve_fut); + + match futures::future::select(Pin::new(&mut args.server.fut), &mut serve_fut).await { + Either::Left((rpc_result, fut)) => { + // the rpc server will only end as a result of a graceful shutdown, or + // with an error. Return the result of the eventual shutdown of the + // control server. + rpc_result.unwrap()?; + fut.await + } + Either::Right((ctrl_result, _)) => ctrl_result, + } +} + +async fn serve_singleton_rpc( + log_broadcast: BroadcastLogSink, + mut server: SingletonServer, + dispatcher: RpcDispatcher, + shutdown_rx: Barrier, +) -> Result<(), CodeError> { + let mut own_shutdown = shutdown_rx.clone(); + let shutdown_fut = own_shutdown.wait(); + pin!(shutdown_fut); + + loop { + let cnx = tokio::select! { + c = server.accept() => c?, + _ = &mut shutdown_fut => return Ok(()), + }; + + let (read, write) = socket_stream_split(cnx); + let dispatcher = dispatcher.clone(); + let msg_rx = log_broadcast.replay_and_subscribe(); + let shutdown_rx = shutdown_rx.clone(); + tokio::spawn(async move { + let _ = start_json_rpc(dispatcher.clone(), read, write, msg_rx, shutdown_rx).await; + }); + } +} + +/// Log sink that can broadcast and replay log events. Used for transmitting +/// logs from the singleton to all clients. This should be created and injected +/// into other services, like the tunnel, before `start_singleton_server` +/// is called. +#[derive(Clone)] +pub struct BroadcastLogSink { + recent: Arc>>>, + tx: broadcast::Sender>, +} + +impl Default for BroadcastLogSink { + fn default() -> Self { + Self::new() + } +} + +impl BroadcastLogSink { + pub fn new() -> Self { + let (tx, _) = broadcast::channel(64); + Self { + tx, + recent: Arc::new(Mutex::new(RingBuffer::new(50))), + } + } + + fn get_brocaster(&self) -> broadcast::Sender> { + self.tx.clone() + } + + fn replay_and_subscribe( + &self, + ) -> ConcatReceivable, mpsc::UnboundedReceiver>, broadcast::Receiver>> { + let (log_replay_tx, log_replay_rx) = mpsc::unbounded_channel(); + + for log in self.recent.lock().unwrap().iter() { + let _ = log_replay_tx.send(log.clone()); + } + + let _ = log_replay_tx.send(RpcCaller::serialize_notify( + &JsonRpcSerializer {}, + protocol::singleton::METHOD_LOG_REPLY_DONE, + protocol::EmptyObject {}, + )); + + ConcatReceivable::new(log_replay_rx, self.tx.subscribe()) + } +} + +impl log::LogSink for BroadcastLogSink { + fn write_log(&self, level: log::Level, prefix: &str, message: &str) { + let s = JsonRpcSerializer {}; + let serialized = RpcCaller::serialize_notify( + &s, + protocol::singleton::METHOD_LOG, + protocol::singleton::LogMessage { + level: Some(level), + prefix, + message, + }, + ); + + let _ = self.tx.send(serialized.clone()); + self.recent.lock().unwrap().push(serialized); + } + + fn write_result(&self, message: &str) { + self.write_log(log::Level::Info, "", message); + } +} diff --git a/cli/src/tunnels/wsl_server.rs b/cli/src/tunnels/wsl_server.rs index 8859cc7f53e..b6250c8247f 100644 --- a/cli/src/tunnels/wsl_server.rs +++ b/cli/src/tunnels/wsl_server.rs @@ -16,6 +16,7 @@ use crate::{ wrap, AnyError, InvalidRpcDataError, MismatchedLaunchModeError, NoAttachedServerError, }, http::ReqwestSimpleHttp, + sync::Barrier, }, }; @@ -69,7 +70,7 @@ pub async fn serve_wsl( code_server_args: CodeServerArgs, platform: Platform, http: reqwest::Client, - shutdown_rx: mpsc::UnboundedReceiver, + shutdown_rx: Barrier, ) -> Result { let (caller_tx, caller_rx) = mpsc::unbounded_channel(); let mut rpc = new_msgpack_rpc(); diff --git a/cli/src/util.rs b/cli/src/util.rs index 2ed47f2f263..48eb634eb8a 100644 --- a/cli/src/util.rs +++ b/cli/src/util.rs @@ -12,8 +12,10 @@ pub mod input; pub mod io; pub mod machine; pub mod prereqs; +pub mod ring_buffer; pub mod sync; pub use is_integrated::*; +pub mod file_lock; #[cfg(target_os = "linux")] pub mod tar; diff --git a/cli/src/util/errors.rs b/cli/src/util/errors.rs index fa5d67db300..6ccc15fc9ed 100644 --- a/cli/src/util/errors.rs +++ b/cli/src/util/errors.rs @@ -2,11 +2,12 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -use std::fmt::Display; - -use crate::constants::{ - APPLICATION_NAME, CONTROL_PORT, DOCUMENTATION_URL, QUALITYLESS_PRODUCT_NAME, +use crate::{ + constants::{APPLICATION_NAME, CONTROL_PORT, DOCUMENTATION_URL, QUALITYLESS_PRODUCT_NAME}, + rpc::ResponseError, }; +use std::fmt::Display; +use thiserror::Error; // Wraps another error with additional info. #[derive(Debug, Clone)] @@ -171,7 +172,7 @@ impl std::fmt::Display for SetupError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, - "{}\r\n\r\nMore info at {}/remote/linux", + "{}\n\nMore info at {}/remote/linux", DOCUMENTATION_URL.unwrap_or(""), self.0 ) @@ -343,7 +344,7 @@ pub struct ServiceAlreadyRegistered(); impl std::fmt::Display for ServiceAlreadyRegistered { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "Already registered the service. Run `code tunnel service uninstall` to unregister it first") + write!(f, "Already registered the service. Run `{} tunnel service uninstall` to unregister it first", APPLICATION_NAME) } } @@ -475,6 +476,26 @@ macro_rules! makeAnyError { }; } +/// Internal errors in the VS Code CLI. +/// Note: other error should be migrated to this type gradually +#[derive(Error, Debug)] +pub enum CodeError { + #[error("could not connect to socket/pipe: {0:?}")] + AsyncPipeFailed(std::io::Error), + #[error("could not listen on socket/pipe: {0:?}")] + AsyncPipeListenerFailed(std::io::Error), + #[error("could not create singleton lock file: {0:?}")] + SingletonLockfileOpenFailed(std::io::Error), + #[error("could not read singleton lock file: {0:?}")] + SingletonLockfileReadFailed(rmp_serde::decode::Error), + #[error("the process holding the singleton lock file (pid={0}) exited")] + SingletonLockedProcessExited(u32), + #[error("no tunnel process is currently running")] + NoRunningTunnel, + #[error("rpc call failed: {0:?}")] + TunnelRpcCallFailed(ResponseError), +} + makeAnyError!( MissingLegalConsent, MismatchConnectionToken, @@ -505,7 +526,8 @@ makeAnyError!( MissingHomeDirectory, CommandFailed, OAuthError, - InvalidRpcDataError + InvalidRpcDataError, + CodeError ); impl From for AnyError { diff --git a/cli/src/util/file_lock.rs b/cli/src/util/file_lock.rs new file mode 100644 index 00000000000..8ee60cba4f8 --- /dev/null +++ b/cli/src/util/file_lock.rs @@ -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. + *--------------------------------------------------------------------------------------------*/ + +use crate::util::errors::CodeError; +use std::{fs::File, io}; + +pub struct FileLock { + file: File, + #[cfg(windows)] + overlapped: winapi::um::minwinbase::OVERLAPPED, +} + +#[cfg(windows)] // overlapped is thread-safe, mark it so with this +unsafe impl Send for FileLock {} + +pub enum Lock { + Acquired(FileLock), + AlreadyLocked(File), +} + +/// Number of locked bytes in the file. On Windows, locking prevents reads, +/// but consumers of the lock may still want to read what the locking file +/// as written. Thus, only PREFIX_LOCKED_BYTES are locked, and any globally- +/// readable content should be written after the prefix. +#[cfg(windows)] +pub const PREFIX_LOCKED_BYTES: usize = 1; + +#[cfg(unix)] +pub const PREFIX_LOCKED_BYTES: usize = 0; + +impl FileLock { + #[cfg(windows)] + pub fn acquire(file: File) -> Result { + use std::os::windows::prelude::AsRawHandle; + use winapi::{ + shared::winerror::{ERROR_IO_PENDING, ERROR_LOCK_VIOLATION}, + um::{ + fileapi::LockFileEx, + minwinbase::{LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY}, + }, + }; + + let handle = file.as_raw_handle(); + let (overlapped, ok) = unsafe { + let mut overlapped = std::mem::zeroed(); + let ok = LockFileEx( + handle, + LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, + 0, + PREFIX_LOCKED_BYTES as u32, + 0, + &mut overlapped, + ); + + (overlapped, ok) + }; + + if ok != 0 { + return Ok(Lock::Acquired(Self { file, overlapped })); + } + + let err = io::Error::last_os_error(); + let raw = err.raw_os_error(); + // docs report it should return ERROR_IO_PENDING, but in my testing it actually + // returns ERROR_LOCK_VIOLATION. Or maybe winapi is wrong? + if raw == Some(ERROR_IO_PENDING as i32) || raw == Some(ERROR_LOCK_VIOLATION as i32) { + return Ok(Lock::AlreadyLocked(file)); + } + + Err(CodeError::SingletonLockfileOpenFailed(err)) + } + + #[cfg(unix)] + pub fn acquire(file: File) -> Result { + use std::os::unix::io::AsRawFd; + + let fd = file.as_raw_fd(); + let res = unsafe { libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB) }; + if res == 0 { + return Ok(Lock::Acquired(Self { file })); + } + + let err = io::Error::last_os_error(); + if err.kind() == io::ErrorKind::WouldBlock { + return Ok(Lock::AlreadyLocked(file)); + } + + Err(CodeError::SingletonLockfileOpenFailed(err)) + } + + pub fn file(&self) -> &File { + &self.file + } + + pub fn file_mut(&mut self) -> &mut File { + &mut self.file + } +} + +impl Drop for FileLock { + #[cfg(windows)] + fn drop(&mut self) { + use std::os::windows::prelude::AsRawHandle; + use winapi::um::fileapi::UnlockFileEx; + + unsafe { + UnlockFileEx( + self.file.as_raw_handle(), + 0, + u32::MAX, + u32::MAX, + &mut self.overlapped, + ) + }; + } + + #[cfg(unix)] + fn drop(&mut self) { + use std::os::unix::io::AsRawFd; + + unsafe { libc::flock(self.file.as_raw_fd(), libc::LOCK_UN) }; + } +} diff --git a/cli/src/util/io.rs b/cli/src/util/io.rs index a21a2ceb632..95b378c0c65 100644 --- a/cli/src/util/io.rs +++ b/cli/src/util/io.rs @@ -15,6 +15,8 @@ use tokio::{ time::sleep, }; +use super::ring_buffer::RingBuffer; + pub trait ReportCopyProgress { fn report_progress(&mut self, bytes_so_far: u64, total_bytes: u64); } @@ -132,8 +134,7 @@ pub fn tailf(file: File, n: usize) -> mpsc::UnboundedReceiver { // Read the initial "n" lines back from the request. initial_lines // is a small ring buffer. - let mut initial_lines = Vec::with_capacity(n); - let mut initial_lines_i = 0; + let mut initial_lines = RingBuffer::new(n); loop { let mut line = String::new(); let bytes_read = match reader.read_line(&mut line) { @@ -151,26 +152,11 @@ pub fn tailf(file: File, n: usize) -> mpsc::UnboundedReceiver { } pos += bytes_read as u64; - if initial_lines.len() < initial_lines.capacity() { - initial_lines.push(line) - } else { - initial_lines[initial_lines_i] = line; - } - - initial_lines_i = (initial_lines_i + 1) % n; + initial_lines.push(line); } - // remove tail lines... - if initial_lines_i < initial_lines.len() { - for line in initial_lines.drain((initial_lines_i)..) { - tx.send(TailEvent::Line(line)).ok(); - } - } - // then the remaining lines - if !initial_lines.is_empty() { - for line in initial_lines.drain(0..) { - tx.send(TailEvent::Line(line)).ok(); - } + for line in initial_lines.into_iter() { + tx.send(TailEvent::Line(line)).ok(); } // now spawn the poll process to keep reading new lines diff --git a/cli/src/util/machine.rs b/cli/src/util/machine.rs index c3e0e2bfb98..e97a043a637 100644 --- a/cli/src/util/machine.rs +++ b/cli/src/util/machine.rs @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -use std::path::Path; +use std::{path::Path, time::Duration}; use sysinfo::{Pid, PidExt, ProcessExt, System, SystemExt}; pub fn process_at_path_exists(pid: u32, name: &Path) -> bool { @@ -29,6 +29,14 @@ pub fn process_exists(pid: u32) -> bool { sys.refresh_process(Pid::from_u32(pid)) } +pub async fn wait_until_process_exits(pid: Pid, poll_ms: u64) { + let mut s = System::new(); + let duration = Duration::from_millis(poll_ms); + while s.refresh_process(pid) { + tokio::time::sleep(duration).await; + } +} + pub fn find_running_process(name: &Path) -> Option { let mut sys = System::new(); sys.refresh_processes(); diff --git a/cli/src/util/ring_buffer.rs b/cli/src/util/ring_buffer.rs new file mode 100644 index 00000000000..3dfb8c587d9 --- /dev/null +++ b/cli/src/util/ring_buffer.rs @@ -0,0 +1,142 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +pub struct RingBuffer { + data: Vec, + i: usize, +} + +impl RingBuffer { + pub fn new(capacity: usize) -> Self { + Self { + data: Vec::with_capacity(capacity), + i: 0, + } + } + + pub fn capacity(&self) -> usize { + self.data.capacity() + } + + pub fn len(&self) -> usize { + self.data.len() + } + + pub fn is_full(&self) -> bool { + self.data.len() == self.data.capacity() + } + + pub fn is_empty(&self) -> bool { + self.data.len() == 0 + } + + pub fn push(&mut self, value: T) { + if self.data.len() == self.data.capacity() { + self.data[self.i] = value; + } else { + self.data.push(value); + } + + self.i = (self.i + 1) % self.data.capacity(); + } + + pub fn iter(&self) -> RingBufferIter<'_, T> { + RingBufferIter { + index: 0, + buffer: self, + } + } +} + +impl IntoIterator for RingBuffer { + type Item = T; + type IntoIter = OwnedRingBufferIter; + + fn into_iter(self) -> OwnedRingBufferIter + where + T: Default, + { + OwnedRingBufferIter { + index: 0, + buffer: self, + } + } +} + +pub struct OwnedRingBufferIter { + buffer: RingBuffer, + index: usize, +} + +impl Iterator for OwnedRingBufferIter { + type Item = T; + + fn next(&mut self) -> Option { + if self.index == self.buffer.len() { + return None; + } + + let ii = (self.index + self.buffer.i) % self.buffer.len(); + let item = std::mem::take(&mut self.buffer.data[ii]); + self.index += 1; + Some(item) + } +} + +pub struct RingBufferIter<'a, T> { + buffer: &'a RingBuffer, + index: usize, +} + +impl<'a, T> Iterator for RingBufferIter<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + if self.index == self.buffer.len() { + return None; + } + + let ii = (self.index + self.buffer.i) % self.buffer.len(); + let item = &self.buffer.data[ii]; + self.index += 1; + Some(item) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_inserts() { + let mut rb = RingBuffer::new(3); + assert_eq!(rb.capacity(), 3); + assert!(!rb.is_full()); + assert_eq!(rb.len(), 0); + assert_eq!(rb.iter().copied().count(), 0); + + rb.push(1); + assert!(!rb.is_full()); + assert_eq!(rb.len(), 1); + assert_eq!(rb.iter().copied().collect::>(), vec![1]); + + rb.push(2); + assert!(!rb.is_full()); + assert_eq!(rb.len(), 2); + assert_eq!(rb.iter().copied().collect::>(), vec![1, 2]); + + rb.push(3); + assert!(rb.is_full()); + assert_eq!(rb.len(), 3); + assert_eq!(rb.iter().copied().collect::>(), vec![1, 2, 3]); + + rb.push(4); + assert!(rb.is_full()); + assert_eq!(rb.len(), 3); + assert_eq!(rb.iter().copied().collect::>(), vec![2, 3, 4]); + + assert_eq!(rb.into_iter().collect::>(), vec![2, 3, 4]); + } +} diff --git a/cli/src/util/sync.rs b/cli/src/util/sync.rs index 5f33419488a..8b653cd2d53 100644 --- a/cli/src/util/sync.rs +++ b/cli/src/util/sync.rs @@ -2,38 +2,60 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -use tokio::sync::watch::{ - self, - error::{RecvError, SendError}, +use async_trait::async_trait; +use std::{marker::PhantomData, sync::Arc}; +use tokio::sync::{ + broadcast, mpsc, + watch::{self, error::RecvError}, }; #[derive(Clone)] pub struct Barrier(watch::Receiver>) where - T: Copy; + T: Clone; impl Barrier where - T: Copy, + T: Clone, { /// Waits for the barrier to be closed, returning a value if one was sent. pub async fn wait(&mut self) -> Result { loop { self.0.changed().await?; - if let Some(v) = *(self.0.borrow()) { + if let Some(v) = self.0.borrow().clone() { return Ok(v); } } } + + /// Gets whether the barrier is currently open + pub fn is_open(&self) -> bool { + self.0.borrow().is_some() + } } -pub struct BarrierOpener(watch::Sender>); +#[async_trait] +impl Receivable for Barrier { + async fn recv_msg(&mut self) -> Option { + self.wait().await.ok() + } +} -impl BarrierOpener { - /// Closes the barrier. - pub fn open(self, value: T) -> Result<(), SendError>> { - self.0.send(Some(value)) +#[derive(Clone)] +pub struct BarrierOpener(Arc>>); + +impl BarrierOpener { + /// Opens the barrier. + pub fn open(&self, value: T) { + self.0.send_if_modified(|v| { + if v.is_none() { + *v = Some(value); + true + } else { + false + } + }); } } @@ -44,7 +66,119 @@ where T: Copy, { let (closed_tx, closed_rx) = watch::channel(None); - (Barrier(closed_rx), BarrierOpener(closed_tx)) + (Barrier(closed_rx), BarrierOpener(Arc::new(closed_tx))) +} + +/// Type that can receive messages in an async way. +#[async_trait] +pub trait Receivable { + async fn recv_msg(&mut self) -> Option; +} + +// todo: ideally we would use an Arc in the broadcast::Receiver to avoid having +// to clone bytes everywhere, requires updating rpc consumers as well. +#[async_trait] +impl Receivable for broadcast::Receiver { + async fn recv_msg(&mut self) -> Option { + loop { + match self.recv().await { + Ok(v) => return Some(v), + Err(broadcast::error::RecvError::Lagged(_)) => continue, + Err(broadcast::error::RecvError::Closed) => return None, + } + } + } +} + +#[async_trait] +impl Receivable for mpsc::UnboundedReceiver { + async fn recv_msg(&mut self) -> Option { + self.recv().await + } +} + +#[async_trait] +impl Receivable for () { + async fn recv_msg(&mut self) -> Option { + futures::future::pending().await + } +} + +pub struct ConcatReceivable, B: Receivable> { + left: Option, + right: B, + _marker: PhantomData, +} + +impl, B: Receivable> ConcatReceivable { + pub fn new(left: A, right: B) -> Self { + Self { + left: Some(left), + right, + _marker: PhantomData, + } + } +} + +#[async_trait] +impl, B: Send + Receivable> Receivable + for ConcatReceivable +{ + async fn recv_msg(&mut self) -> Option { + if let Some(left) = &mut self.left { + match left.recv_msg().await { + Some(v) => return Some(v), + None => { + self.left = None; + } + } + } + + return self.right.recv_msg().await; + } +} + +pub struct MergedReceivable, B: Receivable> { + left: Option, + right: Option, + _marker: PhantomData, +} + +impl, B: Receivable> MergedReceivable { + pub fn new(left: A, right: B) -> Self { + Self { + left: Some(left), + right: Some(right), + _marker: PhantomData, + } + } +} + +#[async_trait] +impl, B: Send + Receivable> Receivable + for MergedReceivable +{ + async fn recv_msg(&mut self) -> Option { + loop { + match (&mut self.left, &mut self.right) { + (Some(left), Some(right)) => { + tokio::select! { + left = left.recv_msg() => match left { + Some(v) => return Some(v), + None => { self.left = None; continue; }, + }, + right = right.recv_msg() => match right { + Some(v) => return Some(v), + None => { self.right = None; continue; }, + }, + } + } + (Some(a), None) => break a.recv_msg().await, + (None, Some(b)) => break b.recv_msg().await, + (None, None) => break None, + } + } + } } #[cfg(test)] @@ -60,7 +194,7 @@ mod tests { tx.send(barrier.wait().await.unwrap()).unwrap(); }); - opener.open(42).unwrap(); + opener.open(42); assert!(rx.await.unwrap() == 42); } @@ -71,7 +205,7 @@ mod tests { let (tx1, rx1) = tokio::sync::oneshot::channel::(); let (tx2, rx2) = tokio::sync::oneshot::channel::(); - opener.open(42).unwrap(); + opener.open(42); let mut b1 = barrier.clone(); tokio::spawn(async move { tx1.send(b1.wait().await.unwrap()).unwrap(); diff --git a/extensions/configuration-editing/src/settingsDocumentHelper.ts b/extensions/configuration-editing/src/settingsDocumentHelper.ts index 6c52bb5a511..110494fdb3e 100644 --- a/extensions/configuration-editing/src/settingsDocumentHelper.ts +++ b/extensions/configuration-editing/src/settingsDocumentHelper.ts @@ -266,7 +266,7 @@ export class SettingsDocument { const languageOverrideRange = languageOverridesRanges.find(range => range.contains(position)); /** - * Skip if suggestsions are for first language override range + * Skip if suggestions are for first language override range * Since VSCode registers language overrides to the schema, JSON language server does suggestions for first language override. */ if (languageOverrideRange && !languageOverrideRange.isEqual(languageOverridesRanges[0])) { diff --git a/extensions/cpp/cgmanifest.json b/extensions/cpp/cgmanifest.json index 1e88d9a4261..03ec3e1ac14 100644 --- a/extensions/cpp/cgmanifest.json +++ b/extensions/cpp/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "jeff-hykin/better-cpp-syntax", "repositoryUrl": "https://github.com/jeff-hykin/better-cpp-syntax", - "commitHash": "e3f51cca7683d2b2b086f889bff586bf9d85eb1f" + "commitHash": "f1d127a8af2b184db570345f0bb179503c47fdf6" } }, "license": "MIT", - "version": "1.17.3", + "version": "1.17.4", "description": "The original JSON grammars were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." }, { diff --git a/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json b/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json index f8b5550ea46..03c6f1ef93e 100644 --- a/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json +++ b/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jeff-hykin/better-cpp-syntax/commit/634bb689da96fb6515b1a688ad3dffede5aa234d", + "version": "https://github.com/jeff-hykin/better-cpp-syntax/commit/f1d127a8af2b184db570345f0bb179503c47fdf6", "name": "C++", "scopeName": "source.cpp.embedded.macro", "patterns": [ @@ -126,11 +126,14 @@ }, { "include": "#string_context" + }, + { + "include": "#ever_present_context" } ] }, { - "match": "(using)(?:\\s)+((?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(\\()", + "begin": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)(((?>(?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?=\\())", + "begin": "\\s*+((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(((?>(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(\\()", + "begin": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(\\{)", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\{)", "end": "\\}|(?=(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)(((?>(?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?=\\())", + "begin": "((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(((?>(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::))?(?:(?:\\s)+)?((?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::))?(?:\\s+)?((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(\\()", + "begin": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)|(?=(?|\\*\\/))\\s*+(?:((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|\\*\\/))\\s*+(?:((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", + "match": "(?<=^|\\))(?:\\s+)?(->)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", "captures": { "1": { "name": "punctuation.definition.function.return-type.cpp" @@ -3721,8 +3669,8 @@ ] }, "function_pointer": { - "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(\\()(\\*)(?:(?:\\s)+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:(?:\\s)+)?(?:(\\[)(\\w*)(\\])(?:(?:\\s)+)?)*(\\))(?:(?:\\s)+)?(\\()", - "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?=[{=,);>]|\\n)(?!\\()|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", + "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(\\()(\\*)(?:(?:\\s)+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:(?:\\s)+)?(?:(\\[)(\\w*)(\\])(?:(?:\\s)+)?)*(\\))(?:(?:\\s)+)?(\\()", - "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?=[{=,);>]|\\n)(?!\\()|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", + "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", + "match": "(?<=protected|virtual|private|public|,|:)(?:\\s+)?(?!(?:(?:(?:protected)|(?:private)|(?:public))|virtual))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", "captures": { "1": { "name": "meta.qualified_type.cpp", @@ -4531,7 +4485,7 @@ ] }, "lambdas": { - "begin": "(?:(?<=[^\\s]|^)(?])|(?<=\\Wreturn|^return))(?:(?:\\s)+)?(\\[(?!\\[| *+\"| *+\\d))((?:[^\\[\\]]|((??)++\\]))*+)(\\](?!((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))[\\[\\];]))", + "begin": "(?:(?<=[^\\s]|^)(?])|(?<=\\Wreturn|^return))(?:\\s+)?(\\[(?!\\[| *+\"| *+\\d))((?:[^\\[\\]]|((??)++\\]))*+)(\\](?!((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))[\\[\\];=]))", "end": "(?<=[;}])|(?=(?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:(?:\\s)+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:(?:\\s)+)?)*)(?:(?:\\s)+)?(~?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:(?:\\s)+)?(\\()", + "begin": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\s+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:\\s+)?)*)(?:\\s+)?(~?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:\\s+)?(\\()", "end": "\\)|(?=(?|->\\*))(?:(?:\\s)+)?(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?\\*|->)))", + "match": "(?<=(?:\\.\\*|\\.|->|->\\*))(?:\\s+)?(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ @@ -4871,7 +4825,7 @@ } }, { - "match": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?\\*|->)))", + "match": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ @@ -4958,11 +4912,14 @@ }, { "include": "#string_context" + }, + { + "include": "#ever_present_context" } ] }, { - "match": "(using)(?:\\s)+((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)(?:(?:\\s)+)?((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)(?:\\s+)?((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)(operator)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)(?:(?:((?:(?:delete\\[\\])|(?:delete)|(?:new\\[\\])|(?:<=>)|(?:<<=)|(?:new)|(?:>>=)|(?:\\->\\*)|(?:\\/=)|(?:%=)|(?:&=)|(?:>=)|(?:\\|=)|(?:\\+\\+)|(?:\\-\\-)|(?:\\(\\))|(?:\\[\\])|(?:\\->)|(?:\\+\\+)|(?:<<)|(?:>>)|(?:\\-\\-)|(?:<=)|(?:\\^=)|(?:==)|(?:!=)|(?:&&)|(?:\\|\\|)|(?:\\+=)|(?:\\-=)|(?:\\*=)|,|(?:\\+)|(?:\\-)|!|~|(?:\\*)|&|(?:\\*)|(?:\\/)|%|(?:\\+)|(?:\\-)|<|>|&|(?:\\^)|(?:\\|)|=))|((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(operator)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(?:(?:((?:(?:delete\\[\\])|(?:delete)|(?:new\\[\\])|(?:<=>)|(?:<<=)|(?:new)|(?:>>=)|(?:\\->\\*)|(?:\\/=)|(?:%=)|(?:&=)|(?:>=)|(?:\\|=)|(?:\\+\\+)|(?:\\-\\-)|(?:\\(\\))|(?:\\[\\])|(?:\\->)|(?:\\+\\+)|(?:<<)|(?:>>)|(?:\\-\\-)|(?:<=)|(?:\\^=)|(?:==)|(?:!=)|(?:&&)|(?:\\|\\|)|(?:\\+=)|(?:\\-=)|(?:\\*=)|,|\\+|\\-|!|~|\\*|&|\\*|\\/|%|\\+|\\-|<|>|&|\\^|\\||=))|((?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?=(?|(?=(?|(?=(?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(\\()(\\*)(?:(?:\\s)+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:(?:\\s)+)?(?:(\\[)(\\w*)(\\])(?:(?:\\s)+)?)*(\\))(?:(?:\\s)+)?(\\()", - "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?=[{=,);>]|\\n)(?!\\()|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", + "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()|(?=(?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))|(?=(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)?((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)?((?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", + "begin": "((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.class.cpp" @@ -634,7 +640,7 @@ "11": { "patterns": [ { - "match": "((?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { @@ -1395,41 +1401,25 @@ "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - "14": { "name": "storage.type.modifier.calling-convention.cpp" }, - "15": { + "11": { "patterns": [ { "include": "#inline_comment" } ] }, - "16": { + "12": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "17": { + "13": { "name": "comment.block.cpp" }, - "18": { + "14": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, - "19": { + "15": { "name": "entity.name.function.constructor.cpp entity.name.function.definition.special.constructor.cpp" } }, @@ -1451,7 +1441,7 @@ "include": "#ever_present_context" }, { - "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(default)|(delete))", + "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cpp" @@ -1494,7 +1484,7 @@ "endCaptures": {}, "patterns": [ { - "begin": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(\\()", + "begin": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)", "beginCaptures": { "1": { @@ -1628,48 +1618,32 @@ ] }, "constructor_root": { - "begin": "\\s*+((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)(((?>(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(((?>(?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.constructor.cpp" }, "1": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "2": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "3": { - "name": "comment.block.cpp" - }, - "4": { - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - "5": { "name": "storage.type.modifier.calling-convention.cpp" }, - "6": { + "2": { "patterns": [ { "include": "#inline_comment" } ] }, - "7": { + "3": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "8": { + "4": { "name": "comment.block.cpp" }, - "9": { + "5": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, - "10": { + "6": { "patterns": [ { "match": "::", @@ -1684,15 +1658,15 @@ } ] }, - "11": { + "7": { "patterns": [ { "include": "#template_call_range" } ] }, - "12": {}, - "13": { + "8": {}, + "9": { "patterns": [ { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?=:)", @@ -1708,7 +1682,23 @@ } ] }, - "14": {}, + "10": {}, + "11": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "12": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "13": { + "name": "comment.block.cpp" + }, + "14": { + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, "15": { "patterns": [ { @@ -1740,22 +1730,6 @@ }, "22": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - "23": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "24": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "25": { - "name": "comment.block.cpp" - }, - "26": { - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" } }, "endCaptures": {}, @@ -1776,7 +1750,7 @@ "include": "#ever_present_context" }, { - "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(default)|(delete))", + "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cpp" @@ -1819,7 +1793,7 @@ "endCaptures": {}, "patterns": [ { - "begin": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(\\()", + "begin": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)", "beginCaptures": { "1": { @@ -1953,7 +1927,7 @@ ] }, "control_flow_keywords": { - "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(\\{)", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\{)", "end": "\\}", "beginCaptures": { "1": { @@ -2226,7 +2206,7 @@ ] }, "d9bc4796b0b_module_import": { - "match": "^((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((import))(?:(?:\\s)+)?(?:(?:(?:((<)[^>]*(>?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=\\/\\/)))|((\\\")[^\\\"]*((?:\\\")?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=\\/\\/))))|(((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\.(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)*((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=(?:\\/\\/|;)))))|((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=(?:\\/\\/|;))))(?:(?:\\s)+)?(;?)", + "match": "^((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((import))(?:\\s+)?(?:(?:(?:((<)[^>]*(>?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=\\/\\/)))|((\\\")[^\\\"]*(\\\"?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=\\/\\/))))|(((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\.(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)*((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=(?:\\/\\/|;)))))|((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=(?:\\/\\/|;))))(?:\\s+)?(;?)", "captures": { "1": { "patterns": [ @@ -2420,7 +2400,7 @@ "endCaptures": {}, "patterns": [ { - "match": "(\\G0[xX])([0-9a-fA-F](?:[0-9a-fA-F]|((?<=[0-9a-fA-F])'(?=[0-9a-fA-F])))*)?((?:(?<=[0-9a-fA-F])\\.|\\.(?=[0-9a-fA-F])))([0-9a-fA-F](?:[0-9a-fA-F]|((?<=[0-9a-fA-F])'(?=[0-9a-fA-F])))*)?(?:(?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { @@ -2801,64 +2781,48 @@ "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "7": { - "name": "comment.block.cpp" - }, - "8": { - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - "9": { "name": "storage.type.modifier.calling-convention.cpp" }, - "10": { + "6": { "patterns": [ { "include": "#inline_comment" } ] }, - "11": { + "7": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "12": { + "8": { "name": "comment.block.cpp" }, - "13": { + "9": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, - "14": { + "10": { "patterns": [ { "include": "#functional_specifiers_pre_parameters" } ] }, - "15": { + "11": { "patterns": [ { "include": "#inline_comment" } ] }, - "16": { + "12": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "17": { + "13": { "name": "comment.block.cpp" }, - "18": { + "14": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, - "19": { + "15": { "name": "entity.name.function.destructor.cpp entity.name.function.definition.special.member.destructor.cpp" } }, @@ -2880,7 +2844,7 @@ "include": "#ever_present_context" }, { - "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(default)|(delete))", + "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cpp" @@ -2964,7 +2928,7 @@ ] }, "destructor_root": { - "begin": "((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)(((?>(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(((?>(?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { @@ -3112,7 +3076,7 @@ "include": "#ever_present_context" }, { - "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(default)|(delete))", + "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cpp" @@ -3196,7 +3160,7 @@ ] }, "diagnostic": { - "begin": "(^((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?((?:error|warning)))\\b(?:(?:\\s)+)?", + "begin": "(^((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(#)(?:\\s+)?((?:error|warning)))\\b(?:\\s+)?", "end": "(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::))?(?:(?:\\s)+)?((?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", + "begin": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::))?(?:\\s+)?((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.enum.cpp" @@ -3463,7 +3427,7 @@ ] }, "enum_declare": { - "match": "((?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", + "begin": "((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(extern)(?=\\s*\\\")", + "end": "(?:(?:(?<=\\}|%>|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.extern.cpp" @@ -3992,7 +3956,7 @@ ] }, "function_call": { - "begin": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(\\()", + "begin": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(\\()", "end": "\\)", "beginCaptures": { "1": { @@ -4066,7 +4030,7 @@ ] }, "function_definition": { - "begin": "(?:(?:^|\\G|(?<=;|\\}))|(?<=>|\\*\\/))\\s*+(?:((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|\\*\\/))\\s*+(?:((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { @@ -4104,7 +4068,7 @@ "7": { "patterns": [ { - "match": "((?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", + "match": "(?<=^|\\))(?:\\s+)?(->)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", "captures": { "1": { "name": "punctuation.definition.function.return-type.cpp" @@ -4696,8 +4644,8 @@ ] }, "function_pointer": { - "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(\\()(\\*)(?:(?:\\s)+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:(?:\\s)+)?(?:(\\[)(\\w*)(\\])(?:(?:\\s)+)?)*(\\))(?:(?:\\s)+)?(\\()", - "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?=[{=,);>]|\\n)(?!\\()", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", + "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", @@ -4843,7 +4791,7 @@ "name": "storage.modifier.pointer.cpp" }, { - "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))){2,}\\&", + "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))){2,}\\&", "captures": { "1": { "patterns": [ @@ -4975,8 +4923,8 @@ ] }, "function_pointer_parameter": { - "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(\\()(\\*)(?:(?:\\s)+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:(?:\\s)+)?(?:(\\[)(\\w*)(\\])(?:(?:\\s)+)?)*(\\))(?:(?:\\s)+)?(\\()", - "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?=[{=,);>]|\\n)(?!\\()", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", + "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", @@ -5122,7 +5070,7 @@ "name": "storage.modifier.pointer.cpp" }, { - "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))){2,}\\&", + "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))){2,}\\&", "captures": { "1": { "patterns": [ @@ -5286,11 +5234,14 @@ }, { "include": "#string_context" + }, + { + "include": "#ever_present_context" } ] }, { - "match": "(using)(?:\\s)+((?]*(>?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=\\/\\/)))|((\\\")[^\\\"]*((?:\\\")?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=\\/\\/))))|(((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\.(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)*((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=(?:\\/\\/|;)))))|((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:\\n)|$)|(?=(?:\\/\\/|;))))", + "match": "^((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((#)(?:\\s+)?((?:include|include_next))\\b)(?:\\s+)?(?:(?:(?:((<)[^>]*(>?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=\\/\\/)))|((\\\")[^\\\"]*(\\\"?)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=\\/\\/))))|(((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\.(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)*((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=(?:\\/\\/|;)))))|((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:\\n|$)|(?=(?:\\/\\/|;))))", "captures": { "1": { "patterns": [ @@ -5586,7 +5540,7 @@ "name": "storage.type.modifier.virtual.cpp" }, { - "match": "(?<=protected|virtual|private|public|,|:)(?:(?:\\s)+)?(?!(?:(?:(?:protected)|(?:private)|(?:public))|virtual))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", + "match": "(?<=protected|virtual|private|public|,|:)(?:\\s+)?(?!(?:(?:(?:protected)|(?:private)|(?:public))|virtual))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", "captures": { "1": { "name": "meta.qualified_type.cpp", @@ -5757,7 +5711,7 @@ ] }, "inline_builtin_storage_type": { - "match": "(?:\\s)*+(?])|(?<=\\Wreturn|^return))(?:(?:\\s)+)?(\\[(?!\\[| *+\"| *+\\d))((?:[^\\[\\]]|((??)++\\]))*+)(\\](?!((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))[\\[\\];]))", + "begin": "(?:(?<=[^\\s]|^)(?])|(?<=\\Wreturn|^return))(?:\\s+)?(\\[(?!\\[| *+\"| *+\\d))((?:[^\\[\\]]|((??)++\\]))*+)(\\](?!((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))[\\[\\];=]))", "end": "(?<=[;}])", "beginCaptures": { "1": { @@ -5866,7 +5820,7 @@ "include": "#the_this_keyword" }, { - "match": "((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?=\\]|\\z|$)|(,))|(\\=))", + "match": "((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?=\\]|\\z|$)|(,))|(\\=))", "captures": { "1": { "name": "variable.parameter.capture.cpp" @@ -5993,7 +5947,7 @@ "name": "constant.language.$0.cpp" }, "line": { - "begin": "^((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?line\\b", + "begin": "^((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(#)(?:\\s+)?line\\b", "end": "(?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:(?:\\s)+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:(?:\\s)+)?)*)(?:(?:\\s)+)?(\\b(?!uint_least32_t[^\\w]|uint_least16_t[^\\w]|uint_least64_t[^\\w]|int_least32_t[^\\w]|int_least64_t[^\\w]|uint_fast32_t[^\\w]|uint_fast64_t[^\\w]|uint_least8_t[^\\w]|uint_fast16_t[^\\w]|int_least16_t[^\\w]|int_fast16_t[^\\w]|int_least8_t[^\\w]|uint_fast8_t[^\\w]|int_fast64_t[^\\w]|int_fast32_t[^\\w]|int_fast8_t[^\\w]|suseconds_t[^\\w]|useconds_t[^\\w]|in_addr_t[^\\w]|uintmax_t[^\\w]|uintmax_t[^\\w]|uintmax_t[^\\w]|in_port_t[^\\w]|uintptr_t[^\\w]|blksize_t[^\\w]|uint32_t[^\\w]|uint64_t[^\\w]|u_quad_t[^\\w]|intmax_t[^\\w]|intmax_t[^\\w]|unsigned[^\\w]|blkcnt_t[^\\w]|uint16_t[^\\w]|intptr_t[^\\w]|swblk_t[^\\w]|wchar_t[^\\w]|u_short[^\\w]|qaddr_t[^\\w]|caddr_t[^\\w]|daddr_t[^\\w]|fixpt_t[^\\w]|nlink_t[^\\w]|segsz_t[^\\w]|clock_t[^\\w]|ssize_t[^\\w]|int16_t[^\\w]|int32_t[^\\w]|int64_t[^\\w]|uint8_t[^\\w]|int8_t[^\\w]|mode_t[^\\w]|quad_t[^\\w]|ushort[^\\w]|u_long[^\\w]|u_char[^\\w]|double[^\\w]|signed[^\\w]|time_t[^\\w]|size_t[^\\w]|key_t[^\\w]|div_t[^\\w]|ino_t[^\\w]|uid_t[^\\w]|gid_t[^\\w]|off_t[^\\w]|pid_t[^\\w]|float[^\\w]|dev_t[^\\w]|u_int[^\\w]|short[^\\w]|bool[^\\w]|id_t[^\\w]|uint[^\\w]|long[^\\w]|char[^\\w]|void[^\\w]|auto[^\\w]|id_t[^\\w]|int[^\\w])(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b(?!\\())", + "match": "(?:((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\s+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:\\s+)?)*)(?:\\s+)?(\\b(?!uint_least32_t[^\\w]|uint_least16_t[^\\w]|uint_least64_t[^\\w]|int_least32_t[^\\w]|int_least64_t[^\\w]|uint_fast32_t[^\\w]|uint_fast64_t[^\\w]|uint_least8_t[^\\w]|uint_fast16_t[^\\w]|int_least16_t[^\\w]|int_fast16_t[^\\w]|int_least8_t[^\\w]|uint_fast8_t[^\\w]|int_fast64_t[^\\w]|int_fast32_t[^\\w]|int_fast8_t[^\\w]|suseconds_t[^\\w]|useconds_t[^\\w]|in_addr_t[^\\w]|uintmax_t[^\\w]|uintmax_t[^\\w]|uintmax_t[^\\w]|in_port_t[^\\w]|uintptr_t[^\\w]|blksize_t[^\\w]|uint32_t[^\\w]|uint64_t[^\\w]|u_quad_t[^\\w]|intmax_t[^\\w]|intmax_t[^\\w]|unsigned[^\\w]|blkcnt_t[^\\w]|uint16_t[^\\w]|intptr_t[^\\w]|swblk_t[^\\w]|wchar_t[^\\w]|u_short[^\\w]|qaddr_t[^\\w]|caddr_t[^\\w]|daddr_t[^\\w]|fixpt_t[^\\w]|nlink_t[^\\w]|segsz_t[^\\w]|clock_t[^\\w]|ssize_t[^\\w]|int16_t[^\\w]|int32_t[^\\w]|int64_t[^\\w]|uint8_t[^\\w]|int8_t[^\\w]|mode_t[^\\w]|quad_t[^\\w]|ushort[^\\w]|u_long[^\\w]|u_char[^\\w]|double[^\\w]|signed[^\\w]|time_t[^\\w]|size_t[^\\w]|key_t[^\\w]|div_t[^\\w]|ino_t[^\\w]|uid_t[^\\w]|gid_t[^\\w]|off_t[^\\w]|pid_t[^\\w]|float[^\\w]|dev_t[^\\w]|u_int[^\\w]|short[^\\w]|bool[^\\w]|id_t[^\\w]|uint[^\\w]|long[^\\w]|char[^\\w]|void[^\\w]|auto[^\\w]|id_t[^\\w]|int[^\\w])(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b(?!\\())", "captures": { "1": { "patterns": [ @@ -6184,7 +6138,7 @@ "7": { "patterns": [ { - "match": "(?<=(?:\\.\\*|\\.|->|->\\*))(?:(?:\\s)+)?(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?\\*|->)))", + "match": "(?<=(?:\\.\\*|\\.|->|->\\*))(?:\\s+)?(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ @@ -6217,7 +6171,7 @@ } }, { - "match": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?\\*|->)))", + "match": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ @@ -6263,7 +6217,7 @@ } }, "memory_operators": { - "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:(?:(delete)(?:(?:\\s)+)?(\\[\\])|(delete))|(new))(?!\\w))", + "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:(?:(delete)(?:\\s+)?(\\[\\])|(delete))|(new))(?!\\w))", "captures": { "1": { "patterns": [ @@ -6308,7 +6262,7 @@ } }, "method_access": { - "begin": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:(?:\\s)+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:(?:\\s)+)?)*)(?:(?:\\s)+)?(~?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:(?:\\s)+)?(\\()", + "begin": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\s+)?(?:(?:\\.\\*|\\.)|(?:->\\*|->))(?:\\s+)?)*)(?:\\s+)?(~?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:\\s+)?(\\()", "end": "\\)", "beginCaptures": { "1": { @@ -6342,7 +6296,7 @@ "9": { "patterns": [ { - "match": "(?<=(?:\\.\\*|\\.|->|->\\*))(?:(?:\\s)+)?(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?\\*|->)))", + "match": "(?<=(?:\\.\\*|\\.|->|->\\*))(?:\\s+)?(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ @@ -6375,7 +6329,7 @@ } }, { - "match": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?\\*|->)))", + "match": "(?:((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?\\*|->)))", "captures": { "1": { "patterns": [ @@ -6434,7 +6388,7 @@ ] }, "misc_keywords": { - "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)(?:(?:\\s)+)?((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)(?:\\s+)?((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)(?:(?:\\s)+)?((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)(?:\\s+)?((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)(operator)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)(?:(?:((?:(?:delete\\[\\])|(?:delete)|(?:new\\[\\])|(?:<=>)|(?:<<=)|(?:new)|(?:>>=)|(?:\\->\\*)|(?:\\/=)|(?:%=)|(?:&=)|(?:>=)|(?:\\|=)|(?:\\+\\+)|(?:\\-\\-)|(?:\\(\\))|(?:\\[\\])|(?:\\->)|(?:\\+\\+)|(?:<<)|(?:>>)|(?:\\-\\-)|(?:<=)|(?:\\^=)|(?:==)|(?:!=)|(?:&&)|(?:\\|\\|)|(?:\\+=)|(?:\\-=)|(?:\\*=)|,|(?:\\+)|(?:\\-)|!|~|(?:\\*)|&|(?:\\*)|(?:\\/)|%|(?:\\+)|(?:\\-)|<|>|&|(?:\\^)|(?:\\|)|=))|((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(operator)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)(?:(?:((?:(?:delete\\[\\])|(?:delete)|(?:new\\[\\])|(?:<=>)|(?:<<=)|(?:new)|(?:>>=)|(?:\\->\\*)|(?:\\/=)|(?:%=)|(?:&=)|(?:>=)|(?:\\|=)|(?:\\+\\+)|(?:\\-\\-)|(?:\\(\\))|(?:\\[\\])|(?:\\->)|(?:\\+\\+)|(?:<<)|(?:>>)|(?:\\-\\-)|(?:<=)|(?:\\^=)|(?:==)|(?:!=)|(?:&&)|(?:\\|\\|)|(?:\\+=)|(?:\\-=)|(?:\\*=)|,|\\+|\\-|!|~|\\*|&|\\*|\\/|%|\\+|\\-|<|>|&|\\^|\\||=))|((?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.function.definition.special.operator-overload.cpp" }, "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + "5": { "name": "meta.qualified_type.cpp", "patterns": [ { @@ -7040,7 +7016,7 @@ } ] }, - "2": { + "6": { "patterns": [ { "include": "#attributes_context" @@ -7050,22 +7026,6 @@ } ] }, - "3": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "4": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "5": { - "name": "comment.block.cpp" - }, - "6": { - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, "7": { "patterns": [ { @@ -7083,6 +7043,22 @@ "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, "11": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "12": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "13": { + "name": "comment.block.cpp" + }, + "14": { + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + "15": { "patterns": [ { "match": "::", @@ -7097,39 +7073,39 @@ } ] }, - "12": { + "16": { "patterns": [ { "include": "#template_call_range" } ] }, - "13": {}, - "14": { + "17": {}, + "18": { "patterns": [ { "include": "#inline_comment" } ] }, - "15": { + "19": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "16": { + "20": { "name": "comment.block.cpp" }, - "17": { + "21": { "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, - "18": {}, - "19": { + "22": {}, + "23": { "patterns": [ { "match": "\\*", "name": "storage.modifier.pointer.cpp" }, { - "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))){2,}\\&", + "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))){2,}\\&", "captures": { "1": { "patterns": [ @@ -7156,22 +7132,6 @@ } ] }, - "20": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "21": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "22": { - "name": "comment.block.cpp" - }, - "23": { - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, "24": { "patterns": [ { @@ -7333,7 +7293,7 @@ "name": "entity.name.operator.type.pointer.cpp" }, { - "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))){2,}\\&", + "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))){2,}\\&", "captures": { "1": { "patterns": [ @@ -7497,7 +7457,7 @@ "include": "#qualifiers_and_specifiers_post_parameters" }, { - "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(default)|(delete))", + "match": "(\\=)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(default)|(delete))", "captures": { "1": { "name": "keyword.operator.assignment.cpp" @@ -7564,7 +7524,7 @@ "operators": { "patterns": [ { - "begin": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.])", + "match": "\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.])", "captures": { "0": { "patterns": [ @@ -10897,12 +10863,12 @@ "name": "meta.qualified_type.cpp" }, "qualifiers_and_specifiers_post_parameters": { - "match": "((?:(?:(?:(?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+", + "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -10952,7 +10918,7 @@ } }, "scope_resolution_function_call": { - "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+", + "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -10974,7 +10940,7 @@ } }, "scope_resolution_function_call_inner_generated": { - "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::)", + "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ @@ -11021,7 +10987,7 @@ } }, "scope_resolution_function_definition": { - "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+", + "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11043,7 +11009,7 @@ } }, "scope_resolution_function_definition_inner_generated": { - "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::)", + "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ @@ -11090,7 +11056,7 @@ } }, "scope_resolution_function_definition_operator_overload": { - "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+", + "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11112,7 +11078,7 @@ } }, "scope_resolution_function_definition_operator_overload_inner_generated": { - "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::)", + "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ @@ -11159,7 +11125,7 @@ } }, "scope_resolution_inner_generated": { - "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::)", + "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ @@ -11206,7 +11172,7 @@ } }, "scope_resolution_namespace_alias": { - "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+", + "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11228,7 +11194,7 @@ } }, "scope_resolution_namespace_alias_inner_generated": { - "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::)", + "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ @@ -11275,7 +11241,7 @@ } }, "scope_resolution_namespace_block": { - "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+", + "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11297,7 +11263,7 @@ } }, "scope_resolution_namespace_block_inner_generated": { - "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::)", + "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ @@ -11344,7 +11310,7 @@ } }, "scope_resolution_namespace_using": { - "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+", + "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11366,7 +11332,7 @@ } }, "scope_resolution_namespace_using_inner_generated": { - "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::)", + "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ @@ -11413,7 +11379,7 @@ } }, "scope_resolution_parameter": { - "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+", + "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11435,7 +11401,7 @@ } }, "scope_resolution_parameter_inner_generated": { - "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::)", + "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ @@ -11482,7 +11448,7 @@ } }, "scope_resolution_template_call": { - "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+", + "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11504,7 +11470,7 @@ } }, "scope_resolution_template_call_inner_generated": { - "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::)", + "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ @@ -11551,7 +11517,7 @@ } }, "scope_resolution_template_definition": { - "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+", + "match": "(::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11573,7 +11539,7 @@ } }, "scope_resolution_template_definition_inner_generated": { - "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?(::)", + "match": "((::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)((?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?(::)", "captures": { "1": { "patterns": [ @@ -11624,7 +11590,7 @@ "name": "punctuation.terminator.statement.cpp" }, "simple_type": { - "match": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?", + "match": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?", "captures": { "1": { "name": "meta.qualified_type.cpp", @@ -11797,7 +11763,7 @@ "name": "storage.modifier.pointer.cpp" }, { - "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))){2,}\\&", + "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))){2,}\\&", "captures": { "1": { "patterns": [ @@ -11877,7 +11843,7 @@ } }, "single_line_macro": { - "match": "^((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))#define.*(?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", + "begin": "((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.struct.cpp" @@ -13131,7 +13097,7 @@ "11": { "patterns": [ { - "match": "((?|\\?\\?>)|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { @@ -13612,7 +13578,7 @@ ] }, "template_argument_defaulted": { - "match": "(?<=<|,)(?:(?:\\s)+)?((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:\\s)+((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:(?:\\s)+)?(\\=)", + "match": "(?<=<|,)(?:\\s+)?((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s+((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(\\=)", "captures": { "1": { "name": "storage.type.template.argument.$1.cpp" @@ -13660,7 +13626,7 @@ ] }, "template_call_innards": { - "match": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+", + "match": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+", "captures": { "0": { "patterns": [ @@ -13702,7 +13668,7 @@ ] }, "template_definition": { - "begin": "(?", "beginCaptures": { "1": { @@ -13720,7 +13686,7 @@ "name": "meta.template.definition.cpp", "patterns": [ { - "begin": "(?<=\\w)(?:(?:\\s)+)?<", + "begin": "(?<=\\w)(?:\\s+)?<", "end": ">", "beginCaptures": { "0": { @@ -13744,7 +13710,7 @@ ] }, "template_definition_argument": { - "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?:(?:(?:((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)|((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?:\\s)+)+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))|((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:(?:\\s)+)?(\\.\\.\\.)(?:(?:\\s)+)?((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))|(?)(?:(?:\\s)+)?(class|typename)(?:(?:\\s)+((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))?)(?:(?:\\s)+)?(?:(\\=)(?:(?:\\s)+)?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?(?:(,)|(?=>|$))", + "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)|((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s+)+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))|((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:\\s+)?(\\.\\.\\.)(?:\\s+)?((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))|(?)(?:\\s+)?(class|typename)(?:\\s+((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))?)(?:\\s+)?(?:(\\=)(?:\\s+)?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?(?:(,)|(?=>|$))", "captures": { "1": { "patterns": [ @@ -13843,7 +13809,7 @@ ] }, "template_explicit_instantiation": { - "match": "(?)(?:(?:\\s)+)?$", + "match": "(?)(?:\\s+)?$", "captures": { "1": { "name": "storage.type.template.cpp" @@ -13972,7 +13938,7 @@ "applyEndPatternLast": 1 }, "the_this_keyword": { - "match": "((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))|(.*(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))|(.*(?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", + "begin": "((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.class.cpp" @@ -14450,7 +14416,7 @@ "11": { "patterns": [ { - "match": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))?(?:(?:&|(?:\\*))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))*(?:&|(?:\\*)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(\\()(\\*)(?:(?:\\s)+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:(?:\\s)+)?(?:(\\[)(\\w*)(\\])(?:(?:\\s)+)?)*(\\))(?:(?:\\s)+)?(\\()", - "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(?=[{=,);>]|\\n)(?!\\()", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\s*\\(\\s*\\(.*?\\)\\s*\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?:(?:(?:(?:unsigned)|(?:signed)|(?:short)|(?:long))|(?:(?:struct)|(?:class)|(?:union)|(?:enum)))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:((?:::)?(?:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|thread_local|dynamic_cast|synchronized|static_cast|const_cast|consteval|co_return|protected|constinit|constexpr|co_return|consteval|namespace|constexpr|constexpr|co_await|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|template|continue|co_await|co_yield|volatile|register|restrict|reflexpr|mutable|alignof|include|private|defined|typedef|_Pragma|__asm__|concept|mutable|warning|default|virtual|alignas|public|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|struct|static|extern|inline|friend|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|compl|while|ifdef|const|bitor|union|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|not|try|for|asm|and|xor|new|do|if|or|if)\\b)(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))(((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))?(?:(?:&|\\*)((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))*(?:&|\\*))?((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(\\()(\\*)(?:\\s+)?((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)(?:\\s+)?(?:(\\[)(\\w*)(\\])(?:\\s+)?)*(\\))(?:\\s+)?(\\()", + "end": "(\\))((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?=[{=,);>]|\\n)(?!\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", @@ -14886,7 +14852,7 @@ "name": "storage.modifier.pointer.cpp" }, { - "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))){2,}\\&", + "match": "(?:\\&((?:(?:(?:\\s*+(\\/\\*)((?:[^\\*]++|\\*+(?!\\/))*+(\\*\\/))\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))){2,}\\&", "captures": { "1": { "patterns": [ @@ -15020,7 +14986,7 @@ ] }, "typedef_struct": { - "begin": "((?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", + "begin": "((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.struct.cpp" @@ -15084,7 +15050,7 @@ "11": { "patterns": [ { - "match": "((?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", + "begin": "((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.union.cpp" @@ -15427,7 +15393,7 @@ "11": { "patterns": [ { - "match": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z))))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", + "match": "(((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z))(?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*+)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|\\A|\\Z)))?(?!(?:(?:transaction_safe_dynamic)|(?:__has_cpp_attribute)|(?:reinterpret_cast)|(?:transaction_safe)|(?:atomic_noexcept)|(?:atomic_commit)|(?:__has_include)|(?:atomic_cancel)|(?:synchronized)|(?:thread_local)|(?:dynamic_cast)|(?:static_cast)|(?:const_cast)|(?:constexpr)|(?:co_return)|(?:constinit)|(?:namespace)|(?:protected)|(?:consteval)|(?:constexpr)|(?:constexpr)|(?:co_return)|(?:consteval)|(?:co_await)|(?:continue)|(?:template)|(?:reflexpr)|(?:volatile)|(?:register)|(?:co_await)|(?:co_yield)|(?:restrict)|(?:noexcept)|(?:volatile)|(?:override)|(?:explicit)|(?:decltype)|(?:operator)|(?:noexcept)|(?:noexcept)|(?:typename)|(?:requires)|(?:co_yield)|(?:nullptr)|(?:alignof)|(?:alignas)|(?:default)|(?:mutable)|(?:virtual)|(?:mutable)|(?:private)|(?:include)|(?:warning)|(?:_Pragma)|(?:defined)|(?:typedef)|(?:__asm__)|(?:concept)|(?:define)|(?:module)|(?:sizeof)|(?:switch)|(?:delete)|(?:pragma)|(?:and_eq)|(?:inline)|(?:xor_eq)|(?:typeid)|(?:import)|(?:extern)|(?:public)|(?:bitand)|(?:static)|(?:export)|(?:return)|(?:friend)|(?:ifndef)|(?:not_eq)|(?:false)|(?:final)|(?:break)|(?:const)|(?:catch)|(?:endif)|(?:ifdef)|(?:undef)|(?:error)|(?:audit)|(?:while)|(?:using)|(?:axiom)|(?:or_eq)|(?:compl)|(?:throw)|(?:bitor)|(?:const)|(?:line)|(?:case)|(?:else)|(?:this)|(?:true)|(?:goto)|(?:else)|(?:NULL)|(?:elif)|(?:new)|(?:asm)|(?:xor)|(?:and)|(?:try)|(?:not)|(?:for)|(?:do)|(?:if)|(?:or)|(?:if))\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)?(?![\\w<:.]))", "captures": { "1": { "name": "storage.modifier.cpp" @@ -15967,7 +15933,7 @@ } }, "undef": { - "match": "(^((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))(#)(?:(?:\\s)+)?undef\\b)((?:((?:\\s*+\\/\\*(?:[^\\*]++|\\*+(?!\\/))*+\\*\\/\\s*+)+)|(?:\\s++)|(?<=\\W)|(?=\\W)|^|(?:\\n?$)|(?:\\A)|(?:\\Z)))((?|\\?\\?>)(?:(?:\\s)+)?(;)|(;))|(?=[;>\\[\\]=]))", + "begin": "((?|\\?\\?>)(?:\\s+)?(;)|(;))|(?=[;>\\[\\]=]))", "beginCaptures": { "0": { "name": "meta.head.union.cpp" @@ -16086,7 +16052,7 @@ "11": { "patterns": [ { - "match": "((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)(?:\\s)*+)?::)*\\s*+)?((?|(?:(?:[^'\"<>\\/]|\\/[^*])++))*>)\\s*+)?::)*\\s*+)?((??]|,\\s*|\\s+extends\\s+)+>)?[!?]?(\\(|\\s+=>)", + "match": "([_$]*[a-z][a-zA-Z0-9_$]*)(<(?:[a-zA-Z0-9_$<>?]|,\\s*|\\s+extends\\s+)+>)?[!?]?\\(", "captures": { "1": { "name": "entity.name.function.dart" @@ -313,7 +313,7 @@ }, { "name": "keyword.control.dart", - "match": "(? s.toLowerCase()); @@ -36,6 +37,7 @@ const implicitActivationEvent = l10n.t("This activation event cannot be explicit const redundantImplicitActivationEvent = l10n.t("This activation event can be removed as VS Code generates these automatically from your package.json contribution declarations."); const bumpEngineForImplicitActivationEvents = l10n.t("This activation event can be removed for extensions targeting engine version ^1.75 as VS Code will generate these automatically from your package.json contribution declarations."); const starActivation = l10n.t("Using '*' activation is usually a bad idea as it impacts performance."); +const parsingErrorHeader = l10n.t("Error parsing the when-clause:"); enum Context { ICON, @@ -110,15 +112,17 @@ export class ExtensionLinter { } private async lint() { - this.lintPackageJson(); - await this.lintReadme(); + await Promise.all([ + this.lintPackageJson(), + this.lintReadme() + ]); } - private lintPackageJson() { - this.packageJsonQ.forEach(document => { + private async lintPackageJson() { + for (const document of Array.from(this.packageJsonQ)) { this.packageJsonQ.delete(document); if (document.isClosed) { - return; + continue; } const diagnostics: Diagnostic[] = []; @@ -190,16 +194,88 @@ export class ExtensionLinter { } } } + + const whenClauseLinting = await this.lintWhenClauses(findNodeAtLocation(tree, ['contributes']), document); + diagnostics.push(...whenClauseLinting); } this.diagnosticsCollection.set(document.uri, diagnostics); - }); + } + } + + /** lints `when` and `enablement` clauses */ + private async lintWhenClauses(contributesNode: JsonNode | undefined, document: TextDocument): Promise { + if (!contributesNode) { + return []; + } + + const whenClauses: JsonNode[] = []; + + function findWhens(node: JsonNode | undefined, clauseName: string) { + if (node) { + switch (node.type) { + case 'property': + if (node.children && node.children.length === 2) { + const key = node.children[0]; + const value = node.children[1]; + switch (value.type) { + case 'string': + if (key.value === clauseName && typeof value.value === 'string' /* careful: `.value` MUST be a string 1) because a when/enablement clause is string; so also, type cast to string below is safe */) { + whenClauses.push(value); + } + case 'object': + case 'array': + findWhens(value, clauseName); + } + } + break; + case 'object': + case 'array': + if (node.children) { + node.children.forEach(n => findWhens(n, clauseName)); + } + } + } + } + + [ + findNodeAtLocation(contributesNode, ['menus']), + findNodeAtLocation(contributesNode, ['views']), + findNodeAtLocation(contributesNode, ['viewsWelcome']), + findNodeAtLocation(contributesNode, ['keybindings']), + ].forEach(n => findWhens(n, 'when')); + + findWhens(findNodeAtLocation(contributesNode, ['commands']), 'enablement'); + + const parseResults = await commands.executeCommand<{ errorMessage: string; offset: number; length: number }[][]>('_validateWhenClauses', whenClauses.map(w => w.value as string /* we make sure to capture only if `w.value` is string above */)); + + const diagnostics: Diagnostic[] = []; + for (let i = 0; i < parseResults.length; ++i) { + const whenClauseJSONNode = whenClauses[i]; + + const jsonStringScanner = new JsonStringScanner(document.getText(), whenClauseJSONNode.offset + 1); + + for (const error of parseResults[i]) { + const realOffset = jsonStringScanner.getOffsetInEncoded(error.offset); + const realOffsetEnd = jsonStringScanner.getOffsetInEncoded(error.offset + error.length); + const start = document.positionAt(realOffset /* +1 to account for the quote (I think) */); + const end = document.positionAt(realOffsetEnd); + const errMsg = `${parsingErrorHeader}\n\n${error.errorMessage}`; + const diagnostic = new Diagnostic(new Range(start, end), errMsg, DiagnosticSeverity.Error); + diagnostic.code = { + value: 'See docs', + target: Uri.parse('https://code.visualstudio.com/api/references/when-clause-contexts'), + }; + diagnostics.push(diagnostic); + } + } + return diagnostics; } private async lintReadme() { - for (const document of Array.from(this.readmeQ)) { + for (const document of this.readmeQ) { this.readmeQ.delete(document); if (document.isClosed) { - return; + continue; } const folder = this.getUriFolder(document.uri); @@ -346,8 +422,8 @@ export class ExtensionLinter { } const file = folder.with({ path: path.posix.join(folder.path, 'package.json') }); try { - const document = await workspace.openTextDocument(file); - return parseTree(document.getText()); + const fileContents = await workspace.fs.readFile(file); // #174888 + return parseTree(Buffer.from(fileContents).toString('utf-8')); } catch (err) { return undefined; } diff --git a/extensions/extension-editing/src/jsonReconstruct.ts b/extensions/extension-editing/src/jsonReconstruct.ts new file mode 100644 index 00000000000..41e2971ba3b --- /dev/null +++ b/extensions/extension-editing/src/jsonReconstruct.ts @@ -0,0 +1,183 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * This class has a very specific purpose: + * + * It can return convert offset within a decoded JSON string to offset within the encoded JSON string. + */ +export class JsonStringScanner { + private resultChars = 0; + private pos = 0; + + /** + * + * @param text the encoded JSON string + * @param pos must not include ", ie must be `stringJSONNode.offset + 1` + */ + constructor(private readonly text: string, initialPos: number /* offset within `text` */) { + this.pos = initialPos; + } + + // note that we don't do bound checks here, because we know that the offset is within the string + getOffsetInEncoded(offsetDecoded: number) { + + let start = this.pos; + + while (true) { + if (this.resultChars > offsetDecoded) { + return start; + } + + const ch = this.text.charCodeAt(this.pos); + + if (ch === CharacterCodes.backslash) { + start = this.pos; + this.pos++; + + const ch2 = this.text.charCodeAt(this.pos++); + switch (ch2) { + case CharacterCodes.doubleQuote: + case CharacterCodes.backslash: + case CharacterCodes.slash: + case CharacterCodes.b: + case CharacterCodes.f: + case CharacterCodes.n: + case CharacterCodes.r: + case CharacterCodes.t: + this.resultChars += 1; + break; + case CharacterCodes.u: { + const ch3 = this.scanHexDigits(4, true); + if (ch3 >= 0) { + this.resultChars += String.fromCharCode(ch3).length; + } + break; + } + } + continue; + } + start = this.pos; + this.pos++; + this.resultChars++; + } + } + + scanHexDigits(count: number, exact?: boolean): number { + let digits = 0; + let value = 0; + while (digits < count || !exact) { + const ch = this.text.charCodeAt(this.pos); + if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) { + value = value * 16 + ch - CharacterCodes._0; + } + else if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) { + value = value * 16 + ch - CharacterCodes.A + 10; + } + else if (ch >= CharacterCodes.a && ch <= CharacterCodes.f) { + value = value * 16 + ch - CharacterCodes.a + 10; + } + else { + break; + } + this.pos++; + digits++; + } + if (digits < count) { + value = -1; + } + return value; + } +} + + +const enum CharacterCodes { + lineFeed = 0x0A, // \n + carriageReturn = 0x0D, // \r + + space = 0x0020, // " " + + _0 = 0x30, + _1 = 0x31, + _2 = 0x32, + _3 = 0x33, + _4 = 0x34, + _5 = 0x35, + _6 = 0x36, + _7 = 0x37, + _8 = 0x38, + _9 = 0x39, + + a = 0x61, + b = 0x62, + c = 0x63, + d = 0x64, + e = 0x65, + f = 0x66, + g = 0x67, + h = 0x68, + i = 0x69, + j = 0x6A, + k = 0x6B, + l = 0x6C, + m = 0x6D, + n = 0x6E, + o = 0x6F, + p = 0x70, + q = 0x71, + r = 0x72, + s = 0x73, + t = 0x74, + u = 0x75, + v = 0x76, + w = 0x77, + x = 0x78, + y = 0x79, + z = 0x7A, + + A = 0x41, + B = 0x42, + C = 0x43, + D = 0x44, + E = 0x45, + F = 0x46, + G = 0x47, + H = 0x48, + I = 0x49, + J = 0x4A, + K = 0x4B, + L = 0x4C, + M = 0x4D, + N = 0x4E, + O = 0x4F, + P = 0x50, + Q = 0x51, + R = 0x52, + S = 0x53, + T = 0x54, + U = 0x55, + V = 0x56, + W = 0x57, + X = 0x58, + Y = 0x59, + Z = 0x5a, + + asterisk = 0x2A, // * + backslash = 0x5C, // \ + closeBrace = 0x7D, // } + closeBracket = 0x5D, // ] + colon = 0x3A, // : + comma = 0x2C, // , + dot = 0x2E, // . + doubleQuote = 0x22, // " + minus = 0x2D, // - + openBrace = 0x7B, // { + openBracket = 0x5B, // [ + plus = 0x2B, // + + slash = 0x2F, // / + + formFeed = 0x0C, // \f + tab = 0x09, // \t +} diff --git a/extensions/git-base/cgmanifest.json b/extensions/git-base/cgmanifest.json index e33513606ce..0815c34f882 100644 --- a/extensions/git-base/cgmanifest.json +++ b/extensions/git-base/cgmanifest.json @@ -71,4 +71,4 @@ } ], "version": 1 -} +} \ No newline at end of file diff --git a/extensions/git-base/src/remoteSource.ts b/extensions/git-base/src/remoteSource.ts index 38729dc6194..d7fb85c620f 100644 --- a/extensions/git-base/src/remoteSource.ts +++ b/extensions/git-base/src/remoteSource.ts @@ -85,7 +85,6 @@ export async function pickRemoteSource(model: Model, options: PickRemoteSourceOp export async function pickRemoteSource(model: Model, options: PickRemoteSourceOptions & { branch: true }): Promise; export async function pickRemoteSource(model: Model, options: PickRemoteSourceOptions = {}): Promise { const quickpick = window.createQuickPick<(QuickPickItem & { provider?: RemoteSourceProvider; url?: string })>(); - quickpick.ignoreFocusOut = true; quickpick.title = options.title; if (options.providerName) { diff --git a/extensions/git/src/actionButton.ts b/extensions/git/src/actionButton.ts index e95e0afae0e..4b07d2a7684 100644 --- a/extensions/git/src/actionButton.ts +++ b/extensions/git/src/actionButton.ts @@ -12,6 +12,7 @@ import { dispose } from './util'; interface ActionButtonState { readonly HEAD: Branch | undefined; + readonly isCheckoutInProgress: boolean; readonly isCommitInProgress: boolean; readonly isMergeInProgress: boolean; readonly isRebaseInProgress: boolean; @@ -39,6 +40,7 @@ export class ActionButtonCommand { readonly postCommitCommandCenter: CommitCommandsCenter) { this._state = { HEAD: undefined, + isCheckoutInProgress: false, isCommitInProgress: false, isMergeInProgress: false, isRebaseInProgress: false, @@ -154,7 +156,7 @@ export class ActionButtonCommand { l10n.t({ message: 'Publish Branch', comment: ['{Locked="Branch"}', 'Do not translate "Branch" as it is a git term'] })), arguments: [this.repository.sourceControl], }, - enabled: !this.state.isSyncInProgress + enabled: !this.state.isCheckoutInProgress && !this.state.isSyncInProgress }; } @@ -180,11 +182,15 @@ export class ActionButtonCommand { arguments: [this.repository.sourceControl], }, description: `${icon}${behind}${ahead}`, - enabled: !this.state.isSyncInProgress + enabled: !this.state.isCheckoutInProgress && !this.state.isSyncInProgress }; } private onDidChangeOperations(): void { + const isCheckoutInProgress + = this.repository.operations.isRunning(OperationKind.Checkout) || + this.repository.operations.isRunning(OperationKind.CheckoutTracking); + const isCommitInProgress = this.repository.operations.isRunning(OperationKind.Commit) || this.repository.operations.isRunning(OperationKind.PostCommitCommand) || @@ -195,7 +201,7 @@ export class ActionButtonCommand { this.repository.operations.isRunning(OperationKind.Push) || this.repository.operations.isRunning(OperationKind.Pull); - this.state = { ...this.state, isCommitInProgress, isSyncInProgress }; + this.state = { ...this.state, isCheckoutInProgress, isCommitInProgress, isSyncInProgress }; } private onDidChangeSmartCommitSettings(): void { diff --git a/extensions/git/src/ipc/ipcServer.ts b/extensions/git/src/ipc/ipcServer.ts index c9de357b1a6..8481aa4a35d 100644 --- a/extensions/git/src/ipc/ipcServer.ts +++ b/extensions/git/src/ipc/ipcServer.ts @@ -17,7 +17,7 @@ function getIPCHandlePath(id: string): string { return `\\\\.\\pipe\\vscode-git-${id}-sock`; } - if (process.env['XDG_RUNTIME_DIR']) { + if (process.platform !== 'darwin' && process.env['XDG_RUNTIME_DIR']) { return path.join(process.env['XDG_RUNTIME_DIR'] as string, `vscode-git-${id}.sock`); } diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 4a12fb8eb2b..6c59db8c15e 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -972,9 +972,13 @@ export class Repository implements Disposable { return; } - const path = uri.path; + // Ignore path that is inside a merge group + if (this.mergeGroup.resourceStates.some(r => r.resourceUri.path === uri.path)) { + return undefined; + } - if (this.mergeGroup.resourceStates.some(r => r.resourceUri.path === path)) { + // Ignore path that is inside a submodule + if (this.submodules.some(s => isDescendant(path.join(this.repository.root, s.path), uri.path))) { return undefined; } diff --git a/extensions/github-authentication/src/githubServer.ts b/extensions/github-authentication/src/githubServer.ts index 8babd85ab73..dc7278f6d4f 100644 --- a/extensions/github-authentication/src/githubServer.ts +++ b/extensions/github-authentication/src/githubServer.ts @@ -594,6 +594,13 @@ export class GitHubServer implements IGitHubServer { return; } + /* __GDPR__ + "session" : { + "owner": "TylerLeonhardt", + "isEdu": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "isManaged": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ this._telemetryReporter.sendTelemetryEvent('session', { isEdu: edu ?? 'unknown', isManaged: managed ?? 'unknown' diff --git a/extensions/github/package.json b/extensions/github/package.json index 046bdc70bfc..68cbd72cbfa 100644 --- a/extensions/github/package.json +++ b/extensions/github/package.json @@ -27,6 +27,7 @@ }, "enabledApiProposals": [ "contribShareMenu", + "contribEditorLineNumberMenu", "contribEditSessions" ], "contributes": { @@ -43,6 +44,10 @@ "command": "github.copyVscodeDevLinkFile", "title": "Copy vscode.dev Link" }, + { + "command": "github.copyVscodeDevLinkWithoutRange", + "title": "Copy vscode.dev Link" + }, { "command": "github.openOnVscodeDev", "title": "Open in vscode.dev", @@ -54,7 +59,8 @@ "command": "github.openOnVscodeDev", "when": "github.hasGitHubRepo", "qualifiedName": "Continue Working in vscode.dev", - "remoteGroup": "virtualfs_43_file_0_web@0" + "category": "Remote Repositories", + "remoteGroup": "virtualfs_44_vscode-vfs_2_web@2" } ], "menus": { @@ -71,6 +77,10 @@ "command": "github.copyVscodeDevLinkFile", "when": "false" }, + { + "command": "github.copyVscodeDevLinkWithoutRange", + "when": "false" + }, { "command": "github.openOnVscodeDev", "when": "false" @@ -79,17 +89,44 @@ "file/share": [ { "command": "github.copyVscodeDevLinkFile", - "when": "github.hasGitHubRepo", + "when": "github.hasGitHubRepo && remoteName != 'codespaces'", "group": "0_vscode@0" } ], "editor/context/share": [ { "command": "github.copyVscodeDevLink", - "when": "github.hasGitHubRepo && resourceScheme != untitled", + "when": "github.hasGitHubRepo && resourceScheme != untitled && remoteName != 'codespaces'", + "group": "0_vscode@0" + } + ], + "explorer/context/share": [ + { + "command": "github.copyVscodeDevLinkWithoutRange", + "when": "github.hasGitHubRepo && resourceScheme != untitled && remoteName != 'codespaces'", + "group": "0_vscode@0" + } + ], + "editor/lineNumber/context": [ + { + "command": "github.copyVscodeDevLink", + "when": "github.hasGitHubRepo && resourceScheme != untitled && activeEditor == workbench.editors.files.textFileEditor && config.editor.lineNumbers == on && remoteName != 'codespaces'", + "group": "1_cutcopypaste@2" + }, + { + "command": "github.copyVscodeDevLink", + "when": "github.hasGitHubRepo && resourceScheme != untitled && activeEditor == workbench.editor.notebook && remoteName != 'codespaces'", + "group": "1_cutcopypaste@2" + } + ], + "editor/title/context/share": [ + { + "command": "github.copyVscodeDevLinkWithoutRange", + "when": "github.hasGitHubRepo && resourceScheme != untitled && remoteName != 'codespaces'", "group": "0_vscode@0" } ] + }, "configuration": [ { diff --git a/extensions/github/src/commands.ts b/extensions/github/src/commands.ts index d46bd50e454..7158759c672 100644 --- a/extensions/github/src/commands.ts +++ b/extensions/github/src/commands.ts @@ -7,15 +7,15 @@ import * as vscode from 'vscode'; import { API as GitAPI } from './typings/git'; import { publishRepository } from './publish'; import { DisposableStore } from './util'; -import { getLink } from './links'; +import { LinkContext, getLink } from './links'; function getVscodeDevHost(): string { return `https://${vscode.env.appName.toLowerCase().includes('insiders') ? 'insiders.' : ''}vscode.dev/github`; } -async function copyVscodeDevLink(gitAPI: GitAPI, useSelection: boolean) { +async function copyVscodeDevLink(gitAPI: GitAPI, useSelection: boolean, context: LinkContext, includeRange = true) { try { - const permalink = getLink(gitAPI, useSelection, getVscodeDevHost()); + const permalink = getLink(gitAPI, useSelection, getVscodeDevHost(), undefined, context, includeRange); if (permalink) { return vscode.env.clipboard.writeText(permalink); } @@ -45,12 +45,16 @@ export function registerCommands(gitAPI: GitAPI): vscode.Disposable { } })); - disposables.add(vscode.commands.registerCommand('github.copyVscodeDevLink', async () => { - return copyVscodeDevLink(gitAPI, true); + disposables.add(vscode.commands.registerCommand('github.copyVscodeDevLink', async (context: LinkContext) => { + return copyVscodeDevLink(gitAPI, true, context); })); - disposables.add(vscode.commands.registerCommand('github.copyVscodeDevLinkFile', async () => { - return copyVscodeDevLink(gitAPI, false); + disposables.add(vscode.commands.registerCommand('github.copyVscodeDevLinkFile', async (context: LinkContext) => { + return copyVscodeDevLink(gitAPI, false, context); + })); + + disposables.add(vscode.commands.registerCommand('github.copyVscodeDevLinkWithoutRange', async (context: LinkContext) => { + return copyVscodeDevLink(gitAPI, true, context, false); })); disposables.add(vscode.commands.registerCommand('github.openOnVscodeDev', async () => { diff --git a/extensions/github/src/links.ts b/extensions/github/src/links.ts index 00a2354645b..5cbdf2e78bc 100644 --- a/extensions/github/src/links.ts +++ b/extensions/github/src/links.ts @@ -40,22 +40,40 @@ interface INotebookPosition { range: vscode.Range | undefined; } -function getFileAndPosition(): IFilePosition | INotebookPosition | undefined { - let uri: vscode.Uri | undefined; - let range: vscode.Range | undefined; - if (vscode.window.activeTextEditor) { - uri = vscode.window.activeTextEditor.document.uri; +interface EditorLineNumberContext { + uri: vscode.Uri; + lineNumber: number; +} +export type LinkContext = vscode.Uri | EditorLineNumberContext | undefined; +function extractContext(context: LinkContext): { fileUri: vscode.Uri | undefined; lineNumber: number | undefined } { + if (context instanceof vscode.Uri) { + return { fileUri: context, lineNumber: undefined }; + } else if (context !== undefined && 'lineNumber' in context && 'uri' in context) { + return { fileUri: context.uri, lineNumber: context.lineNumber }; + } else { + return { fileUri: undefined, lineNumber: undefined }; + } +} + +function getFileAndPosition(context: LinkContext): IFilePosition | INotebookPosition | undefined { + let range: vscode.Range | undefined; + + const { fileUri, lineNumber } = extractContext(context); + const uri = fileUri ?? vscode.window.activeTextEditor?.document.uri; + + if (uri) { if (uri.scheme === 'vscode-notebook-cell' && vscode.window.activeNotebookEditor?.notebook.uri.fsPath === uri.fsPath) { // if the active editor is a notebook editor and the focus is inside any a cell text editor // generate deep link for text selection for the notebook cell. const cell = vscode.window.activeNotebookEditor.notebook.getCells().find(cell => cell.document.uri.fragment === uri?.fragment); const cellIndex = cell?.index ?? vscode.window.activeNotebookEditor.selection.start; - const range = cell !== undefined ? vscode.window.activeTextEditor.selection : undefined; + + const range = getRangeOrSelection(lineNumber); return { type: LinkType.Notebook, uri, cellIndex, range }; } else { // the active editor is a text editor - range = vscode.window.activeTextEditor.selection; + range = getRangeOrSelection(lineNumber); return { type: LinkType.File, uri, range }; } } @@ -68,6 +86,12 @@ function getFileAndPosition(): IFilePosition | INotebookPosition | undefined { return undefined; } +function getRangeOrSelection(lineNumber: number | undefined) { + return lineNumber !== undefined && (!vscode.window.activeTextEditor || vscode.window.activeTextEditor.selection.isEmpty || !vscode.window.activeTextEditor.selection.contains(new vscode.Position(lineNumber - 1, 0))) + ? new vscode.Range(lineNumber - 1, 0, lineNumber - 1, 1) + : vscode.window.activeTextEditor?.selection; +} + function rangeString(range: vscode.Range | undefined) { if (!range) { return ''; @@ -95,9 +119,9 @@ export function notebookCellRangeString(index: number | undefined, range: vscode return hash; } -export function getLink(gitAPI: GitAPI, useSelection: boolean, hostPrefix?: string, linkType: 'permalink' | 'headlink' = 'permalink'): string | undefined { +export function getLink(gitAPI: GitAPI, useSelection: boolean, hostPrefix?: string, linkType: 'permalink' | 'headlink' = 'permalink', context?: LinkContext, useRange?: boolean): string | undefined { hostPrefix = hostPrefix ?? 'https://github.com'; - const fileAndPosition = getFileAndPosition(); + const fileAndPosition = getFileAndPosition(context); if (!fileAndPosition) { return; } @@ -127,8 +151,8 @@ export function getLink(gitAPI: GitAPI, useSelection: boolean, hostPrefix?: stri const blobSegment = (gitRepo.state.HEAD?.ahead === 0) ? `/blob/${linkType === 'headlink' ? gitRepo.state.HEAD.name : gitRepo.state.HEAD?.commit}` : ''; const fileSegments = fileAndPosition.type === LinkType.File - ? (useSelection ? `${uri.path.substring(gitRepo.rootUri.path.length)}${rangeString(fileAndPosition.range)}` : '') - : (useSelection ? `${uri.path.substring(gitRepo.rootUri.path.length)}${notebookCellRangeString(fileAndPosition.cellIndex, fileAndPosition.range)}` : ''); + ? (useSelection ? `${uri.path.substring(gitRepo.rootUri.path.length)}${useRange ? rangeString(fileAndPosition.range) : ''}` : '') + : (useSelection ? `${uri.path.substring(gitRepo.rootUri.path.length)}${useRange ? notebookCellRangeString(fileAndPosition.cellIndex, fileAndPosition.range) : ''}` : ''); return `${hostPrefix}/${repo.owner}/${repo.repo}${blobSegment }${fileSegments}`; diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index cfb791ec324..ab8a7562758 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -258,8 +258,8 @@ ] }, "dependencies": { - "@vscode/extension-telemetry": "^0.7.4-preview", - "vscode-languageclient": "^8.1.0-next.2", + "@vscode/extension-telemetry": "^0.7.5", + "vscode-languageclient": "^8.1.0", "vscode-uri": "^3.0.7" }, "devDependencies": { diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json index 18b9924e86f..7fc2795e590 100644 --- a/extensions/html-language-features/server/package.json +++ b/extensions/html-language-features/server/package.json @@ -10,9 +10,9 @@ "main": "./out/node/htmlServerMain", "dependencies": { "@vscode/l10n": "^0.0.11", - "vscode-css-languageservice": "^6.2.3", + "vscode-css-languageservice": "^6.2.4", "vscode-html-languageservice": "^5.0.4", - "vscode-languageserver": "^8.1.0-next.6", + "vscode-languageserver": "^8.1.0", "vscode-languageserver-textdocument": "^1.0.8", "vscode-uri": "^3.0.7" }, diff --git a/extensions/html-language-features/server/yarn.lock b/extensions/html-language-features/server/yarn.lock index 971f6b60510..20056d64263 100644 --- a/extensions/html-language-features/server/yarn.lock +++ b/extensions/html-language-features/server/yarn.lock @@ -17,14 +17,14 @@ resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.11.tgz#325d7beb2cfb87162bc624d16c4d546de6a73b72" integrity sha512-ukOMWnCg1tCvT7WnDfsUKQOFDQGsyR5tNgRpwmqi+5/vzU3ghdDXzvIM4IOPdSb3OeSsBNvmSL8nxIVOqi2WXA== -vscode-css-languageservice@^6.2.3: - version "6.2.3" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.2.3.tgz#6c1e6104e77f1fb729eeea5cd2f81f3b800d87ff" - integrity sha512-EAyhyIVHpEaf+GjtI+tVe7SekdoANfG0aubnspsQwak3Qkimn/97FpAufNyXk636ngW05pjNKAR9zyTCzo6avQ== +vscode-css-languageservice@^6.2.4: + version "6.2.4" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.2.4.tgz#d03ca783ad922cb903602ca1478f5161e5e5de54" + integrity sha512-9UG0s3Ss8rbaaPZL1AkGzdjrGY8F+P+Ne9snsrvD9gxltDGhsn8C2dQpqQewHrMW37OvlqJoI8sUU2AWDb+qNw== dependencies: "@vscode/l10n" "^0.0.11" vscode-languageserver-textdocument "^1.0.8" - vscode-languageserver-types "^3.17.2" + vscode-languageserver-types "^3.17.3" vscode-uri "^3.0.7" vscode-html-languageservice@^5.0.4: @@ -37,40 +37,40 @@ vscode-html-languageservice@^5.0.4: vscode-languageserver-types "^3.17.2" vscode-uri "^3.0.7" -vscode-jsonrpc@8.1.0-next.7: - version "8.1.0-next.7" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.7.tgz#4ecfada9866f677da9a5915abfceb7b7c90962f6" - integrity sha512-UJlY2e4wnI+GkaNYM2TERqrNvTe0XScny7lUA4f+F+z6XI5pDJnHj6udXiGJofT/tX57d8C6fnlfgrCfF6aptQ== +vscode-jsonrpc@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz#cb9989c65e219e18533cc38e767611272d274c94" + integrity sha512-6TDy/abTQk+zDGYazgbIPc+4JoXdwC8NHU9Pbn4UJP1fehUyZmM4RHp5IthX7A6L5KS30PRui+j+tbbMMMafdw== -vscode-languageserver-protocol@3.17.3-next.6: - version "3.17.3-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.6.tgz#e43dc5dc0e730e3a4d1cb523cce85cd34b6fc64d" - integrity sha512-UCL2DaAOCzGFZKIAJ4wOS9BXVbeARL8GxXTW7ANnAXJg03IytNmOJcmguL6l+ht4CCdKNQbnRSJB4dh8cgDyJw== +vscode-languageserver-protocol@3.17.3: + version "3.17.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3.tgz#6d0d54da093f0c0ee3060b81612cce0f11060d57" + integrity sha512-924/h0AqsMtA5yK22GgMtCYiMdCOtWTSGgUOkgEDX+wk2b0x4sAfLiO4NxBxqbiVtz7K7/1/RgVrVI0NClZwqA== dependencies: - vscode-jsonrpc "8.1.0-next.7" - vscode-languageserver-types "3.17.3-next.3" + vscode-jsonrpc "8.1.0" + vscode-languageserver-types "3.17.3" vscode-languageserver-textdocument@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz#9eae94509cbd945ea44bca8dcfe4bb0c15bb3ac0" integrity sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q== -vscode-languageserver-types@3.17.3-next.3: - version "3.17.3-next.3" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3-next.3.tgz#fc909d37d4200126d74583f2114e53ace27a3e04" - integrity sha512-R36Wi5sHoVc/PsAva0QGoEgw+LRCXPDKcdjFfgoVwrRdrFOdYUkvp5G4NvrPUsVT2f2qS/bSs6QiRxyjNkcR9A== +vscode-languageserver-types@3.17.3, vscode-languageserver-types@^3.17.3: + version "3.17.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64" + integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA== vscode-languageserver-types@^3.17.2: version "3.17.2" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz#b2c2e7de405ad3d73a883e91989b850170ffc4f2" integrity sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA== -vscode-languageserver@^8.1.0-next.6: - version "8.1.0-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.1.0-next.6.tgz#32fe5042b92b58b6f2c3c8cba0ddc77153ad47a7" - integrity sha512-YSj9fKN0FtVW95RKjcy8UheODK4YosqiZUkEbAgJJ0uMxR1Om1dhD/+QwYUKfJX/u8KLS/qFroMNVFHoPoc2hg== +vscode-languageserver@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.1.0.tgz#5024253718915d84576ce6662dd46a791498d827" + integrity sha512-eUt8f1z2N2IEUDBsKaNapkz7jl5QpskN2Y0G01T/ItMxBxw1fJwvtySGB9QMecatne8jFIWJGWI61dWjyTLQsw== dependencies: - vscode-languageserver-protocol "3.17.3-next.6" + vscode-languageserver-protocol "3.17.3" vscode-uri@^3.0.7: version "3.0.7" diff --git a/extensions/html-language-features/yarn.lock b/extensions/html-language-features/yarn.lock index 3d63be49483..4b4415ab484 100644 --- a/extensions/html-language-features/yarn.lock +++ b/extensions/html-language-features/yarn.lock @@ -9,7 +9,7 @@ dependencies: tslib "^2.2.0" -"@azure/core-auth@^1.3.0": +"@azure/core-auth@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.4.0.tgz#6fa9661c1705857820dbc216df5ba5665ac36a9e" integrity sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ== @@ -17,36 +17,30 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-http@^2.2.3": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-2.3.0.tgz#fb96de9a96923c186de15127472cb8e177f7158f" - integrity sha512-Gikj2QO9W41rw7yiKWi2Q2OcVcukt+ux7ZZeFy4ilC/0b1Wcr0rjseZh9bqJ3NI9+h78Hix34ZjEg316iHjbTA== +"@azure/core-rest-pipeline@^1.10.0": + 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.3.0" - "@azure/core-tracing" "1.0.0-preview.13" - "@azure/core-util" "^1.1.1" + "@azure/core-auth" "^1.4.0" + "@azure/core-tracing" "^1.0.1" + "@azure/core-util" "^1.0.0" "@azure/logger" "^1.0.0" - "@types/node-fetch" "^2.5.0" - "@types/tunnel" "^0.0.3" form-data "^4.0.0" - node-fetch "^2.6.7" - process "^0.11.10" - tough-cookie "^4.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" tslib "^2.2.0" - tunnel "^0.0.6" uuid "^8.3.0" - xml2js "^0.4.19" -"@azure/core-tracing@1.0.0-preview.13": - version "1.0.0-preview.13" - resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz#55883d40ae2042f6f1e12b17dd0c0d34c536d644" - integrity sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ== +"@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: - "@opentelemetry/api" "^1.0.1" tslib "^2.2.0" -"@azure/core-util@^1.1.1": +"@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" integrity sha512-A4TBYVQCtHOigFb2ETiiKFDocBoI1Zk2Ui1KpI42aJSIDexF7DHQFpnjonltXAIU/ceH+1fsZAWWgvX6/AKzog== @@ -132,7 +126,7 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.1", "@opentelemetry/api@^1.0.4": +"@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== @@ -166,47 +160,40 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== -"@types/node-fetch@^2.5.0": - version "2.6.2" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" - integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - -"@types/node@*": - version "18.11.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" - integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== +"@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/node@16.x": version "16.11.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== -"@types/tunnel@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.3.tgz#f109e730b072b3136347561fc558c9358bb8c6e9" - integrity sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA== - dependencies: - "@types/node" "*" - -"@vscode/extension-telemetry@^0.7.4-preview": - version "0.7.4-preview" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.4-preview.tgz#318d6bc54064e5f443b25dfb42fec724d888c36b" - integrity sha512-6OkvjCc+DaC9B26t3hj7vuAxf1ONm/p4LrVvFrapa+jBCKxXXUaV1Asz6+QxYaPfd4Ws/MlnFfCvlgvv3uYRwQ== +"@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== dependencies: "@microsoft/1ds-core-js" "^3.2.8" "@microsoft/1ds-post-js" "^3.2.8" "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.3.6" + applicationinsights "2.4.1" -applicationinsights@2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.3.6.tgz#91277ce44e5f6d2f85336922c05d90f8699c2e70" - integrity sha512-ZzXXpZpDRGcy6Pp5V319nDF9/+Ey7jNknEXZyaBajtC5onN0dcBem6ng5jcb3MPH2AjYWRI8XgyNEuzP/6Y5/A== +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: - "@azure/core-http" "^2.2.3" + 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== + dependencies: + "@azure/core-auth" "^1.4.0" + "@azure/core-rest-pipeline" "^1.10.0" "@microsoft/applicationinsights-web-snippet" "^1.0.1" "@opentelemetry/api" "^1.0.4" "@opentelemetry/core" "^1.0.1" @@ -273,6 +260,13 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" +debug@4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -297,15 +291,6 @@ emitter-listener@^1.0.1, emitter-listener@^1.1.1: dependencies: shimmer "^1.2.0" -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -315,6 +300,23 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +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" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -341,42 +343,10 @@ minimatch@^5.1.0: dependencies: brace-expansion "^2.0.1" -node-fetch@^2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== - -psl@^1.1.33: - version "1.9.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== - -punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -querystringify@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" - integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - -sax@>=0.6.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +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== semver@^5.3.0, semver@^5.4.1: version "5.7.1" @@ -400,107 +370,48 @@ 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== -tough-cookie@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.2.0" - url-parse "^1.5.3" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== -tunnel@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" - integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== - -universalify@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" - integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== - -url-parse@^1.5.3: - version "1.5.10" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" - integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - 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== -vscode-jsonrpc@8.1.0-next.3: - version "8.1.0-next.3" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.3.tgz#964c91a3bfd1949b4c3da7136ba46b48b42991ad" - integrity sha512-4eDeAnkWFKFTmT7tUR2wDngNAuwGHvV7yPCzPWGudBWJOoXaPQnwmiQChoj+umH1y2NR+MdBtx49xlZA7FoLRQ== +vscode-jsonrpc@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz#cb9989c65e219e18533cc38e767611272d274c94" + integrity sha512-6TDy/abTQk+zDGYazgbIPc+4JoXdwC8NHU9Pbn4UJP1fehUyZmM4RHp5IthX7A6L5KS30PRui+j+tbbMMMafdw== -vscode-languageclient@^8.1.0-next.2: - version "8.1.0-next.2" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.1.0-next.2.tgz#12a248299d23e48cb9d316129bf9ba0592caa533" - integrity sha512-ZGCQaqXyT7Y4H68zDQ/8XnNzo9tlUxuarJa0hT5EncAC0vmVAxLvhbsz2iSlWx3j6UZUgBM0b6UZtjpzkqr3tQ== +vscode-languageclient@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.1.0.tgz#3e67d5d841481ac66ddbdaa55b4118742f6a9f3f" + integrity sha512-GL4QdbYUF/XxQlAsvYWZRV3V34kOkpRlvV60/72ghHfsYFnS/v2MANZ9P6sHmxFcZKOse8O+L9G7Czg0NUWing== dependencies: minimatch "^5.1.0" semver "^7.3.7" - vscode-languageserver-protocol "3.17.3-next.2" + vscode-languageserver-protocol "3.17.3" -vscode-languageserver-protocol@3.17.3-next.2: - version "3.17.3-next.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.2.tgz#e906471899b9ed2ae1139f95592e0e5c7580bf0f" - integrity sha512-T+vSRHgApc1xCsOUJ/M7UN/tN4aINvc3FYJ6P3vAhvv0i4jZZewFMEonZB76B94TiY6z4eScgaG6m73gTgnyyw== +vscode-languageserver-protocol@3.17.3: + version "3.17.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3.tgz#6d0d54da093f0c0ee3060b81612cce0f11060d57" + integrity sha512-924/h0AqsMtA5yK22GgMtCYiMdCOtWTSGgUOkgEDX+wk2b0x4sAfLiO4NxBxqbiVtz7K7/1/RgVrVI0NClZwqA== dependencies: - vscode-jsonrpc "8.1.0-next.3" - vscode-languageserver-types "3.17.2" + vscode-jsonrpc "8.1.0" + vscode-languageserver-types "3.17.3" -vscode-languageserver-types@3.17.2: - version "3.17.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz#b2c2e7de405ad3d73a883e91989b850170ffc4f2" - integrity sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA== +vscode-languageserver-types@3.17.3: + version "3.17.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64" + integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA== vscode-uri@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.7.tgz#6d19fef387ee6b46c479e5fb00870e15e58c1eb8" integrity sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA== -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -xml2js@^0.4.19: - version "0.4.23" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" diff --git a/extensions/html/language-configuration.json b/extensions/html/language-configuration.json index 628396b0918..ea7a98a3d43 100644 --- a/extensions/html/language-configuration.json +++ b/extensions/html/language-configuration.json @@ -4,7 +4,6 @@ }, "brackets": [ [""], - ["<", ">"], ["{", "}"], ["(", ")"] ], diff --git a/extensions/ipynb/package.nls.json b/extensions/ipynb/package.nls.json index 5fead32a38b..bd8e0ab1da0 100644 --- a/extensions/ipynb/package.nls.json +++ b/extensions/ipynb/package.nls.json @@ -6,5 +6,10 @@ "newUntitledIpynb.shortTitle": "Jupyter Notebook", "openIpynbInNotebookEditor.title": "Open IPYNB File In Notebook Editor", "cleanInvalidImageAttachment.title": "Clean Invalid Image Attachment Reference", - "markdownAttachmentRenderer.displayName": "Markdown it ipynb Cell Attachment renderer" + "markdownAttachmentRenderer.displayName": { + "message": "Markdown-It ipynb Cell Attachment renderer", + "comment": [ + "Markdown-It is a product name and should not be translated" + ] + } } diff --git a/extensions/ipynb/src/serializers.ts b/extensions/ipynb/src/serializers.ts index 96da8f2c617..27c45bce918 100644 --- a/extensions/ipynb/src/serializers.ts +++ b/extensions/ipynb/src/serializers.ts @@ -332,9 +332,10 @@ function convertOutputMimeToJupyterOutput(mime: string, value: Uint8Array) { } else if (mime.toLowerCase().includes('json')) { const stringValue = textDecoder.decode(value); return stringValue.length > 0 ? JSON.parse(stringValue) : stringValue; + } else if (mime === 'image/svg+xml') { + return splitMultilineString(textDecoder.decode(value)); } else { - const stringValue = textDecoder.decode(value); - return stringValue; + return textDecoder.decode(value); } } catch (ex) { return ''; diff --git a/extensions/java/language-configuration.json b/extensions/java/language-configuration.json index e19d2d749f8..610adc686b4 100644 --- a/extensions/java/language-configuration.json +++ b/extensions/java/language-configuration.json @@ -29,5 +29,74 @@ "start": "^\\s*//\\s*(?:(?:#?region\\b)|(?:))" } - } + }, + "onEnterRules": [ + { + // e.g. /** | */ + "beforeText": { + "pattern": "^\\s*/\\*\\*(?!/)([^\\*]|\\*(?!/))*$" + }, + "afterText": { + "pattern": "^\\s*\\*/$" + }, + "action": { + "indent": "indentOutdent", + "appendText": " * " + } + }, + { + // e.g. /** ...| + "beforeText": { + "pattern": "^\\s*/\\*\\*(?!/)([^\\*]|\\*(?!/))*$" + }, + "action": { + "indent": "none", + "appendText": " * " + } + }, + { + // e.g. * ...| + "beforeText": { + "pattern": "^(\\t|[ ])*[ ]\\*([ ]([^\\*]|\\*(?!/))*)?$" + }, + "previousLineText": { + "pattern": "(?=^(\\s*(/\\*\\*|\\*)).*)(?=(?!(\\s*\\*/)))" + }, + "action": { + "indent": "none", + "appendText": "* " + } + }, + { + // e.g. */| + "beforeText": { + "pattern": "^(\\t|[ ])*[ ]\\*/\\s*$" + }, + "action": { + "indent": "none", + "removeText": 1 + } + }, + { + // e.g. *-----*/| + "beforeText": { + "pattern": "^(\\t|[ ])*[ ]\\*[^/]*\\*/\\s*$" + }, + "action": { + "indent": "none", + "removeText": 1 + } + }, + { + "beforeText": { + "pattern": "^\\s*(\\bcase\\s.+:|\\bdefault:)$" + }, + "afterText": { + "pattern": "^(?!\\s*(\\bcase\\b|\\bdefault\\b))" + }, + "action": { + "indent": "indent" + } + } + ] } diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index 57361277809..43d5c8553b2 100644 --- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/8e4e371fe8dd57560b16a44474f8cf8ca981e715", + "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/0d73d1117e0a9b1d6635ebbe9aa37d615171b02d", "name": "JavaScript (with React support)", "scopeName": "source.js", "patterns": [ @@ -989,6 +989,9 @@ }, { "include": "#parameter-binding-element" + }, + { + "include": "#paren-expression" } ] }, @@ -1171,7 +1174,7 @@ "name": "keyword.operator.assignment.js" } }, - "end": "(?=[,);}\\]]|((?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?:&|{\\?]|$|;|^\\s*$|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", + "end": "(?=[,);}\\]=>:&|{\\?]|(extends\\s+)|$|;|^\\s*$|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ + { + "include": "#type-arguments" + }, { "include": "#expression" } @@ -3788,7 +3797,7 @@ "name": "keyword.operator.type.annotation.js" } }, - "end": "(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + "end": "(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", "patterns": [ { "include": "#type" @@ -3803,7 +3812,7 @@ "name": "keyword.operator.type.annotation.js" } }, - "end": "(?])|(?=^\\s*$)|((?<=\\S)(?=\\s*$))|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + "end": "(?])|(?=^\\s*$)|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", "patterns": [ { "include": "#type" @@ -4650,20 +4659,20 @@ "include": "#template-call" }, { - "name": "string.template.js", + "contentName": "string.template.js", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?(`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.js" }, "2": { - "name": "punctuation.definition.string.template.begin.js" + "name": "string.template.js punctuation.definition.string.template.begin.js" } }, "end": "`", "endCaptures": { "0": { - "name": "punctuation.definition.string.template.end.js" + "name": "string.template.js punctuation.definition.string.template.end.js" } }, "patterns": [ @@ -4680,7 +4689,6 @@ "template-call": { "patterns": [ { - "name": "string.template.js", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)", "end": "(?=`)", "patterns": [ @@ -4703,7 +4711,6 @@ ] }, { - "name": "string.template.js", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?\\s*(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)`)", "beginCaptures": { "1": { @@ -4759,20 +4766,20 @@ "include": "#template-call" }, { - "name": "string.template.js", + "contentName": "string.template.js", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?(`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.js" }, "2": { - "name": "punctuation.definition.string.template.begin.js" + "name": "string.template.js punctuation.definition.string.template.begin.js" } }, "end": "`", "endCaptures": { "0": { - "name": "punctuation.definition.string.template.end.js" + "name": "string.template.js punctuation.definition.string.template.end.js" } }, "patterns": [ diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json index 6c6e00215e6..299e33321a4 100644 --- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/8e4e371fe8dd57560b16a44474f8cf8ca981e715", + "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/0d73d1117e0a9b1d6635ebbe9aa37d615171b02d", "name": "JavaScript (with React support)", "scopeName": "source.js.jsx", "patterns": [ @@ -989,6 +989,9 @@ }, { "include": "#parameter-binding-element" + }, + { + "include": "#paren-expression" } ] }, @@ -1171,7 +1174,7 @@ "name": "keyword.operator.assignment.js.jsx" } }, - "end": "(?=[,);}\\]]|((?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?:&|{\\?]|$|;|^\\s*$|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", + "end": "(?=[,);}\\]=>:&|{\\?]|(extends\\s+)|$|;|^\\s*$|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ + { + "include": "#type-arguments" + }, { "include": "#expression" } @@ -3788,7 +3797,7 @@ "name": "keyword.operator.type.annotation.js.jsx" } }, - "end": "(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + "end": "(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", "patterns": [ { "include": "#type" @@ -3803,7 +3812,7 @@ "name": "keyword.operator.type.annotation.js.jsx" } }, - "end": "(?])|(?=^\\s*$)|((?<=\\S)(?=\\s*$))|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + "end": "(?])|(?=^\\s*$)|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", "patterns": [ { "include": "#type" @@ -4650,20 +4659,20 @@ "include": "#template-call" }, { - "name": "string.template.js.jsx", + "contentName": "string.template.js.jsx", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?(`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.js.jsx" }, "2": { - "name": "punctuation.definition.string.template.begin.js.jsx" + "name": "string.template.js.jsx punctuation.definition.string.template.begin.js.jsx" } }, "end": "`", "endCaptures": { "0": { - "name": "punctuation.definition.string.template.end.js.jsx" + "name": "string.template.js.jsx punctuation.definition.string.template.end.js.jsx" } }, "patterns": [ @@ -4680,7 +4689,6 @@ "template-call": { "patterns": [ { - "name": "string.template.js.jsx", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)", "end": "(?=`)", "patterns": [ @@ -4703,7 +4711,6 @@ ] }, { - "name": "string.template.js.jsx", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?\\s*(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)`)", "beginCaptures": { "1": { @@ -4759,20 +4766,20 @@ "include": "#template-call" }, { - "name": "string.template.js.jsx", + "contentName": "string.template.js.jsx", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?(`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.js.jsx" }, "2": { - "name": "punctuation.definition.string.template.begin.js.jsx" + "name": "string.template.js.jsx punctuation.definition.string.template.begin.js.jsx" } }, "end": "`", "endCaptures": { "0": { - "name": "punctuation.definition.string.template.end.js.jsx" + "name": "string.template.js.jsx punctuation.definition.string.template.end.js.jsx" } }, "patterns": [ diff --git a/extensions/json-language-features/client/src/jsonClient.ts b/extensions/json-language-features/client/src/jsonClient.ts index 54a8ecc64ed..d6e1404a7ac 100644 --- a/extensions/json-language-features/client/src/jsonClient.ts +++ b/extensions/json-language-features/client/src/jsonClient.ts @@ -11,7 +11,7 @@ import { ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n } from 'vscode'; import { - LanguageClientOptions, RequestType, NotificationType, + LanguageClientOptions, RequestType, NotificationType, FormattingOptions as LSPFormattingOptions, DidChangeConfigurationNotification, HandleDiagnosticsSignature, ResponseError, DocumentRangeFormattingParams, DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature, BaseLanguageClient, ProvideFoldingRangeSignature, ProvideDocumentSymbolsSignature, ProvideDocumentColorsSignature } from 'vscode-languageclient'; @@ -36,6 +36,23 @@ namespace LanguageStatusRequest { export const type: RequestType = new RequestType('json/languageStatus'); } +interface SortOptions extends LSPFormattingOptions { +} + +interface DocumentSortingParams { + /** + * The uri of the document to sort. + */ + readonly uri: string; + /** + * The sort options + */ + readonly options: SortOptions; +} + +namespace DocumentSortingRequest { + export const type: RequestType = new RequestType('json/sort'); +} export interface ISchemaAssociations { [pattern: string]: string[]; @@ -146,6 +163,37 @@ export async function startClient(context: ExtensionContext, newLanguageClient: window.showInformationMessage(l10n.t('JSON schema cache cleared.')); })); + toDispose.push(commands.registerCommand('json.sort', async () => { + + if (isClientReady) { + const textEditor = window.activeTextEditor; + if (textEditor) { + const document = textEditor.document; + const filesConfig = workspace.getConfiguration('files', document); + const options: SortOptions = { + tabSize: textEditor.options.tabSize ? Number(textEditor.options.tabSize) : 4, + insertSpaces: textEditor.options.insertSpaces ? Boolean(textEditor.options.insertSpaces) : true, + trimTrailingWhitespace: filesConfig.get('trimTrailingWhitespace'), + trimFinalNewlines: filesConfig.get('trimFinalNewlines'), + insertFinalNewline: filesConfig.get('insertFinalNewline'), + }; + const params: DocumentSortingParams = { + uri: document.uri.toString(), + options + }; + const textEdits = await client.sendRequest(DocumentSortingRequest.type, params); + const success = await textEditor.edit(mutator => { + for (const edit of textEdits) { + mutator.replace(client.protocol2CodeConverter.asRange(edit.range), edit.newText); + } + }); + if (!success) { + window.showErrorMessage(l10n.t('Failed to sort the JSONC document, please consider opening an issue.')); + } + } + } + })); + // Options to control the language client const clientOptions: LanguageClientOptions = { // Register the server for json documents @@ -497,40 +545,58 @@ function getSettings(): Settings { } }; - const collectSchemaSettings = (schemaSettings: JSONSchemaSettings[], folderUri?: Uri) => { - for (const setting of schemaSettings) { - const url = getSchemaId(setting, folderUri); - if (url) { - const schemaSetting: JSONSchemaSettings = { url, fileMatch: setting.fileMatch, folderUri: folderUri?.toString(false), schema: setting.schema }; - schemas.push(schemaSetting); + /* + * Add schemas from the settings + * folderUri to which folder the setting is scoped to. `undefined` means global (also external files) + * settingsLocation against which path relative schema URLs are resolved + */ + const collectSchemaSettings = (schemaSettings: JSONSchemaSettings[] | undefined, folderUri: string | undefined, settingsLocation: Uri | undefined) => { + if (schemaSettings) { + for (const setting of schemaSettings) { + const url = getSchemaId(setting, settingsLocation); + if (url) { + const schemaSetting: JSONSchemaSettings = { url, fileMatch: setting.fileMatch, folderUri, schema: setting.schema }; + schemas.push(schemaSetting); + } } } }; - const globalSettings = workspace.getConfiguration('json', null).get('schemas'); - if (Array.isArray(globalSettings)) { - collectSchemaSettings(globalSettings); - } - const folders = workspace.workspaceFolders; - if (folders) { - for (const folder of folders) { - const schemaConfigInfo = workspace.getConfiguration('json', folder.uri).inspect('schemas'); - if (schemaConfigInfo && Array.isArray(schemaConfigInfo.workspaceFolderValue)) { - collectSchemaSettings(schemaConfigInfo.workspaceFolderValue, folder.uri); + const folders = workspace.workspaceFolders ?? []; + + const schemaConfigInfo = workspace.getConfiguration('json', null).inspect('schemas'); + if (schemaConfigInfo) { + // settings in user config + collectSchemaSettings(schemaConfigInfo.globalValue, undefined, undefined); + if (workspace.workspaceFile) { + if (schemaConfigInfo.workspaceValue) { + const settingsLocation = Uri.joinPath(workspace.workspaceFile, '..'); + // settings in the workspace configuration file apply to all files (also external files) + collectSchemaSettings(schemaConfigInfo.workspaceValue, undefined, settingsLocation); + } + for (const folder of folders) { + const folderUri = folder.uri; + const folderSchemaConfigInfo = workspace.getConfiguration('json', folderUri).inspect('schemas'); + collectSchemaSettings(folderSchemaConfigInfo?.workspaceFolderValue, folderUri.toString(false), folderUri); + } + } else { + if (schemaConfigInfo.workspaceValue && folders.length === 1) { + // single folder workspace: settings apply to all files (also external files) + collectSchemaSettings(schemaConfigInfo.workspaceValue, undefined, folders[0].uri); } } } return settings; } -function getSchemaId(schema: JSONSchemaSettings, folderUri?: Uri): string | undefined { +function getSchemaId(schema: JSONSchemaSettings, settingsLocation?: Uri): string | undefined { let url = schema.url; if (!url) { if (schema.schema) { url = schema.schema.id || `vscode://schemas/custom/${encodeURIComponent(hash(schema.schema).toString(16))}`; } - } else if (folderUri && (url[0] === '.' || url[0] === '/')) { - url = Uri.joinPath(folderUri, url).toString(false); + } else if (settingsLocation && (url[0] === '.' || url[0] === '/')) { + url = Uri.joinPath(settingsLocation, url).toString(false); } return url; } diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index 1c5c88794b4..46b1b5564ff 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -149,13 +149,18 @@ "command": "json.clearCache", "title": "%json.command.clearCache%", "category": "JSON" + }, + { + "command": "json.sort", + "title": "%json.command.sort%", + "category": "JSON" } ] }, "dependencies": { - "@vscode/extension-telemetry": "^0.7.4-preview", + "@vscode/extension-telemetry": "^0.7.5", "request-light": "^0.7.0", - "vscode-languageclient": "^8.1.0-next.6" + "vscode-languageclient": "^8.1.0" }, "devDependencies": { "@types/node": "16.x" diff --git a/extensions/json-language-features/package.nls.json b/extensions/json-language-features/package.nls.json index a0d0a84b32c..571d047802d 100644 --- a/extensions/json-language-features/package.nls.json +++ b/extensions/json-language-features/package.nls.json @@ -17,5 +17,6 @@ "json.maxItemsComputed.desc": "The maximum number of outline symbols and folding regions computed (limited for performance reasons).", "json.maxItemsExceededInformation.desc": "Show notification when exceeding the maximum number of outline symbols and folding regions.", "json.enableSchemaDownload.desc": "When enabled, JSON schemas can be fetched from http and https locations.", - "json.command.clearCache": "Clear schema cache" + "json.command.clearCache": "Clear Schema Cache", + "json.command.sort": "Sort Document" } diff --git a/extensions/json-language-features/server/package.json b/extensions/json-language-features/server/package.json index 5abe1a2d35c..aef443f6a90 100644 --- a/extensions/json-language-features/server/package.json +++ b/extensions/json-language-features/server/package.json @@ -15,8 +15,8 @@ "@vscode/l10n": "^0.0.11", "jsonc-parser": "^3.2.0", "request-light": "^0.7.0", - "vscode-json-languageservice": "^5.2.0", - "vscode-languageserver": "^8.1.0-next.6", + "vscode-json-languageservice": "^5.3.2", + "vscode-languageserver": "^8.1.0", "vscode-uri": "^3.0.7" }, "devDependencies": { diff --git a/extensions/json-language-features/server/src/jsonServer.ts b/extensions/json-language-features/server/src/jsonServer.ts index 6a40666d18d..0282e6fa939 100644 --- a/extensions/json-language-features/server/src/jsonServer.ts +++ b/extensions/json-language-features/server/src/jsonServer.ts @@ -11,7 +11,7 @@ import { import { runSafe, runSafeAsync } from './utils/runner'; import { DiagnosticsSupport, registerDiagnosticsPullSupport, registerDiagnosticsPushSupport } from './utils/validation'; -import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Range, Position } from 'vscode-json-languageservice'; +import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Range, Position, SortOptions } from 'vscode-json-languageservice'; import { getLanguageModelCache } from './languageModelCache'; import { Utils, URI } from 'vscode-uri'; @@ -39,6 +39,20 @@ namespace LanguageStatusRequest { export const type: RequestType = new RequestType('json/languageStatus'); } +export interface DocumentSortingParams { + /** + * The uri of the document to sort. + */ + uri: string; + /** + * The sort options + */ + options: SortOptions; +} + +namespace DocumentSortingRequest { + export const type: RequestType = new RequestType('json/sort'); +} const workspaceContext = { resolveRelativePath: (relativePath: string, resource: string) => { @@ -112,9 +126,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) let jsonColorDecoratorLimit = Number.MAX_VALUE; let jsoncColorDecoratorLimit = Number.MAX_VALUE; - let formatterMaxNumberOfEdits = Number.MAX_VALUE; - let diagnosticsSupport: DiagnosticsSupport | undefined; @@ -295,6 +307,16 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) } }); + connection.onRequest(DocumentSortingRequest.type, async params => { + const uri = params.uri; + const options = params.options; + const document = documents.get(uri); + if (document) { + return languageService.sort(document, options); + } + return []; + }); + function updateConfiguration() { const languageSettings = { validate: validateEnabled, @@ -403,6 +425,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) }); function onFormat(textDocument: TextDocumentIdentifier, range: Range | undefined, options: FormattingOptions): TextEdit[] { + options.keepLines = keepLinesEnabled; const document = documents.get(textDocument.uri); if (document) { diff --git a/extensions/json-language-features/server/yarn.lock b/extensions/json-language-features/server/yarn.lock index 5649955bbd4..e6bc6982cc2 100644 --- a/extensions/json-language-features/server/yarn.lock +++ b/extensions/json-language-features/server/yarn.lock @@ -27,51 +27,46 @@ request-light@^0.7.0: resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.7.0.tgz#885628bb2f8040c26401ebf258ec51c4ae98ac2a" integrity sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q== -vscode-json-languageservice@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-5.2.0.tgz#884b7f108be4310e3332167c3ea60ab17f03418c" - integrity sha512-q8Rdhu2HEddRxvlhVqwh0cWmKK+OtyMB2xRhtqXEQ7cjb0iZ14madb90iJe9fCHPjoj9CGBrq6QzuOp8OE6XWg== +vscode-json-languageservice@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-5.3.2.tgz#11e530ba9ec541eaeb421dc274a22efdb5d580ef" + integrity sha512-5td6olfoNdtyxnNA4uocq7V9jdTJt63o9mGEntQb6cbD2HiObZW2XgbSj6nRaebWwBCiYdWpFklNjm6Wz6Xy1Q== dependencies: "@vscode/l10n" "^0.0.11" jsonc-parser "^3.2.0" vscode-languageserver-textdocument "^1.0.8" - vscode-languageserver-types "^3.17.2" + vscode-languageserver-types "^3.17.3" vscode-uri "^3.0.7" -vscode-jsonrpc@8.1.0-next.7: - version "8.1.0-next.7" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.7.tgz#4ecfada9866f677da9a5915abfceb7b7c90962f6" - integrity sha512-UJlY2e4wnI+GkaNYM2TERqrNvTe0XScny7lUA4f+F+z6XI5pDJnHj6udXiGJofT/tX57d8C6fnlfgrCfF6aptQ== +vscode-jsonrpc@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz#cb9989c65e219e18533cc38e767611272d274c94" + integrity sha512-6TDy/abTQk+zDGYazgbIPc+4JoXdwC8NHU9Pbn4UJP1fehUyZmM4RHp5IthX7A6L5KS30PRui+j+tbbMMMafdw== -vscode-languageserver-protocol@3.17.3-next.6: - version "3.17.3-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.6.tgz#e43dc5dc0e730e3a4d1cb523cce85cd34b6fc64d" - integrity sha512-UCL2DaAOCzGFZKIAJ4wOS9BXVbeARL8GxXTW7ANnAXJg03IytNmOJcmguL6l+ht4CCdKNQbnRSJB4dh8cgDyJw== +vscode-languageserver-protocol@3.17.3: + version "3.17.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3.tgz#6d0d54da093f0c0ee3060b81612cce0f11060d57" + integrity sha512-924/h0AqsMtA5yK22GgMtCYiMdCOtWTSGgUOkgEDX+wk2b0x4sAfLiO4NxBxqbiVtz7K7/1/RgVrVI0NClZwqA== dependencies: - vscode-jsonrpc "8.1.0-next.7" - vscode-languageserver-types "3.17.3-next.3" + vscode-jsonrpc "8.1.0" + vscode-languageserver-types "3.17.3" vscode-languageserver-textdocument@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz#9eae94509cbd945ea44bca8dcfe4bb0c15bb3ac0" integrity sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q== -vscode-languageserver-types@3.17.3-next.3: - version "3.17.3-next.3" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3-next.3.tgz#fc909d37d4200126d74583f2114e53ace27a3e04" - integrity sha512-R36Wi5sHoVc/PsAva0QGoEgw+LRCXPDKcdjFfgoVwrRdrFOdYUkvp5G4NvrPUsVT2f2qS/bSs6QiRxyjNkcR9A== +vscode-languageserver-types@3.17.3, vscode-languageserver-types@^3.17.3: + version "3.17.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64" + integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA== -vscode-languageserver-types@^3.17.2: - version "3.17.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz#b2c2e7de405ad3d73a883e91989b850170ffc4f2" - integrity sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA== - -vscode-languageserver@^8.1.0-next.6: - version "8.1.0-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.1.0-next.6.tgz#32fe5042b92b58b6f2c3c8cba0ddc77153ad47a7" - integrity sha512-YSj9fKN0FtVW95RKjcy8UheODK4YosqiZUkEbAgJJ0uMxR1Om1dhD/+QwYUKfJX/u8KLS/qFroMNVFHoPoc2hg== +vscode-languageserver@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.1.0.tgz#5024253718915d84576ce6662dd46a791498d827" + integrity sha512-eUt8f1z2N2IEUDBsKaNapkz7jl5QpskN2Y0G01T/ItMxBxw1fJwvtySGB9QMecatne8jFIWJGWI61dWjyTLQsw== dependencies: - vscode-languageserver-protocol "3.17.3-next.6" + vscode-languageserver-protocol "3.17.3" vscode-uri@^3.0.7: version "3.0.7" diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index 3f68105a5da..afa4409e718 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -9,7 +9,7 @@ dependencies: tslib "^2.2.0" -"@azure/core-auth@^1.3.0": +"@azure/core-auth@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.4.0.tgz#6fa9661c1705857820dbc216df5ba5665ac36a9e" integrity sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ== @@ -17,36 +17,30 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-http@^2.2.3": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-2.3.0.tgz#fb96de9a96923c186de15127472cb8e177f7158f" - integrity sha512-Gikj2QO9W41rw7yiKWi2Q2OcVcukt+ux7ZZeFy4ilC/0b1Wcr0rjseZh9bqJ3NI9+h78Hix34ZjEg316iHjbTA== +"@azure/core-rest-pipeline@^1.10.0": + 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.3.0" - "@azure/core-tracing" "1.0.0-preview.13" - "@azure/core-util" "^1.1.1" + "@azure/core-auth" "^1.4.0" + "@azure/core-tracing" "^1.0.1" + "@azure/core-util" "^1.0.0" "@azure/logger" "^1.0.0" - "@types/node-fetch" "^2.5.0" - "@types/tunnel" "^0.0.3" form-data "^4.0.0" - node-fetch "^2.6.7" - process "^0.11.10" - tough-cookie "^4.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" tslib "^2.2.0" - tunnel "^0.0.6" uuid "^8.3.0" - xml2js "^0.4.19" -"@azure/core-tracing@1.0.0-preview.13": - version "1.0.0-preview.13" - resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz#55883d40ae2042f6f1e12b17dd0c0d34c536d644" - integrity sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ== +"@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: - "@opentelemetry/api" "^1.0.1" tslib "^2.2.0" -"@azure/core-util@^1.1.1": +"@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" integrity sha512-A4TBYVQCtHOigFb2ETiiKFDocBoI1Zk2Ui1KpI42aJSIDexF7DHQFpnjonltXAIU/ceH+1fsZAWWgvX6/AKzog== @@ -132,7 +126,7 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.1", "@opentelemetry/api@^1.0.4": +"@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== @@ -166,47 +160,40 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== -"@types/node-fetch@^2.5.0": - version "2.6.2" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" - integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - -"@types/node@*": - version "18.11.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" - integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== +"@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/node@16.x": version "16.11.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== -"@types/tunnel@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.3.tgz#f109e730b072b3136347561fc558c9358bb8c6e9" - integrity sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA== - dependencies: - "@types/node" "*" - -"@vscode/extension-telemetry@^0.7.4-preview": - version "0.7.4-preview" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.4-preview.tgz#318d6bc54064e5f443b25dfb42fec724d888c36b" - integrity sha512-6OkvjCc+DaC9B26t3hj7vuAxf1ONm/p4LrVvFrapa+jBCKxXXUaV1Asz6+QxYaPfd4Ws/MlnFfCvlgvv3uYRwQ== +"@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== dependencies: "@microsoft/1ds-core-js" "^3.2.8" "@microsoft/1ds-post-js" "^3.2.8" "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.3.6" + applicationinsights "2.4.1" -applicationinsights@2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.3.6.tgz#91277ce44e5f6d2f85336922c05d90f8699c2e70" - integrity sha512-ZzXXpZpDRGcy6Pp5V319nDF9/+Ey7jNknEXZyaBajtC5onN0dcBem6ng5jcb3MPH2AjYWRI8XgyNEuzP/6Y5/A== +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: - "@azure/core-http" "^2.2.3" + 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== + dependencies: + "@azure/core-auth" "^1.4.0" + "@azure/core-rest-pipeline" "^1.10.0" "@microsoft/applicationinsights-web-snippet" "^1.0.1" "@opentelemetry/api" "^1.0.4" "@opentelemetry/core" "^1.0.1" @@ -273,6 +260,13 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" +debug@4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -297,15 +291,6 @@ emitter-listener@^1.0.1, emitter-listener@^1.1.1: dependencies: shimmer "^1.2.0" -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -315,6 +300,23 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +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" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -341,48 +343,16 @@ minimatch@^5.1.0: dependencies: brace-expansion "^2.0.1" -node-fetch@^2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== - -psl@^1.1.33: - version "1.9.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== - -punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -querystringify@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" - integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== +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== request-light@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.7.0.tgz#885628bb2f8040c26401ebf258ec51c4ae98ac2a" integrity sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q== -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - -sax@>=0.6.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - semver@^5.3.0, semver@^5.4.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -405,101 +375,42 @@ 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== -tough-cookie@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.2.0" - url-parse "^1.5.3" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== -tunnel@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" - integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== - -universalify@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" - integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== - -url-parse@^1.5.3: - version "1.5.10" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" - integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - 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== -vscode-jsonrpc@8.1.0-next.7: - version "8.1.0-next.7" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.7.tgz#4ecfada9866f677da9a5915abfceb7b7c90962f6" - integrity sha512-UJlY2e4wnI+GkaNYM2TERqrNvTe0XScny7lUA4f+F+z6XI5pDJnHj6udXiGJofT/tX57d8C6fnlfgrCfF6aptQ== +vscode-jsonrpc@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz#cb9989c65e219e18533cc38e767611272d274c94" + integrity sha512-6TDy/abTQk+zDGYazgbIPc+4JoXdwC8NHU9Pbn4UJP1fehUyZmM4RHp5IthX7A6L5KS30PRui+j+tbbMMMafdw== -vscode-languageclient@^8.1.0-next.6: - version "8.1.0-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.1.0-next.6.tgz#ce5c19ee6831a9c1886b0f19d9c2e2ebb0aa4c07" - integrity sha512-DvqmwhnQlgvYVoiVxYemPo/wQ2gtpJrgt10rgv32J5bg3OkVgWFH31Uut3jF30UK4aA2sLis64PD/yMMJZy+bQ== +vscode-languageclient@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.1.0.tgz#3e67d5d841481ac66ddbdaa55b4118742f6a9f3f" + integrity sha512-GL4QdbYUF/XxQlAsvYWZRV3V34kOkpRlvV60/72ghHfsYFnS/v2MANZ9P6sHmxFcZKOse8O+L9G7Czg0NUWing== dependencies: minimatch "^5.1.0" semver "^7.3.7" - vscode-languageserver-protocol "3.17.3-next.6" + vscode-languageserver-protocol "3.17.3" -vscode-languageserver-protocol@3.17.3-next.6: - version "3.17.3-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.6.tgz#e43dc5dc0e730e3a4d1cb523cce85cd34b6fc64d" - integrity sha512-UCL2DaAOCzGFZKIAJ4wOS9BXVbeARL8GxXTW7ANnAXJg03IytNmOJcmguL6l+ht4CCdKNQbnRSJB4dh8cgDyJw== +vscode-languageserver-protocol@3.17.3: + version "3.17.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3.tgz#6d0d54da093f0c0ee3060b81612cce0f11060d57" + integrity sha512-924/h0AqsMtA5yK22GgMtCYiMdCOtWTSGgUOkgEDX+wk2b0x4sAfLiO4NxBxqbiVtz7K7/1/RgVrVI0NClZwqA== dependencies: - vscode-jsonrpc "8.1.0-next.7" - vscode-languageserver-types "3.17.3-next.3" + vscode-jsonrpc "8.1.0" + vscode-languageserver-types "3.17.3" -vscode-languageserver-types@3.17.3-next.3: - version "3.17.3-next.3" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3-next.3.tgz#fc909d37d4200126d74583f2114e53ace27a3e04" - integrity sha512-R36Wi5sHoVc/PsAva0QGoEgw+LRCXPDKcdjFfgoVwrRdrFOdYUkvp5G4NvrPUsVT2f2qS/bSs6QiRxyjNkcR9A== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -xml2js@^0.4.19: - version "0.4.23" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== +vscode-languageserver-types@3.17.3: + version "3.17.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64" + integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA== yallist@^4.0.0: version "4.0.0" diff --git a/extensions/latex/cgmanifest.json b/extensions/latex/cgmanifest.json index 4aa9afa9391..a0b3f87945c 100644 --- a/extensions/latex/cgmanifest.json +++ b/extensions/latex/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "jlelong/vscode-latex-basics", "repositoryUrl": "https://github.com/jlelong/vscode-latex-basics", - "commitHash": "16ac438ab14488976672c3c948ed29335fcd9dd5" + "commitHash": "d80a1a5dcff9b85217e174242dd3d0e2210b94a0" } }, "license": "MIT", - "version": "1.5.0", + "version": "1.5.1", "description": "The files in syntaxes/ were originally part of https://github.com/James-Yu/LaTeX-Workshop. They have been extracted in the hope that they can useful outside of the LaTeX-Workshop extension.", "licenseDetail": [ "Copyright (c) vscode-latex-basics authors", diff --git a/extensions/latex/syntaxes/Bibtex.tmLanguage.json b/extensions/latex/syntaxes/Bibtex.tmLanguage.json index 3fe919168e8..d1e6a3c2224 100644 --- a/extensions/latex/syntaxes/Bibtex.tmLanguage.json +++ b/extensions/latex/syntaxes/Bibtex.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jlelong/vscode-latex-basics/commit/b98c2d4911652824fc990f4b26c9c30be59b78a2", + "version": "https://github.com/jlelong/vscode-latex-basics/commit/d80a1a5dcff9b85217e174242dd3d0e2210b94a0", "name": "BibTeX", "scopeName": "text.bibtex", "comment": "Grammar based on description from http://artis.imag.fr/~Xavier.Decoret/resources/xdkbibtex/bibtex_summary.html#comment\n\t\n\tTODO: Does not support @preamble\n\t", @@ -19,6 +19,13 @@ "end": "$\\n?", "name": "comment.line.at-sign.bibtex" }, + { + "patterns": [ + { + "include": "#percentage_comment" + } + ] + }, { "begin": "((@)(?i:string))\\s*(\\{)\\s*([a-zA-Z]*)", "beginCaptures": { @@ -49,7 +56,7 @@ ] }, { - "begin": "((@)i(?i::string))\\s*(\\()\\s*([a-zA-Z]*)", + "begin": "((@)(?i:string))\\s*(\\()\\s*([a-zA-Z]*)", "beginCaptures": { "1": { "name": "keyword.other.string-constant.bibtex" @@ -101,6 +108,12 @@ }, "name": "meta.entry.braces.bibtex", "patterns": [ + { + "include": "#percentage_comment" + }, + { + "include": "#url_field" + }, { "begin": "([a-zA-Z0-9\\!\\$\\&\\*\\+\\-\\.\\/\\:\\;\\<\\>\\?\\[\\]\\^\\_\\`\\|]+)\\s*(\\=)", "beginCaptures": { @@ -114,6 +127,9 @@ "end": "(?=[,}])", "name": "meta.key-assignment.bibtex", "patterns": [ + { + "include": "#percentage_comment" + }, { "include": "#string_var" }, @@ -151,6 +167,12 @@ }, "name": "meta.entry.parenthesis.bibtex", "patterns": [ + { + "include": "#percentage_comment" + }, + { + "include": "#url_field" + }, { "begin": "([a-zA-Z0-9\\!\\$\\&\\*\\+\\-\\.\\/\\:\\;\\<\\>\\?\\[\\]\\^\\_\\`\\|]+)\\s*(\\=)", "beginCaptures": { @@ -164,6 +186,9 @@ "end": "(?=[,)])", "name": "meta.key-assignment.bibtex", "patterns": [ + { + "include": "#percentage_comment" + }, { "include": "#string_var" }, @@ -237,6 +262,12 @@ } }, "patterns": [ + { + "include": "#url_cmd" + }, + { + "include": "#percentage_comment" + }, { "match": "@", "name": "invalid.illegal.at-sign.bibtex" @@ -260,6 +291,12 @@ } }, "patterns": [ + { + "include": "#url_cmd" + }, + { + "include": "#percentage_comment" + }, { "match": "@", "name": "invalid.illegal.at-sign.bibtex" @@ -267,6 +304,94 @@ ] } ] + }, + "string_url": { + "patterns": [ + { + "begin": "\\{|\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.bibtex" + } + }, + "end": "(\\}|\")(?=(?:,?\\s*\\}?\\s*\\n)|(?:\\s*#))", + "endCaptures": { + "1": { + "name": "punctuation.definition.string.end.bibtex" + } + }, + "contentName": "meta.url.bibtex", + "patterns": [ + { + "include": "#url_cmd" + } + ] + } + ] + }, + "percentage_comment": { + "patterns": [ + { + "begin": "(^[ \\t]+)?(?=%)", + "beginCaptures": { + "1": { + "name": "punctuation.whitespace.comment.leading.bibtex" + } + }, + "end": "(?!\\G)", + "patterns": [ + { + "begin": "%", + "beginCaptures": { + "0": { + "name": "punctuation.definition.comment.bibtex" + } + }, + "end": "$\\n?", + "name": "comment.line.percentage.bibtex" + } + ] + } + ] + }, + "url_cmd": { + "captures": { + "1": { + "name": "support.function.url.bibtex" + }, + "2": { + "name": "punctuation.definition.function.bibtex" + }, + "3": { + "name": "punctuation.definition.arguments.begin.bibtex" + }, + "4": { + "name": "markup.underline.link.bibtex" + }, + "5": { + "name": "punctuation.definition.arguments.end.bibtex" + } + }, + "match": "(?:\\s*)((\\\\)(?:url|href))(\\{)([^}]*)(\\})", + "name": "meta.function.link.url.bibtex" + }, + "url_field": { + "begin": "(url)\\s*(\\=)", + "beginCaptures": { + "1": { + "name": "support.function.key.bibtex" + }, + "2": { + "name": "punctuation.separator.key-value.bibtex" + } + }, + "end": "(?=[,}])", + "name": "meta.key-assignment.url.bibtex", + "patterns": [ + { + "include": "#string_url" + } + ] } } } \ No newline at end of file diff --git a/extensions/latex/syntaxes/LaTeX.tmLanguage.json b/extensions/latex/syntaxes/LaTeX.tmLanguage.json index bfce1b50e8f..945a803dbe9 100644 --- a/extensions/latex/syntaxes/LaTeX.tmLanguage.json +++ b/extensions/latex/syntaxes/LaTeX.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jlelong/vscode-latex-basics/commit/fcf4cca5b18a4c71ace161cf6af87cf6a50d9abd", + "version": "https://github.com/jlelong/vscode-latex-basics/commit/eed5b817b757aab3695af437409fcbfdd37bbc59", "name": "LaTeX", "scopeName": "text.tex.latex", "patterns": [ @@ -1064,7 +1064,7 @@ ] }, { - "begin": "((?:\\s*)\\\\begin\\{([a-z]*code(?:\\*)?)\\}(?:\\[.*\\])?(?:\\{.*\\})?)", + "begin": "((?:\\s*)\\\\begin\\{([a-zA-Z]*code(?:\\*)?)\\}(?:\\[.*\\])?(?:\\{.*\\})?)", "captures": { "1": { "patterns": [ @@ -1074,7 +1074,9 @@ ] } }, - "end": "(\\\\end\\{\\2\\}(?:\\s*\\n)?)" + "end": "(\\\\end\\{\\2\\}(?:\\s*\\n)?)", + "contentName": "meta.function.embedded.latex", + "name": "meta.embedded.block.generic.latex" }, { "begin": "((\\\\)addplot)(?:\\+?)((?:\\[[^\\[]*\\]))*\\s*(gnuplot)\\s*((?:\\[[^\\[]*\\]))*\\s*(\\{)", @@ -1684,7 +1686,7 @@ "name": "meta.scope.item.latex" }, { - "begin": "((\\\\)(?:[aA]uto|foot|full|no|ref|short|[tT]ext|[pP]aren|[sS]mart)?[cC]ite(?:al)?(?:p|s|t|author|year(?:par)?|title)?[ANP]*\\*?)((?:(?:\\([^\\)]*\\)){0,2}(?:\\[[^\\]]*\\]){0,2}\\{[\\w:.]*\\})*)(?:([<\\[])[^\\]<>]*([>\\]]))?(?:(\\[)[^\\]]*(\\]))?(\\{)", + "begin": "((\\\\)(?:[aA]uto|foot|full|no|ref|short|[tT]ext|[pP]aren|[sS]mart)?[cC]ite(?:al)?(?:p|s|t|author|year(?:par)?|title)?[ANP]*\\*?)((?:(?:\\([^\\)]*\\)){0,2}(?:\\[[^\\]]*\\]){0,2}\\{[\\p{Alphabetic}:.]*\\})*)(?:([<\\[])[^\\]<>]*([>\\]]))?(?:(\\[)[^\\]]*(\\]))?(\\{)", "captures": { "1": { "name": "keyword.control.cite.latex" @@ -1735,7 +1737,7 @@ "match": "((%).*)$" }, { - "match": "[\\w:.-]+", + "match": "[\\p{Alphabetic}:.-]+", "name": "constant.other.reference.citation.latex" } ] @@ -1762,7 +1764,7 @@ "name": "meta.citation.latex", "patterns": [ { - "match": "[\\w:.]+", + "match": "[\\p{Alphabetic}:.]+", "name": "constant.other.reference.citation.latex" } ] @@ -1789,7 +1791,7 @@ "name": "meta.reference.label.latex", "patterns": [ { - "match": "[a-zA-Z0-9\\.,:/*!^_-]", + "match": "[\\p{Alphabetic}\\p{Number}\\.,:/*!^_-]", "name": "constant.other.reference.label.latex" } ] @@ -2248,7 +2250,7 @@ ] } }, - "match": "(?:(\\()[^\\)]*(\\))){0,2}(?:(\\[)[^\\]]*(\\])){0,2}(\\{)([\\w:.]+)(\\})(.*)" + "match": "(?:(\\()[^\\)]*(\\))){0,2}(?:(\\[)[^\\]]*(\\])){0,2}(\\{)([\\p{Alphabetic}:.]+)(\\})(.*)" } ] }, diff --git a/extensions/latex/syntaxes/TeX.tmLanguage.json b/extensions/latex/syntaxes/TeX.tmLanguage.json index 4e3e4d697b5..22d47bc8ee1 100644 --- a/extensions/latex/syntaxes/TeX.tmLanguage.json +++ b/extensions/latex/syntaxes/TeX.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jlelong/vscode-latex-basics/commit/8776a0856846b63d9e5765e8ec42a8a2f4f52219", + "version": "https://github.com/jlelong/vscode-latex-basics/commit/890b6155b82b12c67b350aa99be5637eaa64f222", "name": "TeX", "scopeName": "text.tex", "patterns": [ @@ -14,7 +14,7 @@ "name": "punctuation.definition.keyword.tex" } }, - "match": "(\\\\)(backmatter|else|fi|frontmatter|mainmatter|if(case|cat|dim|eof|false|hbox|hmode|inner|mmode|num|odd|true|undefined|vbox|vmode|void|x)?)(?![a-zA-Z@])", + "match": "(\\\\)(backmatter|csname|else|endcsname|fi|frontmatter|mainmatter|unless|if(case|cat|csname|defined|dim|eof|false|fontchar|hbox|hmode|inner|mmode|num|odd|true|vbox|vmode|void|x)?)(?![a-zA-Z@])", "name": "keyword.control.tex" }, { @@ -176,7 +176,7 @@ "name": "punctuation.definition.constant.math.tex" } }, - "match": "(\\\\)(s(s(earrow|warrow|lash)|h(ort(downarrow|uparrow|parallel|leftarrow|rightarrow|mid)|arp)|tar|i(gma|m(eq)?)|u(cc(sim|n(sim|approx)|curlyeq|eq|approx)?|pset(neq(q)?|plus(eq)?|eq(q)?)?|rd|m|bset(neq(q)?|plus(eq)?|eq(q)?)?)|p(hericalangle|adesuit)|e(tminus|arrow)|q(su(pset(eq)?|bset(eq)?)|c(up|ap)|uare)|warrow|m(ile|all(s(etminus|mile)|frown)))|h(slash|ook(leftarrow|rightarrow)|eartsuit|bar)|R(sh|ightarrow|e|bag)|Gam(e|ma)|n(s(hort(parallel|mid)|im|u(cc(eq)?|pseteq(q)?|bseteq))|Rightarrow|n(earrow|warrow)|cong|triangle(left(eq(slant)?)?|right(eq(slant)?)?)|i(plus)?|u|p(lus|arallel|rec(eq)?)|e(q|arrow|g|xists)|v(dash|Dash)|warrow|le(ss|q(slant|q)?|ft(arrow|rightarrow))|a(tural|bla)|VDash|rightarrow|g(tr|eq(slant|q)?)|mid|Left(arrow|rightarrow))|c(hi|irc(eq|le(d(circ|S|dash|ast)|arrow(left|right)))?|o(ng|prod|lon|mplement)|dot(s|p)?|u(p|r(vearrow(left|right)|ly(eq(succ|prec)|vee(downarrow|uparrow)?|wedge(downarrow|uparrow)?)))|enterdot|lubsuit|ap)|Xi|Maps(to(char)?|from(char)?)|B(ox|umpeq|bbk)|t(h(ick(sim|approx)|e(ta|refore))|imes|op|wohead(leftarrow|rightarrow)|a(u|lloblong)|riangle(down|q|left(eq(slant)?)?|right(eq(slant)?)?)?)|i(n(t(er(cal|leave))?|plus|fty)?|ota|math)|S(igma|u(pset|bset))|zeta|o(slash|times|int|dot|plus|vee|wedge|lessthan|greaterthan|m(inus|ega)|b(slash|long|ar))|d(i(v(ideontimes)?|a(g(down|up)|mond(suit)?)|gamma)|o(t(plus|eq(dot)?)|ublebarwedge|wn(harpoon(left|right)|downarrows|arrow))|d(ots|agger)|elta|a(sh(v|leftarrow|rightarrow)|leth|gger))|Y(down|up|left|right)|C(up|ap)|u(n(lhd|rhd)|p(silon|harpoon(left|right)|downarrow|uparrows|lus|arrow)|lcorner|rcorner)|jmath|Theta|Im|p(si|hi|i(tchfork)?|erp|ar(tial|allel)|r(ime|o(d|pto)|ec(sim|n(sim|approx)|curlyeq|eq|approx)?)|m)|e(t(h|a)|psilon|q(slant(less|gtr)|circ|uiv)|ll|xists|mptyset)|Omega|D(iamond|ownarrow|elta)|v(d(ots|ash)|ee(bar)?|Dash|ar(s(igma|u(psetneq(q)?|bsetneq(q)?))|nothing|curly(vee|wedge)|t(heta|imes|riangle(left|right)?)|o(slash|circle|times|dot|plus|vee|wedge|lessthan|ast|greaterthan|minus|b(slash|ar))|p(hi|i|ropto)|epsilon|kappa|rho|bigcirc))|kappa|Up(silon|downarrow|arrow)|Join|f(orall|lat|a(t(s(emi|lash)|bslash)|llingdotseq)|rown)|P(si|hi|i)|w(p|edge|r)|l(hd|n(sim|eq(q)?|approx)|ceil|times|ightning|o(ng(left(arrow|rightarrow)|rightarrow|maps(to|from))|zenge|oparrow(left|right))|dot(s|p)|e(ss(sim|dot|eq(qgtr|gtr)|approx|gtr)|q(slant|q)?|ft(slice|harpoon(down|up)|threetimes|leftarrows|arrow(t(ail|riangle))?|right(squigarrow|harpoons|arrow(s|triangle|eq)?))|adsto)|vertneqq|floor|l(c(orner|eil)|floor|l|bracket)?|a(ngle|mbda)|rcorner|bag)|a(s(ymp|t)|ngle|pprox(eq)?|l(pha|eph)|rrownot|malg)|V(dash|vdash)|r(h(o|d)|ceil|times|i(singdotseq|ght(s(quigarrow|lice)|harpoon(down|up)|threetimes|left(harpoons|arrows)|arrow(t(ail|riangle))?|rightarrows))|floor|angle|r(ceil|parenthesis|floor|bracket)|bag)|g(n(sim|eq(q)?|approx)|tr(sim|dot|eq(qless|less)|less|approx)|imel|eq(slant|q)?|vertneqq|amma|g(g)?)|Finv|xi|m(ho|i(nuso|d)|o(o|dels)|u(ltimap)?|p|e(asuredangle|rge)|aps(to|from(char)?))|b(i(n(dnasrepma|ampersand)|g(s(tar|qc(up|ap))|nplus|c(irc|u(p|rly(vee|wedge))|ap)|triangle(down|up)|interleave|o(times|dot|plus)|uplus|parallel|vee|wedge|box))|o(t|wtie|x(slash|circle|times|dot|plus|empty|ast|minus|b(slash|ox|ar)))|u(llet|mpeq)|e(cause|t(h|ween|a))|lack(square|triangle(down|left|right)?|lozenge)|a(ck(s(im(eq)?|lash)|prime|epsilon)|r(o|wedge))|bslash)|L(sh|ong(left(arrow|rightarrow)|rightarrow|maps(to|from))|eft(arrow|rightarrow)|leftarrow|ambda|bag)|Arrownot)(?=\\b|_)", + "match": "(\\\\)(s(s(earrow|warrow|lash)|h(ort(downarrow|uparrow|parallel|leftarrow|rightarrow|mid)|arp)|tar|i(gma|m(eq)?)|u(cc(sim|n(sim|approx)|curlyeq|eq|approx)?|pset(neq(q)?|plus(eq)?|eq(q)?)?|rd|m|bset(neq(q)?|plus(eq)?|eq(q)?)?)|p(hericalangle|adesuit)|e(tminus|arrow)|q(su(pset(eq)?|bset(eq)?)|c(up|ap)|uare)|warrow|m(ile|all(s(etminus|mile)|frown)))|h(slash|ook(leftarrow|rightarrow)|eartsuit|bar)|R(sh|ightarrow|e|bag)|Gam(e|ma)|n(s(hort(parallel|mid)|im|u(cc(eq)?|pseteq(q)?|bseteq))|Rightarrow|n(earrow|warrow)|cong|triangle(left(eq(slant)?)?|right(eq(slant)?)?)|i(plus)?|u|p(lus|arallel|rec(eq)?)|e(q|arrow|g|xists)|v(dash|Dash)|warrow|le(ss|q(slant|q)?|ft(arrow|rightarrow))|a(tural|bla)|VDash|rightarrow|g(tr|eq(slant|q)?)|mid|Left(arrow|rightarrow))|c(hi|irc(eq|le(d(circ|S|dash|ast)|arrow(left|right)))?|o(ng|prod|lon|mplement)|dot(s|p)?|u(p|r(vearrow(left|right)|ly(eq(succ|prec)|vee(downarrow|uparrow)?|wedge(downarrow|uparrow)?)))|enterdot|lubsuit|ap)|Xi|Maps(to(char)?|from(char)?)|B(ox|umpeq|bbk)|t(h(ick(sim|approx)|e(ta|refore))|imes|op|wohead(leftarrow|rightarrow)|a(u|lloblong)|riangle(down|q|left(eq(slant)?)?|right(eq(slant)?)?)?)|i(n(t(er(cal|leave))?|plus|fty)?|ota|math)|S(igma|u(pset|bset))|zeta|o(slash|times|int|dot|plus|vee|wedge|lessthan|greaterthan|m(inus|ega)|b(slash|long|ar))|d(i(v(ideontimes)?|a(g(down|up)|mond(suit)?)|gamma)|o(t(plus|eq(dot)?)|ublebarwedge|wn(harpoon(left|right)|downarrows|arrow))|d(ots|agger)|elta|a(sh(v|leftarrow|rightarrow)|leth|gger))|Y(down|up|left|right)|C(up|ap)|u(n(lhd|rhd)|p(silon|harpoon(left|right)|downarrow|uparrows|lus|arrow)|lcorner|rcorner)|jmath|Theta|Im|p(si|hi|i(tchfork)?|erp|ar(tial|allel)|r(ime|o(d|pto)|ec(sim|n(sim|approx)|curlyeq|eq|approx)?)|m)|e(t(h|a)|psilon|q(slant(less|gtr)|circ|uiv)|ll|xists|mptyset)|Omega|D(iamond|ownarrow|elta)|v(d(ots|ash)|ee(bar)?|Dash|ar(s(igma|u(psetneq(q)?|bsetneq(q)?))|nothing|curly(vee|wedge)|t(heta|imes|riangle(left|right)?)|o(slash|circle|times|dot|plus|vee|wedge|lessthan|ast|greaterthan|minus|b(slash|ar))|p(hi|i|ropto)|epsilon|kappa|rho|bigcirc))|kappa|Up(silon|downarrow|arrow)|Join|f(orall|lat|a(t(s(emi|lash)|bslash)|llingdotseq)|rown)|P(si|hi|i)|w(p|edge|r)|l(hd|n(sim|eq(q)?|approx)|ceil|times|ightning|o(ng(left(arrow|rightarrow)|rightarrow|maps(to|from))|zenge|oparrow(left|right))|dot(s|p)|e(ss(sim|dot|eq(qgtr|gtr)|approx|gtr)|q(slant|q)?|ft(slice|harpoon(down|up)|threetimes|leftarrows|arrow(t(ail|riangle))?|right(squigarrow|harpoons|arrow(s|triangle|eq)?))|adsto)|vertneqq|floor|l(c(orner|eil)|floor|l|bracket)?|a(ngle|mbda)|rcorner|bag)|a(s(ymp|t)|ngle|pprox(eq)?|l(pha|eph)|rrownot|malg)|V(dash|vdash)|r(h(o|d)|ceil|times|i(singdotseq|ght(s(quigarrow|lice)|harpoon(down|up)|threetimes|left(harpoons|arrows)|arrow(t(ail|riangle))?|rightarrows))|floor|angle|r(ceil|parenthesis|floor|bracket)|bag)|g(n(sim|eq(q)?|approx)|tr(sim|dot|eq(qless|less)|less|approx)|imel|eq(slant|q)?|vertneqq|amma|g(g)?)|Finv|xi|m(ho|i(nuso|d)|o(o|dels)|u(ltimap)?|p|e(asuredangle|rge)|aps(to|from(char)?))|b(i(n(dnasrepma|ampersand)|g(s(tar|qc(up|ap))|nplus|c(irc|u(p|rly(vee|wedge))|ap)|triangle(down|up)|interleave|o(times|dot|plus)|uplus|parallel|vee|wedge|box))|o(t|wtie|x(slash|circle|times|dot|plus|empty|ast|minus|b(slash|ox|ar)))|u(llet|mpeq)|e(cause|t(h|ween|a))|lack(square|triangle(down|left|right)?|lozenge)|a(ck(s(im(eq)?|lash)|prime|epsilon)|r(o|wedge))|bslash)|L(sh|ong(left(arrow|rightarrow)|rightarrow|maps(to|from))|eft(arrow|rightarrow)|leftarrow|ambda|bag)|Arrownot)(?![a-zA-Z])", "name": "constant.character.math.tex" }, { diff --git a/extensions/lua/cgmanifest.json b/extensions/lua/cgmanifest.json index c1b98909447..d8e50c4e8c6 100644 --- a/extensions/lua/cgmanifest.json +++ b/extensions/lua/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "sumneko/lua.tmbundle", "repositoryUrl": "https://github.com/sumneko/lua.tmbundle", - "commitHash": "57be7c5cf8fa173f5f39806822725e503932ab45" + "commitHash": "dfdf6c33f33b7d478c474afbe1b6b3cd2e99b716" } }, "licenseDetail": [ diff --git a/extensions/lua/syntaxes/lua.tmLanguage.json b/extensions/lua/syntaxes/lua.tmLanguage.json index ac3de0811b3..8393d1a356e 100644 --- a/extensions/lua/syntaxes/lua.tmLanguage.json +++ b/extensions/lua/syntaxes/lua.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/sumneko/lua.tmbundle/commit/57be7c5cf8fa173f5f39806822725e503932ab45", + "version": "https://github.com/sumneko/lua.tmbundle/commit/dfdf6c33f33b7d478c474afbe1b6b3cd2e99b716", "name": "Lua", "scopeName": "source.lua", "patterns": [ @@ -77,7 +77,11 @@ ] }, { - "match": "(?('data-state') }; +if (typeof originalState.scrollProgress !== 'undefined' && originalState?.resource !== state.resource) { + state.scrollProgress = 0; +} + // Make sure to sync VS Code state here vscode.setState(state); @@ -62,7 +66,9 @@ onceDocumentLoaded(() => { if (typeof scrollProgress === 'number' && !settings.settings.fragment) { doAfterImagesLoaded(() => { scrollDisabledCount += 1; - window.scrollTo(0, scrollProgress * document.body.clientHeight); + // Always set scroll of at least 1 to prevent VS Code's webview code from auto scrolling us + const scrollToY = Math.max(1, scrollProgress * document.body.clientHeight); + window.scrollTo(0, scrollToY); }); return; } @@ -71,10 +77,16 @@ onceDocumentLoaded(() => { doAfterImagesLoaded(() => { // Try to scroll to fragment if available if (settings.settings.fragment) { + let fragment: string; + try { + fragment = encodeURIComponent(settings.settings.fragment); + } catch { + fragment = settings.settings.fragment; + } state.fragment = undefined; vscode.setState(state); - const element = getLineElementForFragment(settings.settings.fragment, documentVersion); + const element = getLineElementForFragment(fragment, documentVersion); if (element) { scrollDisabledCount += 1; scrollToRevealSourceLine(element.line, documentVersion, settings); @@ -114,16 +126,17 @@ window.addEventListener('resize', () => { }, true); window.addEventListener('message', async event => { - switch (event.data.type) { + const data = event.data as ToWebviewMessage.Type; + switch (data.type) { case 'onDidChangeTextEditorSelection': - if (event.data.source === documentResource) { - marker.onDidChangeTextEditorSelection(event.data.line, documentVersion); + if (data.source === documentResource) { + marker.onDidChangeTextEditorSelection(data.line, documentVersion); } return; case 'updateView': - if (event.data.source === documentResource) { - onUpdateView(event.data.line); + if (data.source === documentResource) { + onUpdateView(data.line); } return; @@ -131,7 +144,7 @@ window.addEventListener('message', async event => { const root = document.querySelector('.markdown-body')!; const parser = new DOMParser(); - const newContent = parser.parseFromString(event.data.content, 'text/html'); + const newContent = parser.parseFromString(data.content, 'text/html'); // Strip out meta http-equiv tags for (const metaElement of Array.from(newContent.querySelectorAll('meta'))) { @@ -140,11 +153,15 @@ window.addEventListener('message', async event => { } } - if (event.data.source !== documentResource) { + if (data.source !== documentResource) { root.replaceWith(newContent.querySelector('.markdown-body')!); - documentResource = event.data.source; + documentResource = data.source; } else { - // Compare two elements but skip `data-line` + const skippedAttrs = [ + 'open', // for details + ]; + + // Compare two elements but some elements const areEqual = (a: Element, b: Element): boolean => { if (a.isEqualNode(b)) { return true; @@ -154,8 +171,8 @@ window.addEventListener('message', async event => { return false; } - const aAttrs = a.attributes; - const bAttrs = b.attributes; + const aAttrs = [...a.attributes].filter(attr => !skippedAttrs.includes(attr.name)); + const bAttrs = [...b.attributes].filter(attr => !skippedAttrs.includes(attr.name)); if (aAttrs.length !== bAttrs.length) { return false; } @@ -186,15 +203,13 @@ window.addEventListener('message', async event => { style.remove(); } newRoot.prepend(...styles); - morphdom(root, newRoot, { childrenOnly: true, onBeforeElUpdated: (fromEl, toEl) => { if (areEqual(fromEl, toEl)) { - // areEqual doesn't look at `data-line` so copy those over - + // areEqual doesn't look at `data-line` so copy those over manually const fromLines = fromEl.querySelectorAll('[data-line]'); - const toLines = fromEl.querySelectorAll('[data-line]'); + const toLines = toEl.querySelectorAll('[data-line]'); if (fromLines.length !== toLines.length) { console.log('unexpected line number change'); } @@ -210,6 +225,12 @@ window.addEventListener('message', async event => { return false; } + if (fromEl.tagName === 'DETAILS' && toEl.tagName === 'DETAILS') { + if (fromEl.hasAttribute('open')) { + toEl.setAttribute('open', ''); + } + } + return true; } }); diff --git a/extensions/markdown-language-features/preview-src/messaging.ts b/extensions/markdown-language-features/preview-src/messaging.ts index 6452ae6c3c8..1fb29f0b55b 100644 --- a/extensions/markdown-language-features/preview-src/messaging.ts +++ b/extensions/markdown-language-features/preview-src/messaging.ts @@ -4,21 +4,28 @@ *--------------------------------------------------------------------------------------------*/ import { SettingsManager } from './settings'; +import type { FromWebviewMessage } from '../types/previewMessaging'; export interface MessagePoster { /** * Post a message to the markdown extension */ - postMessage(type: string, body: object): void; + postMessage( + type: T['type'], + body: Omit + ): void; } -export const createPosterForVsCode = (vscode: any, settingsManager: SettingsManager) => { - return new class implements MessagePoster { - postMessage(type: string, body: object): void { +export const createPosterForVsCode = (vscode: any, settingsManager: SettingsManager): MessagePoster => { + return { + postMessage( + type: T['type'], + body: Omit + ): void { vscode.postMessage({ type, source: settingsManager.settings!.source, - body + ...body }); } }; diff --git a/extensions/markdown-language-features/preview-src/scroll-sync.ts b/extensions/markdown-language-features/preview-src/scroll-sync.ts index 54921b45894..a884730a152 100644 --- a/extensions/markdown-language-features/preview-src/scroll-sync.ts +++ b/extensions/markdown-language-features/preview-src/scroll-sync.ts @@ -8,10 +8,20 @@ import { SettingsManager } from './settings'; const codeLineClass = 'code-line'; -export interface CodeLineElement { - element: HTMLElement; - line: number; - codeElement?: HTMLElement; +export class CodeLineElement { + private readonly _detailParentElements: readonly HTMLDetailsElement[]; + + constructor( + readonly element: HTMLElement, + readonly line: number, + readonly codeElement?: HTMLElement, + ) { + this._detailParentElements = Array.from(getParentsWithTagName(element, 'DETAILS')); + } + + get isVisible(): boolean { + return !this._detailParentElements.some(x => !x.open); + } } const getCodeLineElements = (() => { @@ -20,21 +30,26 @@ const getCodeLineElements = (() => { return (documentVersion: number) => { if (!cachedElements || documentVersion !== cachedVersion) { cachedVersion = documentVersion; - cachedElements = [{ element: document.body, line: -1 }]; + cachedElements = [new CodeLineElement(document.body, -1)]; for (const element of document.getElementsByClassName(codeLineClass)) { + if (!(element instanceof HTMLElement)) { + continue; + } + const line = +element.getAttribute('data-line')!; if (isNaN(line)) { continue; } + if (element.tagName === 'CODE' && element.parentElement && element.parentElement.tagName === 'PRE') { // Fenced code blocks are a special case since the `code-line` can only be marked on // the `` element and not the parent `

` element.
-					cachedElements.push({ element: element.parentElement as HTMLElement, line: line, codeElement: element as HTMLElement });
+					cachedElements.push(new CodeLineElement(element.parentElement, line, element));
 				} else if (element.tagName === 'UL' || element.tagName === 'OL') {
 					// Skip adding list elements since the first child has the same code line (and should be preferred)
 				} else {
-					cachedElements.push({ element: element as HTMLElement, line });
+					cachedElements.push(new CodeLineElement(element, line));
 				}
 			}
 		}
@@ -67,7 +82,7 @@ export function getElementsForSourceLine(targetLine: number, documentVersion: nu
  * Find the html elements that are at a specific pixel offset on the page.
  */
 export function getLineElementsAtPageOffset(offset: number, documentVersion: number): { previous: CodeLineElement; next?: CodeLineElement } {
-	const lines = getCodeLineElements(documentVersion);
+	const lines = getCodeLineElements(documentVersion).filter(x => x.isVisible);
 	const position = offset - window.scrollY;
 	let lo = -1;
 	let hi = lines.length - 1;
@@ -145,9 +160,12 @@ export function scrollToRevealSourceLine(line: number, documentVersion: number,
 	window.scroll(window.scrollX, Math.max(1, window.scrollY + scrollTo));
 }
 
-export function getEditorLineNumberForPageOffset(offset: number, documentVersion: number) {
+export function getEditorLineNumberForPageOffset(offset: number, documentVersion: number): number | null {
 	const { previous, next } = getLineElementsAtPageOffset(offset, documentVersion);
 	if (previous) {
+		if (previous.line < 0) {
+			return 0;
+		}
 		const previousBounds = getElementBounds(previous);
 		const offsetFromPrevious = (offset - window.scrollY - previousBounds.top);
 		if (next) {
@@ -169,3 +187,11 @@ export function getLineElementForFragment(fragment: string, documentVersion: num
 		return element.element.id === fragment;
 	});
 }
+
+function* getParentsWithTagName(element: HTMLElement, tagName: string): Iterable {
+	for (let parent = element.parentElement; parent; parent = parent.parentElement) {
+		if (parent.tagName === tagName) {
+			yield parent as T;
+		}
+	}
+}
diff --git a/extensions/markdown-language-features/server/CHANGELOG.md b/extensions/markdown-language-features/server/CHANGELOG.md
new file mode 100644
index 00000000000..98ac9c98688
--- /dev/null
+++ b/extensions/markdown-language-features/server/CHANGELOG.md
@@ -0,0 +1,2 @@
+# 0.3.0 - March 28, 2023
+- Pick up [Markdown Language Service](https://github.com/microsoft/vscode-markdown-languageservice) 0.3.0. See [CHANGELOG](https://github.com/microsoft/vscode-markdown-languageservice/blob/main/CHANGELOG.md#030--march-16-2023) for details.
diff --git a/extensions/markdown-language-features/server/build/pipeline.yml b/extensions/markdown-language-features/server/build/pipeline.yml
new file mode 100644
index 00000000000..4e58aa31f02
--- /dev/null
+++ b/extensions/markdown-language-features/server/build/pipeline.yml
@@ -0,0 +1,33 @@
+name: $(Date:yyyyMMdd)$(Rev:.r)
+
+trigger: none
+pr: none
+
+resources:
+  repositories:
+    - repository: templates
+      type: github
+      name: microsoft/vscode-engineering
+      ref: main
+      endpoint: Monaco
+
+parameters:
+  - name: publishPackage
+    displayName: Publish vscode-markdown-languageserver
+    type: boolean
+    default: false
+
+extends:
+  template: azure-pipelines/npm-package/pipeline.yml@templates
+  parameters:
+    npmPackages:
+      - name: vscode-markdown-languageserver
+
+        buildSteps:
+          - script: yarn install
+            displayName: Install dependencies
+
+          - script: gulp compile-extension:markdown-language-features-server
+            displayName: Compile
+
+        publishPackage: ${{ parameters.publishPackage }}
diff --git a/extensions/markdown-language-features/server/package.json b/extensions/markdown-language-features/server/package.json
index 27d09b94257..e9464e843c9 100644
--- a/extensions/markdown-language-features/server/package.json
+++ b/extensions/markdown-language-features/server/package.json
@@ -1,7 +1,7 @@
 {
   "name": "vscode-markdown-languageserver",
   "description": "Markdown language server",
-  "version": "0.3.0-alpha.4",
+  "version": "0.3.0",
   "author": "Microsoft Corporation",
   "license": "MIT",
   "engines": {
@@ -18,7 +18,7 @@
     "vscode-languageserver": "^8.0.2",
     "vscode-languageserver-textdocument": "^1.0.5",
     "vscode-languageserver-types": "^3.17.1",
-    "vscode-markdown-languageservice": "^0.3.0-alpha.4",
+    "vscode-markdown-languageservice": "^0.3.0",
     "vscode-uri": "^3.0.3"
   },
   "devDependencies": {
diff --git a/extensions/markdown-language-features/server/src/configuration.ts b/extensions/markdown-language-features/server/src/configuration.ts
index b71cff5d416..949573cfaf5 100644
--- a/extensions/markdown-language-features/server/src/configuration.ts
+++ b/extensions/markdown-language-features/server/src/configuration.ts
@@ -10,6 +10,12 @@ export type ValidateEnabled = 'ignore' | 'warning' | 'error' | 'hint';
 
 export interface Settings {
 	readonly markdown: {
+		readonly server: {
+			readonly log: 'off' | 'debug' | 'trace';
+		};
+
+		readonly preferredMdPathExtensionStyle: 'auto' | 'includeExtension' | 'removeExtension';
+
 		readonly occurrencesHighlight: {
 			readonly enabled: boolean;
 		};
diff --git a/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts b/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts
index 0f7e6954dbc..d21a6fdbfb6 100644
--- a/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts
+++ b/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts
@@ -73,7 +73,7 @@ export function registerValidateSupport(
 	const emptyDiagnosticsResponse = Object.freeze({ kind: 'full', items: [] });
 
 	connection.languages.diagnostics.on(async (params, token): Promise => {
-		logger.log(md.LogLevel.Trace, 'Server: connection.languages.diagnostics.on', params.textDocument.uri);
+		logger.log(md.LogLevel.Debug, 'connection.languages.diagnostics.on', { document: params.textDocument.uri });
 
 		if (!config.getSettings()?.markdown.validate.enabled) {
 			return emptyDiagnosticsResponse;
diff --git a/extensions/markdown-language-features/server/src/logging.ts b/extensions/markdown-language-features/server/src/logging.ts
index 2fc08c25b7a..0df6b8e0cc5 100644
--- a/extensions/markdown-language-features/server/src/logging.ts
+++ b/extensions/markdown-language-features/server/src/logging.ts
@@ -3,9 +3,11 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-import { ILogger, LogLevel } from 'vscode-markdown-languageservice';
+import * as md from 'vscode-markdown-languageservice';
+import { ConfigurationManager } from './configuration';
+import { Disposable } from './util/dispose';
 
-export class LogFunctionLogger implements ILogger {
+export class LogFunctionLogger extends Disposable implements md.ILogger {
 
 	private static now(): string {
 		const now = new Date();
@@ -27,21 +29,53 @@ export class LogFunctionLogger implements ILogger {
 		return JSON.stringify(data, undefined, 2);
 	}
 
+	private _logLevel: md.LogLevel;
+
 	constructor(
-		private readonly _logFn: typeof console.log
-	) { }
+		private readonly _logFn: typeof console.log,
+		private readonly _config: ConfigurationManager,
+	) {
+		super();
 
+		this._register(this._config.onDidChangeConfiguration(() => {
+			this._logLevel = LogFunctionLogger.readLogLevel(this._config);
+		}));
 
-	public log(level: LogLevel, title: string, message: string, data?: any): void {
-		this.appendLine(`[${level} ${LogFunctionLogger.now()}] ${title}: ${message}`);
+		this._logLevel = LogFunctionLogger.readLogLevel(this._config);
+	}
+
+	private static readLogLevel(config: ConfigurationManager): md.LogLevel {
+		switch (config.getSettings()?.markdown.server.log) {
+			case 'trace': return md.LogLevel.Trace;
+			case 'debug': return md.LogLevel.Debug;
+			case 'off':
+			default:
+				return md.LogLevel.Off;
+		}
+	}
+
+	get level(): md.LogLevel { return this._logLevel; }
+
+	public log(level: md.LogLevel, message: string, data?: any): void {
+		if (this.level < level) {
+			return;
+		}
+
+		this.appendLine(`[${this.toLevelLabel(level)} ${LogFunctionLogger.now()}] ${message}`);
 		if (data) {
 			this.appendLine(LogFunctionLogger.data2String(data));
 		}
 	}
 
+	private toLevelLabel(level: md.LogLevel): string {
+		switch (level) {
+			case md.LogLevel.Off: return 'Off';
+			case md.LogLevel.Debug: return 'Debug';
+			case md.LogLevel.Trace: return 'Trace';
+		}
+	}
+
 	private appendLine(value: string): void {
 		this._logFn(value);
 	}
 }
-
-export const consoleLogger = new LogFunctionLogger(console.log);
diff --git a/extensions/markdown-language-features/server/src/server.ts b/extensions/markdown-language-features/server/src/server.ts
index a3f62c4ab2e..1c379c90a8f 100644
--- a/extensions/markdown-language-features/server/src/server.ts
+++ b/extensions/markdown-language-features/server/src/server.ts
@@ -22,7 +22,8 @@ interface MdServerInitializationOptions extends LsConfiguration { }
 const organizeLinkDefKind = 'source.organizeLinkDefinitions';
 
 export async function startVsCodeServer(connection: Connection) {
-	const logger = new LogFunctionLogger(connection.console.log.bind(connection.console));
+	const configurationManager = new ConfigurationManager(connection);
+	const logger = new LogFunctionLogger(connection.console.log.bind(connection.console), configurationManager);
 
 	const parser = new class implements md.IMdParser {
 		slugifier = md.githubSlugifier;
@@ -41,7 +42,7 @@ export async function startVsCodeServer(connection: Connection) {
 		return workspace;
 	};
 
-	return startServer(connection, { documents, notebooks, logger, parser, workspaceFactory });
+	return startServer(connection, { documents, notebooks, configurationManager, logger, parser, workspaceFactory });
 }
 
 type WorkspaceFactory = (config: {
@@ -53,6 +54,7 @@ type WorkspaceFactory = (config: {
 export async function startServer(connection: Connection, serverConfig: {
 	documents: TextDocuments;
 	notebooks?: NotebookDocuments;
+	configurationManager: ConfigurationManager;
 	logger: md.ILogger;
 	parser: md.IMdParser;
 	workspaceFactory: WorkspaceFactory;
@@ -63,22 +65,29 @@ export async function startServer(connection: Connection, serverConfig: {
 
 	connection.onInitialize((params: InitializeParams): InitializeResult => {
 		const initOptions = params.initializationOptions as MdServerInitializationOptions | undefined;
-		const config = getLsConfiguration(initOptions ?? {});
 
-		const configurationManager = new ConfigurationManager(connection);
+		const mdConfig = getLsConfiguration(initOptions ?? {});
 
-		const workspace = serverConfig.workspaceFactory({ connection, config, workspaceFolders: params.workspaceFolders });
+		const workspace = serverConfig.workspaceFactory({ connection, config: mdConfig, workspaceFolders: params.workspaceFolders });
 		mdLs = md.createLanguageService({
 			workspace,
 			parser: serverConfig.parser,
 			logger: serverConfig.logger,
-			markdownFileExtensions: config.markdownFileExtensions,
-			excludePaths: config.excludePaths,
+			...mdConfig,
+			get preferredMdPathExtensionStyle() {
+				switch (serverConfig.configurationManager.getSettings()?.markdown.preferredMdPathExtensionStyle) {
+					case 'includeExtension': return md.PreferredMdPathExtensionStyle.includeExtension;
+					case 'removeExtension': return md.PreferredMdPathExtensionStyle.removeExtension;
+					case 'auto':
+					default:
+						return md.PreferredMdPathExtensionStyle.auto;
+				}
+			}
 		});
 
-		registerCompletionsSupport(connection, documents, mdLs, configurationManager);
-		registerDocumentHighlightSupport(connection, documents, mdLs, configurationManager);
-		registerValidateSupport(connection, workspace, documents, mdLs, configurationManager, serverConfig.logger);
+		registerCompletionsSupport(connection, documents, mdLs, serverConfig.configurationManager);
+		registerDocumentHighlightSupport(connection, documents, mdLs, serverConfig.configurationManager);
+		registerValidateSupport(connection, workspace, documents, mdLs, serverConfig.configurationManager, serverConfig.logger);
 
 		return {
 			capabilities: {
diff --git a/extensions/markdown-language-features/server/src/workspace.ts b/extensions/markdown-language-features/server/src/workspace.ts
index 17a66cc7f60..10d725530b5 100644
--- a/extensions/markdown-language-features/server/src/workspace.ts
+++ b/extensions/markdown-language-features/server/src/workspace.ts
@@ -116,7 +116,7 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching {
 				return;
 			}
 
-			this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: TextDocument.onDidOpen', `${e.document.uri}`);
+			this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace.TextDocument.onDidOpen', { document: e.document.uri });
 
 			const uri = URI.parse(e.document.uri);
 			const doc = this._documentCache.get(uri);
@@ -141,7 +141,7 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching {
 				return;
 			}
 
-			this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: TextDocument.onDidChanceContent', `${e.document.uri}`);
+			this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace.TextDocument.onDidChanceContent', { document: e.document.uri });
 
 			const uri = URI.parse(e.document.uri);
 			const entry = this._documentCache.get(uri);
@@ -156,7 +156,7 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching {
 				return;
 			}
 
-			this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: TextDocument.onDidClose', `${e.document.uri}`);
+			this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace.TextDocument.onDidClose', { document: e.document.uri });
 
 			const uri = URI.parse(e.document.uri);
 			const doc = this._documentCache.get(uri);
@@ -191,7 +191,7 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching {
 		connection.onDidChangeWatchedFiles(async ({ changes }) => {
 			for (const change of changes) {
 				const resource = URI.parse(change.uri);
-				this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: onDidChangeWatchedFiles', `${change.type}: ${resource}`);
+				this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace.onDidChangeWatchedFiles', { type: change.type, resource });
 				switch (change.type) {
 					case FileChangeType.Changed: {
 						const entry = this._documentCache.get(resource);
@@ -230,7 +230,7 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching {
 		});
 
 		connection.onRequest(protocol.fs_watcher_onChange, params => {
-			this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: fs_watcher_onChange', `${params.kind}: ${params.uri}`);
+			this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace.fs_watcher_onChange', { kind: params.kind, uri: params.uri });
 
 			const watcher = this._watchers.get(params.id);
 			if (!watcher) {
@@ -342,7 +342,7 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching {
 	}
 
 	async stat(resource: URI): Promise {
-		this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: stat', `${resource}`);
+		this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace.stat', { resource });
 		if (this._documentCache.has(resource)) {
 			return { isDirectory: false };
 		}
@@ -359,7 +359,7 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching {
 	}
 
 	async readDirectory(resource: URI): Promise<[string, md.FileStat][]> {
-		this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: readDir', `${resource}`);
+		this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace.readDir', { resource });
 		return this.connection.sendRequest(protocol.fs_readDirectory, { uri: resource.toString() });
 	}
 
@@ -378,7 +378,7 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching {
 
 	watchFile(resource: URI, options: md.FileWatcherOptions): md.IFileSystemWatcher {
 		const id = this._watcherPool++;
-		this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: watchFile', `(${id}) ${resource}`);
+		this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace.watchFile', { id, resource });
 
 		const entry = {
 			resource,
@@ -401,7 +401,7 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching {
 			onDidChange: entry.onDidChange.event,
 			onDidDelete: entry.onDidDelete.event,
 			dispose: () => {
-				this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: disposeWatcher', `(${id}) ${resource}`);
+				this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace.disposeWatcher', { id, resource });
 				this.connection.sendRequest(protocol.fs_watcher_delete, { id });
 				this._watchers.delete(id);
 			}
@@ -413,7 +413,7 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching {
 	}
 
 	private doDeleteDocument(uri: URI) {
-		this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: deleteDocument', `${uri}`);
+		this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace.deleteDocument', { document: uri });
 
 		this._documentCache.delete(uri);
 		this._onDidDeleteMarkdownDocument.fire(uri);
diff --git a/extensions/markdown-language-features/server/yarn.lock b/extensions/markdown-language-features/server/yarn.lock
index a08e3800d89..734f974e51c 100644
--- a/extensions/markdown-language-features/server/yarn.lock
+++ b/extensions/markdown-language-features/server/yarn.lock
@@ -52,10 +52,10 @@ vscode-languageserver@^8.0.2:
   dependencies:
     vscode-languageserver-protocol "3.17.2"
 
-vscode-markdown-languageservice@^0.3.0-alpha.4:
-  version "0.3.0-alpha.4"
-  resolved "https://registry.yarnpkg.com/vscode-markdown-languageservice/-/vscode-markdown-languageservice-0.3.0-alpha.4.tgz#59cc97102d6d0177a028b320fa76fe86d294cdb0"
-  integrity sha512-wMstTLuX3F+BkjxXCY4d1xKzHyBTHTC2EECg701FpBbSppa17Zj/Hk2G9H1dZGXhQeexXifxVXKScbLD6cB/3g==
+vscode-markdown-languageservice@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/vscode-markdown-languageservice/-/vscode-markdown-languageservice-0.3.0.tgz#4d2ed4aca2921392bfaaf982cc109b0b6a539d9f"
+  integrity sha512-+HGaZSsZGHbNdDyjfdkDws9a9oiqUsfnW5AtZQpgcxCavP5Gwom77S4XXzL/uEUUZ5u1K/0VTOhqha7qPcCW5w==
   dependencies:
     "@vscode/l10n" "^0.0.10"
     picomatch "^2.3.1"
diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropIntoEditor.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropIntoEditor.ts
index e91d9d11008..5c7e04711ae 100644
--- a/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropIntoEditor.ts
+++ b/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropIntoEditor.ts
@@ -45,7 +45,7 @@ export async function tryGetUriListSnippet(document: vscode.TextDocument, dataTr
 	}
 
 	const uris: vscode.Uri[] = [];
-	for (const resource of urlList.split('\n')) {
+	for (const resource of urlList.split(/\r?\n/g)) {
 		try {
 			uris.push(vscode.Uri.parse(resource));
 		} catch {
diff --git a/extensions/markdown-language-features/src/markdownEngine.ts b/extensions/markdown-language-features/src/markdownEngine.ts
index c0fe501e692..282cef1548d 100644
--- a/extensions/markdown-language-features/src/markdownEngine.ts
+++ b/extensions/markdown-language-features/src/markdownEngine.ts
@@ -412,6 +412,9 @@ async function getMarkdownOptions(md: () => MarkdownIt): Promise;
 }
 
+export interface ImageInfo {
+	readonly id: string;
+	readonly width: number;
+	readonly height: number;
+}
 
 export class MdDocumentRenderer {
 	constructor(
@@ -57,6 +62,7 @@ export class MdDocumentRenderer {
 		initialLine: number | undefined,
 		selectedLine: number | undefined,
 		state: any | undefined,
+		imageInfo: readonly ImageInfo[],
 		token: vscode.CancellationToken
 	): Promise {
 		const sourceUri = markdownDocument.uri;
@@ -94,7 +100,7 @@ export class MdDocumentRenderer {
 					data-strings="${escapeAttribute(JSON.stringify(previewStrings))}"
 					data-state="${escapeAttribute(JSON.stringify(state || {}))}">
 				
-				${this._getStyles(resourceProvider, sourceUri, config, state)}
+				${this._getStyles(resourceProvider, sourceUri, config, imageInfo)}
 				
 			
 			
@@ -180,22 +186,24 @@ export class MdDocumentRenderer {
 		].join(' ');
 	}
 
-	private _getImageStabilizerStyles(state?: any) {
+	private _getImageStabilizerStyles(imageInfo: readonly ImageInfo[]): string {
+		if (!imageInfo.length) {
+			return '';
+		}
+
 		let ret = '\n';
 
 		return ret;
 	}
 
-	private _getStyles(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration, state?: any): string {
+	private _getStyles(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration, imageInfo: readonly ImageInfo[]): string {
 		const baseStyles: string[] = [];
 		for (const resource of this._contributionProvider.contributions.previewStyles) {
 			baseStyles.push(``);
@@ -203,7 +211,7 @@ export class MdDocumentRenderer {
 
 		return `${baseStyles.join('\n')}
 			${this._computeCustomStyleSheetIncludes(resourceProvider, resource, config)}
-			${this._getImageStabilizerStyles(state)}`;
+			${this._getImageStabilizerStyles(imageInfo)}`;
 	}
 
 	private _getScripts(resourceProvider: WebviewResourceProvider, nonce: string): string {
diff --git a/extensions/markdown-language-features/src/preview/preview.ts b/extensions/markdown-language-features/src/preview/preview.ts
index 3d04c6db309..828442a76e5 100644
--- a/extensions/markdown-language-features/src/preview/preview.ts
+++ b/extensions/markdown-language-features/src/preview/preview.ts
@@ -12,52 +12,11 @@ import { isMarkdownFile } from '../util/file';
 import { MdLinkOpener } from '../util/openDocumentLink';
 import { WebviewResourceProvider } from '../util/resources';
 import { urlToUri } from '../util/url';
-import { MdDocumentRenderer } from './documentRenderer';
+import { ImageInfo, MdDocumentRenderer } from './documentRenderer';
 import { MarkdownPreviewConfigurationManager } from './previewConfig';
 import { scrollEditorToLine, StartingScrollFragment, StartingScrollLine, StartingScrollLocation } from './scrolling';
 import { getVisibleLine, LastScrollLocation, TopmostLineMonitor } from './topmostLineMonitor';
-
-
-interface WebviewMessage {
-	readonly source: string;
-}
-
-interface CacheImageSizesMessage extends WebviewMessage {
-	readonly type: 'cacheImageSizes';
-	readonly body: { id: string; width: number; height: number }[];
-}
-
-interface RevealLineMessage extends WebviewMessage {
-	readonly type: 'revealLine';
-	readonly body: {
-		readonly line: number;
-	};
-}
-
-interface DidClickMessage extends WebviewMessage {
-	readonly type: 'didClick';
-	readonly body: {
-		readonly line: number;
-	};
-}
-
-interface ClickLinkMessage extends WebviewMessage {
-	readonly type: 'openLink';
-	readonly body: {
-		readonly href: string;
-	};
-}
-
-interface ShowPreviewSecuritySelectorMessage extends WebviewMessage {
-	readonly type: 'showPreviewSecuritySelector';
-}
-
-interface PreviewStyleLoadErrorMessage extends WebviewMessage {
-	readonly type: 'previewStyleLoadError';
-	readonly body: {
-		readonly unloadedStyles: string[];
-	};
-}
+import type { FromWebviewMessage, ToWebviewMessage } from '../../types/previewMessaging';
 
 export class PreviewDocumentVersion {
 
@@ -78,10 +37,9 @@ export class PreviewDocumentVersion {
 interface MarkdownPreviewDelegate {
 	getTitle?(resource: vscode.Uri): string;
 	getAdditionalState(): {};
-	openPreviewLinkToMarkdownFile(markdownLink: vscode.Uri, fragment: string): void;
+	openPreviewLinkToMarkdownFile(markdownLink: vscode.Uri, fragment: string | undefined): void;
 }
 
-
 class MarkdownPreview extends Disposable implements WebviewResourceProvider {
 
 	private static readonly _unwatchedImageSchemes = new Set(['https', 'http', 'data']);
@@ -100,7 +58,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
 	private _currentVersion?: PreviewDocumentVersion;
 	private _isScrolling = false;
 
-	private _imageInfo: { readonly id: string; readonly width: number; readonly height: number }[] = [];
+	private _imageInfo: readonly ImageInfo[] = [];
 	private readonly _fileWatchersBySrc = new Map();
 
 	private readonly _onScrollEmitter = this._register(new vscode.EventEmitter());
@@ -162,26 +120,26 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
 			}
 		}));
 
-		this._register(this._webviewPanel.webview.onDidReceiveMessage((e: CacheImageSizesMessage | RevealLineMessage | DidClickMessage | ClickLinkMessage | ShowPreviewSecuritySelectorMessage | PreviewStyleLoadErrorMessage) => {
+		this._register(this._webviewPanel.webview.onDidReceiveMessage((e: FromWebviewMessage.Type) => {
 			if (e.source !== this._resource.toString()) {
 				return;
 			}
 
 			switch (e.type) {
 				case 'cacheImageSizes':
-					this._imageInfo = e.body;
+					this._imageInfo = e.imageData;
 					break;
 
 				case 'revealLine':
-					this._onDidScrollPreview(e.body.line);
+					this._onDidScrollPreview(e.line);
 					break;
 
 				case 'didClick':
-					this._onDidClickPreview(e.body.line);
+					this._onDidClickPreview(e.line);
 					break;
 
 				case 'openLink':
-					this._onDidClickPreviewLink(e.body.href);
+					this._onDidClickPreviewLink(e.href);
 					break;
 
 				case 'showPreviewSecuritySelector':
@@ -190,7 +148,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
 
 				case 'previewStyleLoadError':
 					vscode.window.showWarningMessage(
-						vscode.l10n.t("Could not load 'markdown.styles': {0}", e.body.unloadedStyles.join(', ')));
+						vscode.l10n.t("Could not load 'markdown.styles': {0}", e.unloadedStyles.join(', ')));
 					break;
 			}
 		}));
@@ -220,7 +178,6 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
 		return {
 			resource: this._resource.toString(),
 			line: this._line,
-			imageInfo: this._imageInfo,
 			fragment: this._scrollToFragment,
 			...this._delegate.getAdditionalState(),
 		};
@@ -248,7 +205,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
 		return this._resource.fsPath === resource.fsPath;
 	}
 
-	public postMessage(msg: any) {
+	public postMessage(msg: ToWebviewMessage.Type) {
 		if (!this._disposed) {
 			this._webviewPanel.webview.postMessage(msg);
 		}
@@ -315,7 +272,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
 		}
 
 		const content = await (shouldReloadPage
-			? this._contentProvider.renderDocument(document, this, this._previewConfigurations, this._line, selectedLine, this.state, this._disposeCts.token)
+			? this._contentProvider.renderDocument(document, this, this._previewConfigurations, this._line, selectedLine, this.state, this._imageInfo, this._disposeCts.token)
 			: this._contentProvider.renderBody(document, this));
 
 		// Another call to `doUpdate` may have happened.
@@ -389,7 +346,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
 		if (reloadPage) {
 			this._webviewPanel.webview.html = html;
 		} else {
-			this._webviewPanel.webview.postMessage({
+			this.postMessage({
 				type: 'updateContent',
 				content: html,
 				source: this._resource.toString(),
@@ -453,7 +410,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
 				try {
 					const doc = await vscode.workspace.openTextDocument(vscode.Uri.from(resolved.uri));
 					if (isMarkdownFile(doc)) {
-						return this._delegate.openPreviewLinkToMarkdownFile(doc.uri, resolved.fragment ?? '');
+						return this._delegate.openPreviewLinkToMarkdownFile(doc.uri, resolved.fragment ? decodeURIComponent(resolved.fragment) : undefined);
 					}
 				} catch {
 					// Noop
diff --git a/extensions/markdown-language-features/src/preview/previewManager.ts b/extensions/markdown-language-features/src/preview/previewManager.ts
index dc4d311a96d..7f6de5023b3 100644
--- a/extensions/markdown-language-features/src/preview/previewManager.ts
+++ b/extensions/markdown-language-features/src/preview/previewManager.ts
@@ -236,6 +236,7 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
 			lineNumber
 		);
 		this._registerStaticPreview(preview);
+		this._activePreview = preview;
 	}
 
 	private _createNewDynamicPreview(
diff --git a/extensions/markdown-language-features/src/preview/scrolling.ts b/extensions/markdown-language-features/src/preview/scrolling.ts
index cb807893266..aa0798fb747 100644
--- a/extensions/markdown-language-features/src/preview/scrolling.ts
+++ b/extensions/markdown-language-features/src/preview/scrolling.ts
@@ -16,6 +16,7 @@ export function scrollEditorToLine(
 }
 
 function toRevealRange(line: number, editor: vscode.TextEditor): vscode.Range {
+	line = Math.max(0, line);
 	const sourceLine = Math.floor(line);
 	if (sourceLine >= editor.document.lineCount) {
 		return new vscode.Range(editor.document.lineCount - 1, 0, editor.document.lineCount - 1, 0);
diff --git a/extensions/markdown-language-features/src/util/openDocumentLink.ts b/extensions/markdown-language-features/src/util/openDocumentLink.ts
index f29661571a5..4fc423d3675 100644
--- a/extensions/markdown-language-features/src/util/openDocumentLink.ts
+++ b/extensions/markdown-language-features/src/util/openDocumentLink.ts
@@ -37,6 +37,18 @@ export class MdLinkOpener {
 				return vscode.commands.executeCommand('revealInExplorer', uri);
 
 			case 'file': {
+				// If no explicit viewColumn is given, check if the editor is already open in a tab
+				if (typeof viewColumn === 'undefined') {
+					for (const tab of vscode.window.tabGroups.all.flatMap(x => x.tabs)) {
+						if (tab.input instanceof vscode.TabInputText) {
+							if (tab.input.uri.fsPath === uri.fsPath) {
+								viewColumn = tab.group.viewColumn;
+								break;
+							}
+						}
+					}
+				}
+
 				return vscode.commands.executeCommand('vscode.open', uri, {
 					selection: resolved.position ? new vscode.Range(resolved.position.line, resolved.position.character, resolved.position.line, resolved.position.character) : undefined,
 					viewColumn: viewColumn ?? getViewColumn(fromResource),
diff --git a/extensions/markdown-language-features/types/previewMessaging.d.ts b/extensions/markdown-language-features/types/previewMessaging.d.ts
new file mode 100644
index 00000000000..ee8f91f596f
--- /dev/null
+++ b/extensions/markdown-language-features/types/previewMessaging.d.ts
@@ -0,0 +1,73 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+interface BaseMessage {
+	readonly source: string;
+}
+
+export namespace FromWebviewMessage {
+
+	export interface CacheImageSizes extends BaseMessage {
+		readonly type: 'cacheImageSizes';
+		readonly imageData: ReadonlyArray<{ id: string; width: number; height: number }>;
+	}
+
+	export interface RevealLine extends BaseMessage {
+		readonly type: 'revealLine';
+		readonly line: number;
+	}
+
+	export interface DidClick extends BaseMessage {
+		readonly type: 'didClick';
+		readonly line: number;
+	}
+
+	export interface ClickLink extends BaseMessage {
+		readonly type: 'openLink';
+		readonly href: string;
+	}
+
+	export interface ShowPreviewSecuritySelector extends BaseMessage {
+		readonly type: 'showPreviewSecuritySelector';
+	}
+
+	export interface PreviewStyleLoadError extends BaseMessage {
+		readonly type: 'previewStyleLoadError';
+		readonly unloadedStyles: readonly string[];
+	}
+
+	export type Type =
+		| CacheImageSizes
+		| RevealLine
+		| DidClick
+		| ClickLink
+		| ShowPreviewSecuritySelector
+		| PreviewStyleLoadError
+		;
+}
+
+export namespace ToWebviewMessage {
+	export interface OnDidChangeTextEditorSelection extends BaseMessage {
+		readonly type: 'onDidChangeTextEditorSelection';
+		readonly line: number;
+	}
+
+	export interface UpdateView extends BaseMessage {
+		readonly type: 'updateView';
+		readonly line: number;
+		readonly source: string;
+	}
+
+	export interface UpdateContent extends BaseMessage {
+		readonly type: 'updateContent';
+		readonly content: string;
+	}
+
+	export type Type =
+		| OnDidChangeTextEditorSelection
+		| UpdateView
+		| UpdateContent
+		;
+}
diff --git a/extensions/microsoft-authentication/extension-browser.webpack.config.js b/extensions/microsoft-authentication/extension-browser.webpack.config.js
index 4d0866c793f..c9cb43b944b 100644
--- a/extensions/microsoft-authentication/extension-browser.webpack.config.js
+++ b/extensions/microsoft-authentication/extension-browser.webpack.config.js
@@ -21,9 +21,12 @@ module.exports = withBrowserDefaults({
 		extension: './src/extension.ts',
 	},
 	externals: {
-		'keytar': 'commonjs keytar'
+		'keytar': 'commonjs keytar',
 	},
 	resolve: {
+		fallback: {
+			'querystring': require.resolve('querystring-es3')
+		},
 		alias: {
 			'./node/crypto': path.resolve(__dirname, 'src/browser/crypto'),
 			'./node/authServer': path.resolve(__dirname, 'src/browser/authServer'),
diff --git a/extensions/microsoft-authentication/package.json b/extensions/microsoft-authentication/package.json
index 4369ed0c006..c30a8173f9f 100644
--- a/extensions/microsoft-authentication/package.json
+++ b/extensions/microsoft-authentication/package.json
@@ -49,7 +49,8 @@
     "@types/node-fetch": "^2.5.7",
     "@types/randombytes": "^2.0.0",
     "@types/sha.js": "^2.4.0",
-    "@types/uuid": "8.0.0"
+    "@types/uuid": "8.0.0",
+    "querystring-es3": "^0.2.1"
   },
   "dependencies": {
     "node-fetch": "2.6.7",
diff --git a/extensions/microsoft-authentication/src/AADHelper.ts b/extensions/microsoft-authentication/src/AADHelper.ts
index a6126dd7084..c49c708e14c 100644
--- a/extensions/microsoft-authentication/src/AADHelper.ts
+++ b/extensions/microsoft-authentication/src/AADHelper.ts
@@ -62,6 +62,7 @@ export interface IMicrosoftTokens {
 }
 
 interface IScopeData {
+	originalScopes?: string[];
 	scopes: string[];
 	scopeStr: string;
 	scopesToSend: string;
@@ -210,27 +211,28 @@ export class AzureActiveDirectoryService {
 			}
 		}
 
+		const clientId = this.getClientId(scopes);
+		const scopeData: IScopeData = {
+			clientId,
+			originalScopes: scopes,
+			scopes: modifiedScopes,
+			scopeStr: modifiedScopesStr,
+			// filter our special scopes
+			scopesToSend: modifiedScopes.filter(s => !s.startsWith('VSCODE_')).join(' '),
+			tenant: this.getTenantId(scopes),
+		};
+
 		// If we still don't have a matching token try to get a new token from an existing token by using
 		// the refreshToken. This is documented here:
 		// https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#refresh-the-access-token
 		// "Refresh tokens are valid for all permissions that your client has already received consent for."
 		if (!matchingTokens.length) {
-			const clientId = this.getClientId(modifiedScopes);
 			// Get a token with the correct client id.
 			const token = clientId === DEFAULT_CLIENT_ID
 				? this._tokens.find(t => t.refreshToken && !t.scope.includes('VSCODE_CLIENT_ID'))
 				: this._tokens.find(t => t.refreshToken && t.scope.includes(`VSCODE_CLIENT_ID:${clientId}`));
 
 			if (token) {
-				const scopeData: IScopeData = {
-					clientId,
-					scopes: modifiedScopes,
-					scopeStr: modifiedScopesStr,
-					// filter our special scopes
-					scopesToSend: modifiedScopes.filter(s => !s.startsWith('VSCODE_')).join(' '),
-					tenant: this.getTenantId(modifiedScopes),
-				};
-
 				try {
 					const itoken = await this.refreshToken(token.refreshToken, scopeData);
 					matchingTokens.push(itoken);
@@ -241,36 +243,35 @@ export class AzureActiveDirectoryService {
 		}
 
 		Logger.info(`Got ${matchingTokens.length} sessions for scopes: ${modifiedScopesStr}`);
-		return Promise.all(matchingTokens.map(token => this.convertToSession(token)));
+		return Promise.all(matchingTokens.map(token => this.convertToSession(token, scopeData)));
 	}
 
 	public createSession(scopes: string[]): Promise {
-		if (!scopes.includes('openid')) {
-			scopes.push('openid');
+		let modifiedScopes = [...scopes];
+		if (!modifiedScopes.includes('openid')) {
+			modifiedScopes.push('openid');
 		}
-		if (!scopes.includes('email')) {
-			scopes.push('email');
+		if (!modifiedScopes.includes('email')) {
+			modifiedScopes.push('email');
 		}
-		if (!scopes.includes('profile')) {
-			scopes.push('profile');
+		if (!modifiedScopes.includes('profile')) {
+			modifiedScopes.push('profile');
 		}
-		if (!scopes.includes('offline_access')) {
-			scopes.push('offline_access');
+		if (!modifiedScopes.includes('offline_access')) {
+			modifiedScopes.push('offline_access');
 		}
-		scopes = scopes.sort();
+		modifiedScopes = modifiedScopes.sort();
 		const scopeData: IScopeData = {
-			scopes,
-			scopeStr: scopes.join(' '),
+			originalScopes: scopes,
+			scopes: modifiedScopes,
+			scopeStr: modifiedScopes.join(' '),
 			// filter our special scopes
-			scopesToSend: scopes.filter(s => !s.startsWith('VSCODE_')).join(' '),
+			scopesToSend: modifiedScopes.filter(s => !s.startsWith('VSCODE_')).join(' '),
 			clientId: this.getClientId(scopes),
 			tenant: this.getTenantId(scopes),
 		};
 
 		Logger.info(`Logging in for the following scopes: ${scopeData.scopeStr}`);
-		if (!scopeData.scopes.includes('offline_access')) {
-			Logger.info('Warning: The \'offline_access\' scope was not included, so the generated token will not be able to be refreshed.');
-		}
 
 		const runsRemote = vscode.env.remoteName !== undefined;
 		const runsServerless = vscode.env.remoteName === undefined && vscode.env.uiKind === vscode.UIKind.Web;
@@ -511,7 +512,7 @@ export class AzureActiveDirectoryService {
 		};
 	}
 
-	private async convertToSession(token: IToken): Promise {
+	private async convertToSession(token: IToken, scopeData: IScopeData): Promise {
 		if (token.accessToken && (!token.expiresAt || token.expiresAt > Date.now())) {
 			token.expiresAt
 				? Logger.info(`Token available from cache (for scopes ${token.scope}), expires in ${token.expiresAt - Date.now()} milliseconds`)
@@ -521,21 +522,12 @@ export class AzureActiveDirectoryService {
 				accessToken: token.accessToken,
 				idToken: token.idToken,
 				account: token.account,
-				scopes: token.scope.split(' ')
+				scopes: scopeData.originalScopes ?? scopeData.scopes
 			};
 		}
 
 		try {
 			Logger.info(`Token expired or unavailable (for scopes ${token.scope}), trying refresh`);
-			const scopes = token.scope.split(' ');
-			const scopeData: IScopeData = {
-				scopes,
-				scopeStr: token.scope,
-				// filter our special scopes
-				scopesToSend: scopes.filter(s => !s.startsWith('VSCODE_')).join(' '),
-				clientId: this.getClientId(scopes),
-				tenant: this.getTenantId(scopes),
-			};
 			const refreshedToken = await this.refreshToken(token.refreshToken, scopeData, token.sessionId);
 			if (refreshedToken.accessToken) {
 				return {
@@ -543,7 +535,8 @@ export class AzureActiveDirectoryService {
 					accessToken: refreshedToken.accessToken,
 					idToken: refreshedToken.idToken,
 					account: token.account,
-					scopes: token.scope.split(' ')
+					// We always prefer the original scopes requested since that array is used as a key in the AuthService
+					scopes: scopeData.originalScopes ?? scopeData.scopes
 				};
 			} else {
 				throw new Error();
@@ -729,7 +722,7 @@ export class AzureActiveDirectoryService {
 		}
 		this.setToken(token, scopeData);
 		Logger.info(`Login successful for scopes: ${scopeData.scopeStr}`);
-		return await this.convertToSession(token);
+		return await this.convertToSession(token, scopeData);
 	}
 
 	private async fetchTokenResponse(endpoint: string, postData: string, scopeData: IScopeData): Promise {
diff --git a/extensions/microsoft-authentication/yarn.lock b/extensions/microsoft-authentication/yarn.lock
index fbc077f1509..5513eb3e992 100644
--- a/extensions/microsoft-authentication/yarn.lock
+++ b/extensions/microsoft-authentication/yarn.lock
@@ -370,6 +370,11 @@ node-fetch@2.6.7:
   dependencies:
     whatwg-url "^5.0.0"
 
+querystring-es3@^0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
+  integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==
+
 semver@^5.3.0, semver@^5.4.1:
   version "5.7.1"
   resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
diff --git a/extensions/notebook-renderers/package.json b/extensions/notebook-renderers/package.json
index f78839bbeeb..3f9f3d21e33 100644
--- a/extensions/notebook-renderers/package.json
+++ b/extensions/notebook-renderers/package.json
@@ -41,14 +41,15 @@
 		]
 	},
 	"scripts": {
-		"compile": "npm run build-notebook",
-		"watch": "node ./esbuild --watch",
+		"compile": "npx gulp compile-extension:notebook-renderers && npm run build-notebook",
+		"watch": "npx gulp compile-watch:notebook-renderers",
 		"build-notebook": "node ./esbuild"
 	},
-	"dependencies": {
-	},
+	"dependencies": {},
 	"devDependencies": {
-		"@types/vscode-notebook-renderer": "^1.60.0"
+		"@types/jsdom": "^21.1.0",
+		"@types/vscode-notebook-renderer": "^1.60.0",
+		"jsdom": "^21.1.1"
 	},
 	"repository": {
 		"type": "git",
diff --git a/extensions/notebook-renderers/src/ansi.ts b/extensions/notebook-renderers/src/ansi.ts
index 95bd1769dcc..bf3516b0252 100644
--- a/extensions/notebook-renderers/src/ansi.ts
+++ b/extensions/notebook-renderers/src/ansi.ts
@@ -5,6 +5,7 @@
 
 import { RGBA, Color } from './color';
 import { ansiColorIdentifiers } from './colorMap';
+import { ttPolicy } from './htmlHelper';
 import { linkify } from './linkify';
 
 
@@ -379,11 +380,6 @@ export function handleANSIOutput(text: string, trustHtml: boolean): HTMLSpanElem
 	}
 }
 
-const ttPolicy = window.trustedTypes?.createPolicy('notebookRenderer', {
-	createHTML: value => value,
-	createScript: value => value,
-});
-
 function appendStylizedStringToContainer(
 	root: HTMLElement,
 	stringContent: string,
diff --git a/extensions/notebook-renderers/src/htmlHelper.ts b/extensions/notebook-renderers/src/htmlHelper.ts
new file mode 100644
index 00000000000..819a3a640af
--- /dev/null
+++ b/extensions/notebook-renderers/src/htmlHelper.ts
@@ -0,0 +1,10 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+export const ttPolicy = (typeof window !== 'undefined') ?
+	window.trustedTypes?.createPolicy('notebookRenderer', {
+		createHTML: value => value,
+		createScript: value => value,
+	}) : undefined;
diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts
index 9220ff0c79f..385f6d865d8 100644
--- a/extensions/notebook-renderers/src/index.ts
+++ b/extensions/notebook-renderers/src/index.ts
@@ -4,35 +4,9 @@
  *--------------------------------------------------------------------------------------------*/
 
 import type { ActivationFunction, OutputItem, RendererContext } from 'vscode-notebook-renderer';
-import { insertOutput } from './textHelper';
-
-interface IDisposable {
-	dispose(): void;
-}
-
-interface HtmlRenderingHook {
-	/**
-	 * Invoked after the output item has been rendered but before it has been appended to the document.
-	 *
-	 * @return A new `HTMLElement` or `undefined` to continue using the provided element.
-	 */
-	postRender(outputItem: OutputItem, element: HTMLElement, signal: AbortSignal): HTMLElement | undefined | Promise;
-}
-
-interface JavaScriptRenderingHook {
-	/**
-	 * Invoked before the script is evaluated.
-	 *
-	 * @return A new string of JavaScript or `undefined` to continue using the provided string.
-	 */
-	preEvaluate(outputItem: OutputItem, element: HTMLElement, script: string, signal: AbortSignal): string | undefined | Promise;
-}
-
-interface RenderOptions {
-	readonly lineLimit: number;
-	readonly outputScrolling: boolean;
-	readonly outputWordWrap: boolean;
-}
+import { createOutputContent, scrollableClass } from './textHelper';
+import { HtmlRenderingHook, IDisposable, IRichRenderContext, JavaScriptRenderingHook, RenderOptions } from './rendererTypes';
+import { ttPolicy } from './htmlHelper';
 
 function clearContainer(container: HTMLElement) {
 	while (container.firstChild) {
@@ -67,11 +41,6 @@ function renderImage(outputInfo: OutputItem, element: HTMLElement): IDisposable
 	return disposable;
 }
 
-const ttPolicy = window.trustedTypes?.createPolicy('notebookRenderer', {
-	createHTML: value => value,
-	createScript: value => value,
-});
-
 const preservedScriptAttributes: (keyof HTMLScriptElement)[] = [
 	'type', 'src', 'nonce', 'noModule', 'async',
 ];
@@ -134,11 +103,35 @@ async function renderJavascript(outputInfo: OutputItem, container: HTMLElement,
 	domEval(element);
 }
 
-function renderError(outputInfo: OutputItem, container: HTMLElement, ctx: RendererContext & { readonly settings: RenderOptions }): void {
-	clearContainer(container);
+interface Event {
+	(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]): IDisposable;
+}
+
+function createDisposableStore(): { push(...disposables: IDisposable[]): void; dispose(): void } {
+	const localDisposables: IDisposable[] = [];
+	const disposable = {
+		push: (...disposables: IDisposable[]) => {
+			localDisposables.push(...disposables);
+		},
+		dispose: () => {
+			localDisposables.forEach(d => d.dispose());
+		}
+	};
+
+	return disposable;
+}
+
+type DisposableStore = ReturnType;
+
+function renderError(
+	outputInfo: OutputItem,
+	outputElement: HTMLElement,
+	ctx: IRichRenderContext
+): IDisposable {
+	const disposableStore = createDisposableStore();
+
+	clearContainer(outputElement);
 
-	const element = document.createElement('div');
-	container.appendChild(element);
 	type ErrorLike = Partial;
 
 	let err: ErrorLike;
@@ -146,97 +139,162 @@ function renderError(outputInfo: OutputItem, container: HTMLElement, ctx: Render
 		err = JSON.parse(outputInfo.text());
 	} catch (e) {
 		console.log(e);
-		return;
+		return disposableStore;
 	}
 
 	if (err.stack) {
-		const stack = document.createElement('pre');
-		stack.classList.add('traceback');
-		if (ctx.settings.outputWordWrap) {
-			stack.classList.add('wordWrap');
-		}
-		stack.style.margin = '8px 0';
-		const element = document.createElement('span');
-		insertOutput(outputInfo.id, [err.stack ?? ''], ctx.settings.lineLimit, false, element, true);
-		stack.appendChild(element);
-		container.appendChild(stack);
+		outputElement.classList.add('traceback');
+
+		const outputScrolling = ctx.settings.outputScrolling;
+		const content = createOutputContent(outputInfo.id, [err.stack ?? ''], ctx.settings.lineLimit, outputScrolling, true);
+		const contentParent = document.createElement('div');
+		contentParent.classList.toggle('word-wrap', ctx.settings.outputWordWrap);
+		disposableStore.push(ctx.onDidChangeSettings(e => {
+			contentParent.classList.toggle('word-wrap', e.outputWordWrap);
+		}));
+		contentParent.classList.toggle('scrollable', outputScrolling);
+		outputElement.classList.toggle('hide-refresh', !outputScrolling);
+		disposableStore.push(ctx.onDidChangeSettings(e => {
+			outputElement.classList.toggle('hide-refresh', !e.outputScrolling);
+		}));
+		outputElement.classList.toggle('remove-padding', outputScrolling);
+
+		contentParent.appendChild(content);
+		outputElement.appendChild(contentParent);
+		initializeScroll(contentParent, disposableStore);
 	} else {
 		const header = document.createElement('div');
 		const headerMessage = err.name && err.message ? `${err.name}: ${err.message}` : err.name || err.message;
 		if (headerMessage) {
 			header.innerText = headerMessage;
-			container.appendChild(header);
+			outputElement.appendChild(header);
 		}
 	}
 
-	container.classList.add('error');
+	outputElement.classList.add('error');
+	return disposableStore;
 }
 
-function renderStream(outputInfo: OutputItem, container: HTMLElement, error: boolean, ctx: RendererContext & { readonly settings: RenderOptions }): void {
-	const outputContainer = container.parentElement;
-	if (!outputContainer) {
-		// should never happen
-		return;
-	}
+function getPreviousMatchingContentGroup(outputElement: HTMLElement) {
+	const outputContainer = outputElement.parentElement;
+	let match: HTMLElement | undefined = undefined;
 
-	const prev = outputContainer.previousSibling;
-	if (prev) {
-		// OutputItem in the same cell
-		// check if the previous item is a stream
-		const outputElement = (prev.firstChild as HTMLElement | null);
-		if (outputElement && outputElement.getAttribute('output-mime-type') === outputInfo.mime) {
-			// same stream
-
-			// find child with same id
-			const existing = outputElement.querySelector(`[output-item-id="${outputInfo.id}"]`) as HTMLElement | null;
-			if (existing) {
-				clearContainer(existing);
-			}
-
-			const text = outputInfo.text();
-			const element = existing ?? document.createElement('span');
-			element.classList.add('output-stream');
-			if (ctx.settings.outputWordWrap) {
-				element.classList.add('wordWrap');
-			} else {
-				element.classList.remove('wordWrap');
-			}
-			element.setAttribute('output-item-id', outputInfo.id);
-			insertOutput(outputInfo.id, [text], ctx.settings.lineLimit, ctx.settings.outputScrolling, element, false);
-			outputElement.appendChild(element);
-			return;
+	let previous = outputContainer?.previousSibling;
+	while (previous) {
+		const outputElement = (previous.firstChild as HTMLElement | null);
+		if (!outputElement || !outputElement.classList.contains('output-stream')) {
+			break;
 		}
+
+		match = outputElement.firstChild as HTMLElement;
+		previous = previous?.previousSibling;
 	}
 
-	const element = document.createElement('span');
-	element.classList.add('output-stream');
-	if (ctx.settings.outputWordWrap) {
-		element.classList.add('wordWrap');
+	return match;
+}
+
+function onScrollHandler(e: globalThis.Event) {
+	const target = e.target as HTMLElement;
+	if (target.scrollTop === 0) {
+		target.classList.remove('more-above');
+	} else {
+		target.classList.add('more-above');
 	}
-	element.setAttribute('output-item-id', outputInfo.id);
+}
+
+// if there is a scrollable output, it will be scrolled to the given value if provided or the bottom of the element
+function initializeScroll(scrollableElement: HTMLElement, disposables: DisposableStore, scrollTop?: number) {
+	if (scrollableElement.classList.contains(scrollableClass)) {
+		scrollableElement.classList.toggle('scrollbar-visible', scrollableElement.scrollHeight > scrollableElement.clientHeight);
+		scrollableElement.scrollTop = scrollTop !== undefined ? scrollTop : scrollableElement.scrollHeight;
+		scrollableElement.addEventListener('scroll', onScrollHandler);
+		disposables.push({ dispose: () => scrollableElement.removeEventListener('scroll', onScrollHandler) });
+	}
+}
+
+// Find the scrollTop of the existing scrollable output, return undefined if at the bottom or element doesn't exist
+function findScrolledHeight(scrollableElement: HTMLElement): number | undefined {
+	if (scrollableElement && scrollableElement.scrollHeight - scrollableElement.scrollTop - scrollableElement.clientHeight > 2) {
+		// not scrolled to the bottom
+		return scrollableElement.scrollTop;
+	}
+	return undefined;
+}
+
+function renderStream(outputInfo: OutputItem, outputElement: HTMLElement, error: boolean, ctx: IRichRenderContext): IDisposable {
+	const disposableStore = createDisposableStore();
+	const outputScrolling = ctx.settings.outputScrolling;
+
+	outputElement.classList.add('output-stream');
+	outputElement.classList.toggle('remove-padding', outputScrolling);
 
 	const text = outputInfo.text();
-	insertOutput(outputInfo.id, [text], ctx.settings.lineLimit, ctx.settings.outputScrolling, element, false);
-	while (container.firstChild) {
-		container.removeChild(container.firstChild);
-	}
-	container.appendChild(element);
-	container.setAttribute('output-mime-type', outputInfo.mime);
+	const content = createOutputContent(outputInfo.id, [text], ctx.settings.lineLimit, outputScrolling, false);
+	content.setAttribute('output-item-id', outputInfo.id);
 	if (error) {
-		container.classList.add('error');
+		content.classList.add('error');
 	}
+
+	const scrollTop = outputScrolling ? findScrolledHeight(outputElement) : undefined;
+
+	// If the previous output item for the same cell was also a stream, append this output to the previous
+	const existingContentParent = getPreviousMatchingContentGroup(outputElement);
+	if (existingContentParent) {
+		const existing = existingContentParent.querySelector(`[output-item-id="${outputInfo.id}"]`) as HTMLElement | null;
+		if (existing) {
+			existing.replaceWith(content);
+		} else {
+			existingContentParent.appendChild(content);
+		}
+		existingContentParent.classList.toggle('scrollbar-visible', existingContentParent.scrollHeight > existingContentParent.clientHeight);
+		existingContentParent.scrollTop = scrollTop !== undefined ? scrollTop : existingContentParent.scrollHeight;
+	} else {
+		const contentParent = document.createElement('div');
+		contentParent.appendChild(content);
+		contentParent.classList.toggle('scrollable', outputScrolling);
+		outputElement.classList.toggle('hide-refresh', !outputScrolling);
+		disposableStore.push(ctx.onDidChangeSettings(e => {
+			outputElement.classList.toggle('hide-refresh', !e.outputScrolling);
+		}));
+
+		contentParent.classList.toggle('word-wrap', ctx.settings.outputWordWrap);
+		disposableStore.push(ctx.onDidChangeSettings(e => {
+			contentParent.classList.toggle('word-wrap', e.outputWordWrap);
+		}));
+
+
+		while (outputElement.firstChild) {
+			outputElement.removeChild(outputElement.firstChild);
+		}
+		outputElement.appendChild(contentParent);
+		initializeScroll(contentParent, disposableStore, scrollTop);
+	}
+
+	return disposableStore;
 }
 
-function renderText(outputInfo: OutputItem, container: HTMLElement, ctx: RendererContext & { readonly settings: RenderOptions }): void {
-	clearContainer(container);
-	const contentNode = document.createElement('div');
-	contentNode.classList.add('output-plaintext');
-	if (ctx.settings.outputWordWrap) {
-		contentNode.classList.add('wordWrap');
-	}
+function renderText(outputInfo: OutputItem, outputElement: HTMLElement, ctx: IRichRenderContext): IDisposable {
+	const disposableStore = createDisposableStore();
+	clearContainer(outputElement);
+
 	const text = outputInfo.text();
-	insertOutput(outputInfo.id, [text], ctx.settings.lineLimit, ctx.settings.outputScrolling, contentNode, false);
-	container.appendChild(contentNode);
+	const content = createOutputContent(outputInfo.id, [text], ctx.settings.lineLimit, ctx.settings.outputScrolling, false);
+	content.classList.add('output-plaintext');
+	if (ctx.settings.outputWordWrap) {
+		content.classList.add('word-wrap');
+	}
+
+	const outputScrolling = ctx.settings.outputScrolling;
+	content.classList.toggle('scrollable', outputScrolling);
+	outputElement.classList.toggle('hide-refresh', !outputScrolling);
+	disposableStore.push(ctx.onDidChangeSettings(e => {
+		outputElement.classList.toggle('hide-refresh', !e.outputScrolling);
+	}));
+	outputElement.classList.toggle('remove-padding', outputScrolling);
+	outputElement.appendChild(content);
+	initializeScroll(content, disposableStore);
+
+	return disposableStore;
 }
 
 export const activate: ActivationFunction = (ctx) => {
@@ -244,10 +302,14 @@ export const activate: ActivationFunction = (ctx) => {
 	const htmlHooks = new Set();
 	const jsHooks = new Set();
 
-	const latestContext = ctx as (RendererContext & { readonly settings: RenderOptions });
+	const latestContext = ctx as (RendererContext & { readonly settings: RenderOptions; readonly onDidChangeSettings: Event });
 
 	const style = document.createElement('style');
 	style.textContent = `
+	#container div.output.remove-padding {
+		padding-left: 0;
+		padding-right: 0;
+	}
 	.output-plaintext,
 	.output-stream,
 	.traceback {
@@ -260,29 +322,38 @@ export const activate: ActivationFunction = (ctx) => {
 		-webkit-user-select: text;
 		-ms-user-select: text;
 		cursor: auto;
+		word-wrap: break-word;
+		/* text/stream output container should scroll but preserve newline character */
+		white-space: pre;
 	}
-	.output-plaintext.wordWrap span,
-	.output-stream.wordWrap span,
-	.traceback.wordWrap span {
-		white-space: pre-wrap !important;
-		word-break: break-all;
-	}
-	.output-plaintext,
-	.output-stream {
+	/* When wordwrap turned on, force it to pre-wrap */
+	#container div.output_container .word-wrap span {
 		white-space: pre-wrap;
 	}
-	output-plaintext,
-	.traceback {
-		word-wrap: break-word;
-	}
-	.output > .scrollable {
+	#container div.output .scrollable {
+		padding-left: var(--notebook-output-node-left-padding);
+		padding-right: var(--notebook-output-node-padding);
 		overflow-y: scroll;
 		max-height: var(--notebook-cell-output-max-height);
-		border: var(--vscode-editorWidget-border);
 		border-style: solid;
-		padding-left: 4px;
 		box-sizing: border-box;
 		border-width: 1px;
+		border-color: transparent;
+	}
+	#container div.output .scrollable div {
+		cursor: text;
+	}
+	#container div.output .scrollable div a {
+		cursor: pointer;
+	}
+	#container div.output .scrollable.more-above {
+		box-shadow: var(--vscode-scrollbar-shadow) 0 6px 6px -6px inset
+	}
+	#container div.output .scrollable.scrollbar-visible {
+		border-color: var(--vscode-editorWidget-border);
+	}
+	#container div.output.hide-refresh .scroll-refresh {
+		display: none;
 	}
 	.output-plaintext .code-bold,
 	.output-stream .code-bold,
@@ -339,25 +410,33 @@ export const activate: ActivationFunction = (ctx) => {
 					break;
 				case 'application/vnd.code.notebook.error':
 					{
-						renderError(outputInfo, element, latestContext);
+						disposables.get(outputInfo.id)?.dispose();
+						const disposable = renderError(outputInfo, element, latestContext);
+						disposables.set(outputInfo.id, disposable);
 					}
 					break;
 				case 'application/vnd.code.notebook.stdout':
 				case 'application/x.notebook.stdout':
 				case 'application/x.notebook.stream':
 					{
-						renderStream(outputInfo, element, false, latestContext);
+						disposables.get(outputInfo.id)?.dispose();
+						const disposable = renderStream(outputInfo, element, false, latestContext);
+						disposables.set(outputInfo.id, disposable);
 					}
 					break;
 				case 'application/vnd.code.notebook.stderr':
 				case 'application/x.notebook.stderr':
 					{
-						renderStream(outputInfo, element, true, latestContext);
+						disposables.get(outputInfo.id)?.dispose();
+						const disposable = renderStream(outputInfo, element, true, latestContext);
+						disposables.set(outputInfo.id, disposable);
 					}
 					break;
 				case 'text/plain':
 					{
-						renderText(outputInfo, element, latestContext);
+						disposables.get(outputInfo.id)?.dispose();
+						const disposable = renderText(outputInfo, element, latestContext);
+						disposables.set(outputInfo.id, disposable);
 					}
 					break;
 				default:
diff --git a/extensions/notebook-renderers/src/linkify.ts b/extensions/notebook-renderers/src/linkify.ts
index 416527484d9..80e812f7f0a 100644
--- a/extensions/notebook-renderers/src/linkify.ts
+++ b/extensions/notebook-renderers/src/linkify.ts
@@ -11,7 +11,7 @@ const WIN_RELATIVE_PATH = /(?:(?:\~|\.)(?:(?:\\|\/)[\w\.-]*)+)/;
 const WIN_PATH = new RegExp(`(${WIN_ABSOLUTE_PATH.source}|${WIN_RELATIVE_PATH.source})`);
 const POSIX_PATH = /((?:\~|\.)?(?:\/[\w\.-]*)+)/;
 const LINE_COLUMN = /(?:\:([\d]+))?(?:\:([\d]+))?/;
-const isWindows = navigator.userAgent.indexOf('Windows') >= 0;
+const isWindows = (typeof navigator !== 'undefined') ? navigator.userAgent && navigator.userAgent.indexOf('Windows') >= 0 : false;
 const PATH_LINK_REGEX = new RegExp(`${isWindows ? WIN_PATH.source : POSIX_PATH.source}${LINE_COLUMN.source}`, 'g');
 
 const MAX_LENGTH = 2000;
diff --git a/extensions/notebook-renderers/src/rendererTypes.ts b/extensions/notebook-renderers/src/rendererTypes.ts
new file mode 100644
index 00000000000..9da94aeef5d
--- /dev/null
+++ b/extensions/notebook-renderers/src/rendererTypes.ts
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { OutputItem, RendererContext } from 'vscode-notebook-renderer';
+import { Event } from 'vscode';
+
+export interface IDisposable {
+	dispose(): void;
+}
+
+export interface HtmlRenderingHook {
+	/**
+	 * Invoked after the output item has been rendered but before it has been appended to the document.
+	 *
+	 * @return A new `HTMLElement` or `undefined` to continue using the provided element.
+	 */
+	postRender(outputItem: OutputItem, element: HTMLElement, signal: AbortSignal): HTMLElement | undefined | Promise;
+}
+
+export interface JavaScriptRenderingHook {
+	/**
+	 * Invoked before the script is evaluated.
+	 *
+	 * @return A new string of JavaScript or `undefined` to continue using the provided string.
+	 */
+	preEvaluate(outputItem: OutputItem, element: HTMLElement, script: string, signal: AbortSignal): string | undefined | Promise;
+}
+
+export interface RenderOptions {
+	readonly lineLimit: number;
+	readonly outputScrolling: boolean;
+	readonly outputWordWrap: boolean;
+}
+
+export type IRichRenderContext = RendererContext & { readonly settings: RenderOptions; readonly onDidChangeSettings: Event };
diff --git a/extensions/notebook-renderers/src/test/index.ts b/extensions/notebook-renderers/src/test/index.ts
new file mode 100644
index 00000000000..c7a818354b7
--- /dev/null
+++ b/extensions/notebook-renderers/src/test/index.ts
@@ -0,0 +1,40 @@
+/*---------------------------------------------------------------------------------------------
+ *  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 testRunner from '../../../../test/integration/electron/testrunner';
+
+const options: import('mocha').MochaOptions = {
+	ui: 'tdd',
+	color: true,
+	timeout: 60000
+};
+
+// These integration tests is being run in multiple environments (electron, web, remote)
+// so we need to set the suite name based on the environment as the suite name is used
+// for the test results file name
+let suite = '';
+if (process.env.VSCODE_BROWSER) {
+	suite = `${process.env.VSCODE_BROWSER} Browser Integration notebook output renderer Tests`;
+} else if (process.env.REMOTE_VSCODE) {
+	suite = 'Remote Integration notebook output renderer Tests';
+} else {
+	suite = 'Integration notebook output renderer Tests';
+}
+
+if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
+	options.reporter = 'mocha-multi-reporters';
+	options.reporterOptions = {
+		reporterEnabled: 'spec, mocha-junit-reporter',
+		mochaJunitReporterReporterOptions: {
+			testsuitesTitle: `${suite} ${process.platform}`,
+			mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${process.arch}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
+		}
+	};
+}
+
+testRunner.configure(options);
+
+export = testRunner;
diff --git a/extensions/notebook-renderers/src/test/notebookRenderer.test.ts b/extensions/notebook-renderers/src/test/notebookRenderer.test.ts
new file mode 100644
index 00000000000..3ce2c4019e8
--- /dev/null
+++ b/extensions/notebook-renderers/src/test/notebookRenderer.test.ts
@@ -0,0 +1,229 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as assert from 'assert';
+import { activate } from '..';
+import { OutputItem, RendererApi } from 'vscode-notebook-renderer';
+import { IRichRenderContext, RenderOptions } from '../rendererTypes';
+import { JSDOM } from "jsdom";
+
+const dom = new JSDOM();
+global.document = dom.window.document;
+
+suite('Notebook builtin output renderer', () => {
+
+	const error = {
+		name: "NameError",
+		message: "name 'x' is not defined",
+		stack: "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m" +
+			"\n\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)" +
+			"\nCell \u001b[1;32mIn[3], line 1\u001b[0m" +
+			"\n\u001b[1;32m----> 1\u001b[0m \u001b[39mprint\u001b[39m(x)" +
+			"\n\n\u001b[1;31mNameError\u001b[0m: name 'x' is not defined"
+	};
+
+	const errorMimeType = 'application/vnd.code.notebook.error';
+
+	const stdoutMimeType = 'application/vnd.code.notebook.stdout';
+	const stderrMimeType = 'application/vnd.code.notebook.stderr';
+
+	const textLikeMimeTypes = [
+		stdoutMimeType,
+		stderrMimeType,
+		'text/plain'
+	];
+
+	type optionalRenderOptions = { [k in keyof RenderOptions]?: RenderOptions[k] };
+
+	function createContext(settings?: optionalRenderOptions): IRichRenderContext {
+		return {
+			setState(_value: void) { },
+			getState() { return undefined; },
+			async getRenderer(_id): Promise { return undefined; },
+			settings: {
+				outputWordWrap: true,
+				outputScrolling: true,
+				lineLimit: 30,
+				...settings
+			} as RenderOptions,
+			onDidChangeSettings(_listener: (e: T) => any, _thisArgs?: any, _disposables?: any) {
+				return {
+					dispose(): void { }
+				};
+			},
+			workspace: {
+				isTrusted: true
+			}
+		};
+	}
+
+	function createElement(elementType: 'div' | 'span', classes: string[]) {
+		const el = global.document.createElement(elementType);
+		classes.forEach((c) => el.classList.add(c));
+		return el;
+	}
+
+	// Helper to generate HTML similar to what is passed to the renderer
+	// 
+ //
+ //
+ class OutputHtml { + private readonly cell = createElement('div', ['cell_container']); + private readonly firstOutput: HTMLElement; + + constructor() { + const outputContainer = createElement('div', ['output_container']); + const outputElement = createElement('div', ['output']); + + this.cell.appendChild(outputContainer); + outputContainer.appendChild(outputElement); + + this.firstOutput = outputElement; + } + + public getFirstOuputElement() { + return this.firstOutput; + } + + public appendOutputElement() { + const outputElement = createElement('div', ['output']); + const outputContainer = createElement('div', ['output_container']); + this.cell.appendChild(outputContainer); + outputContainer.appendChild(outputElement); + + return outputElement; + } + } + + function createOutputItem(text: string, mime: string, id: string = '123'): OutputItem { + return { + id: id, + mime: mime, + text() { + return text; + }, + blob() { + return [] as any; + }, + json() { + return '{ }'; + }, + data() { + return [] as any; + }, + metadata: {} + }; + } + + textLikeMimeTypes.forEach((mimeType) => { + test(`Render with wordwrap and scrolling for mimetype ${mimeType}`, async () => { + const context = createContext({ outputWordWrap: true, outputScrolling: true }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const outputItem = createOutputItem('content', mimeType); + await renderer!.renderOutputItem(outputItem, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted, `nothing appended to output element: ${outputElement.innerHTML}`); + assert.ok(outputElement.classList.contains('remove-padding'), `Padding should be removed for scrollable outputs ${outputElement.classList}`); + assert.ok(inserted.classList.contains('word-wrap') && inserted.classList.contains('scrollable'), + `output content classList should contain word-wrap and scrollable ${inserted.classList}`); + assert.ok(inserted.innerHTML.indexOf('>content -1, `Content was not added to output element: ${outputElement.innerHTML}`); + }); + + test(`Render without wordwrap or scrolling for mimetype ${mimeType}`, async () => { + const context = createContext({ outputWordWrap: false, outputScrolling: false }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const outputItem = createOutputItem('content', mimeType); + await renderer!.renderOutputItem(outputItem, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted, `nothing appended to output element: ${outputElement.innerHTML}`); + assert.ok(!outputElement.classList.contains('remove-padding'), `Padding should not be removed for non-scrollable outputs: ${outputElement.classList}`); + assert.ok(!inserted.classList.contains('word-wrap') && !inserted.classList.contains('scrollable'), + `output content classList should not contain word-wrap and scrollable ${inserted.classList}`); + assert.ok(inserted.innerHTML.indexOf('>content -1, `Content was not added to output element: ${outputElement.innerHTML}`); + }); + + test(`Replace content in element for mimetype ${mimeType}`, async () => { + const context = createContext(); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const outputItem = createOutputItem('content', 'text/plain'); + await renderer!.renderOutputItem(outputItem, outputElement); + const outputItem2 = createOutputItem('replaced content', 'text/plain'); + await renderer!.renderOutputItem(outputItem2, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted.innerHTML.indexOf('>contentreplaced content { + const context = createContext({ outputWordWrap: true, outputScrolling: true }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const outputItem = createOutputItem(JSON.stringify(error), errorMimeType); + await renderer!.renderOutputItem(outputItem, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted, `nothing appended to output element: ${outputElement.innerHTML}`); + assert.ok(outputElement.classList.contains('remove-padding'), 'Padding should be removed for scrollable outputs'); + assert.ok(inserted.classList.contains('word-wrap') && inserted.classList.contains('scrollable'), + `output content classList should contain word-wrap and scrollable ${inserted.classList}`); + assert.ok(inserted.innerHTML.indexOf('>: name \'x\' is not defined -1, `Content was not added to output element:\n ${outputElement.innerHTML}`); + }); + + test(`Replace content in element for error output`, async () => { + const context = createContext(); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const outputItem = createOutputItem(JSON.stringify(error), errorMimeType); + await renderer!.renderOutputItem(outputItem, outputElement); + const error2: typeof error = { ...error, message: 'new message', stack: 'replaced content' }; + const outputItem2 = createOutputItem(JSON.stringify(error2), errorMimeType); + await renderer!.renderOutputItem(outputItem2, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted.innerHTML.indexOf('>: name \'x\' is not definedreplaced content { + const context = createContext(); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputHtml = new OutputHtml(); + const outputElement = outputHtml.getFirstOuputElement(); + const outputItem1 = createOutputItem('first stream content', stdoutMimeType, '1'); + const outputItem2 = createOutputItem('second stream content', stdoutMimeType, '2'); + const outputItem3 = createOutputItem('third stream content', stderrMimeType, '3'); + await renderer!.renderOutputItem(outputItem1, outputElement); + await renderer!.renderOutputItem(outputItem2, outputHtml.appendOutputElement()); + await renderer!.renderOutputItem(outputItem3, outputHtml.appendOutputElement()); + + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted, `nothing appended to output element: ${outputElement.innerHTML}`); + assert.ok(inserted.innerHTML.indexOf('>first stream content -1, `Content was not added to output element: ${outputElement.innerHTML}`); + assert.ok(inserted.innerHTML.indexOf('>second stream content -1, `Content was not added to output element: ${outputElement.innerHTML}`); + assert.ok(inserted.innerHTML.indexOf('>third stream content -1, `Content was not added to output element: ${outputElement.innerHTML}`); + }); +}); + diff --git a/extensions/notebook-renderers/src/textHelper.ts b/extensions/notebook-renderers/src/textHelper.ts index 3555307ec9d..d4ae6542990 100644 --- a/extensions/notebook-renderers/src/textHelper.ts +++ b/extensions/notebook-renderers/src/textHelper.ts @@ -5,74 +5,98 @@ import { handleANSIOutput } from './ansi'; -function generateViewMoreElement(outputId: string, adjustableSize: boolean) { - const container = document.createElement('span'); - const first = document.createElement('span'); +export const scrollableClass = 'scrollable'; - if (adjustableSize) { - first.textContent = 'Output exceeds the '; - const second = document.createElement('a'); - second.textContent = 'size limit'; - second.href = `command:workbench.action.openSettings?%5B%22notebook.output.textLineLimit%22%5D`; - container.appendChild(first); - container.appendChild(second); - } else { - first.textContent = 'Output exceeds the maximium size limit'; - container.appendChild(first); - } +function generateViewMoreElement(outputId: string) { + const container = document.createElement('div'); + const first = document.createElement('span'); + first.textContent = 'Output exceeds the '; + + const second = document.createElement('a'); + second.textContent = 'size limit'; + second.href = `command:workbench.action.openSettings?%5B%22notebook.output.textLineLimit%22%5D`; + container.appendChild(first); + container.appendChild(second); const third = document.createElement('span'); third.textContent = '. Open the full output data '; + const forth = document.createElement('a'); forth.textContent = 'in a text editor'; forth.href = `command:workbench.action.openLargeOutput?${outputId}`; container.appendChild(third); container.appendChild(forth); + + const refreshSpan = document.createElement('span'); + refreshSpan.classList.add('scroll-refresh'); + const fifth = document.createElement('span'); + fifth.textContent = '. Refresh to view '; + + const sixth = document.createElement('a'); + sixth.textContent = 'scrollable element'; + sixth.href = `command:cellOutput.enableScrolling?${outputId}`; + refreshSpan.appendChild(fifth); + refreshSpan.appendChild(sixth); + container.appendChild(refreshSpan); + return container; } -function truncatedArrayOfString(id: string, buffer: string[], linesLimit: number, container: HTMLElement, trustHtml: boolean) { - const lineCount = buffer.length; - container.appendChild(generateViewMoreElement(id, true)); +function generateNestedViewAllElement(outputId: string) { + const container = document.createElement('div'); - const div = document.createElement('div'); - container.appendChild(div); - div.appendChild(handleANSIOutput(buffer.slice(0, linesLimit - 5).join('\n'), trustHtml)); + const link = document.createElement('a'); + link.textContent = '...'; + link.href = `command:workbench.action.openLargeOutput?${outputId}`; + link.ariaLabel = 'Open full output in text editor'; + link.title = 'Open full output in text editor'; + link.style.setProperty('text-decoration', 'none'); + container.appendChild(link); - // view more ... - const viewMoreSpan = document.createElement('span'); - viewMoreSpan.innerText = '...'; - container.appendChild(viewMoreSpan); - - const div2 = document.createElement('div'); - container.appendChild(div2); - div2.appendChild(handleANSIOutput(buffer.slice(lineCount - 5).join('\n'), trustHtml)); + return container; } -function scrollableArrayOfString(id: string, buffer: string[], container: HTMLElement, trustHtml: boolean) { - container.classList.add('scrollable'); - - if (buffer.length > 5000) { - container.appendChild(generateViewMoreElement(id, false)); - } - const div = document.createElement('div'); - container.appendChild(div); - div.appendChild(handleANSIOutput(buffer.slice(0, 5000).join('\n'), trustHtml)); -} - -export function insertOutput(id: string, outputs: string[], linesLimit: number, scrollable: boolean, container: HTMLElement, trustHtml: boolean) { - const buffer = outputs.join('\n').split(/\r\n|\r|\n/g); +function truncatedArrayOfString(id: string, buffer: string[], linesLimit: number, trustHtml: boolean) { + const container = document.createElement('div'); const lineCount = buffer.length; - if (lineCount < linesLimit) { + if (lineCount <= linesLimit) { const spanElement = handleANSIOutput(buffer.join('\n'), trustHtml); container.appendChild(spanElement); - return; + return container; } + container.appendChild(generateViewMoreElement(id)); + container.appendChild(handleANSIOutput(buffer.slice(0, linesLimit - 5).join('\n'), trustHtml)); + + // truncated piece + const elipses = document.createElement('div'); + elipses.innerText = '...'; + container.appendChild(elipses); + + container.appendChild(handleANSIOutput(buffer.slice(lineCount - 5).join('\n'), trustHtml)); + + return container; +} + +function scrollableArrayOfString(id: string, buffer: string[], trustHtml: boolean) { + const element = document.createElement('div'); + if (buffer.length > 5000) { + element.appendChild(generateNestedViewAllElement(id)); + } + + element.appendChild(handleANSIOutput(buffer.slice(-5000).join('\n'), trustHtml)); + + return element; +} + +export function createOutputContent(id: string, outputs: string[], linesLimit: number, scrollable: boolean, trustHtml: boolean): HTMLElement { + + const buffer = outputs.join('\n').split(/\r\n|\r|\n/g); + if (scrollable) { - scrollableArrayOfString(id, buffer, container, trustHtml); + return scrollableArrayOfString(id, buffer, trustHtml); } else { - truncatedArrayOfString(id, buffer, linesLimit, container, trustHtml); + return truncatedArrayOfString(id, buffer, linesLimit, trustHtml); } } diff --git a/extensions/notebook-renderers/yarn.lock b/extensions/notebook-renderers/yarn.lock index 06ac4e135c3..ba3ff6b48d9 100644 --- a/extensions/notebook-renderers/yarn.lock +++ b/extensions/notebook-renderers/yarn.lock @@ -2,7 +2,422 @@ # yarn lockfile v1 +"@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/jsdom@^21.1.0": + version "21.1.0" + resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-21.1.0.tgz#219f15e3370da3f85d18fe02ae86bda7ff66104a" + integrity sha512-leWreJOdnuIxq9Y70tBVm/bvTuh31DSlF/r4l7Cfi4uhVQqLHD0Q4v301GMisEMwwbMgF7ZKxuZ+Jbd4NcdmRw== + dependencies: + "@types/node" "*" + "@types/tough-cookie" "*" + parse5 "^7.0.0" + +"@types/node@*": + version "18.15.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.3.tgz#f0b991c32cfc6a4e7f3399d6cb4b8cf9a0315014" + integrity sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw== + +"@types/tough-cookie@*": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397" + integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw== + "@types/vscode-notebook-renderer@^1.60.0": version "1.60.0" resolved "https://registry.yarnpkg.com/@types/vscode-notebook-renderer/-/vscode-notebook-renderer-1.60.0.tgz#8a67d561f48ddf46a95dfa9f712a79c72c7b8f7a" integrity sha512-u7TD2uuEZTVuitx0iijOJdKI0JLiQP6PsSBSRy2XmHXUOXcp5p1S56NrjOEDoF+PIHd3NL3eO6KTRSf5nukDqQ== + +abab@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +acorn-globals@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" + integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q== + dependencies: + acorn "^8.1.0" + acorn-walk "^8.0.2" + +acorn-walk@^8.0.2: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.1.0, acorn@^8.8.2: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +cssstyle@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-3.0.0.tgz#17ca9c87d26eac764bb8cfd00583cff21ce0277a" + integrity sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg== + dependencies: + rrweb-cssom "^0.6.0" + +data-urls@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-4.0.0.tgz#333a454eca6f9a5b7b0f1013ff89074c3f522dd4" + integrity sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g== + dependencies: + abab "^2.0.6" + whatwg-mimetype "^3.0.0" + whatwg-url "^12.0.0" + +debug@4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decimal.js@^10.4.3: + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== + +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +domexception@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== + dependencies: + webidl-conversions "^7.0.0" + +entities@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" + integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +html-encoding-sniffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" + integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== + dependencies: + whatwg-encoding "^2.0.0" + +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" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +jsdom@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-21.1.1.tgz#ab796361e3f6c01bcfaeda1fea3c06197ac9d8ae" + integrity sha512-Jjgdmw48RKcdAIQyUD1UdBh2ecH7VqwaXPN3ehoZN6MqgVbMn+lRm1aAT1AsdJRAJpwfa4IpwgzySn61h2qu3w== + dependencies: + abab "^2.0.6" + acorn "^8.8.2" + acorn-globals "^7.0.0" + cssstyle "^3.0.0" + data-urls "^4.0.0" + decimal.js "^10.4.3" + domexception "^4.0.0" + escodegen "^2.0.0" + form-data "^4.0.0" + html-encoding-sniffer "^3.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.1" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.2" + parse5 "^7.1.2" + rrweb-cssom "^0.6.0" + saxes "^6.0.0" + symbol-tree "^3.2.4" + tough-cookie "^4.1.2" + w3c-xmlserializer "^4.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^12.0.1" + ws "^8.13.0" + xml-name-validator "^4.0.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +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== + +nwsapi@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" + integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +parse5@^7.0.0, parse5@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== + +psl@^1.1.33: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +punycode@^2.1.1, punycode@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +rrweb-cssom@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz#ed298055b97cbddcdeb278f904857629dec5e0e1" + integrity sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw== + +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +saxes@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" + integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA== + dependencies: + xmlchars "^2.2.0" + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +tough-cookie@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" + integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" + +tr46@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-4.1.1.tgz#281a758dcc82aeb4fe38c7dfe4d11a395aac8469" + integrity sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw== + dependencies: + punycode "^2.3.0" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== + dependencies: + prelude-ls "~1.1.2" + +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +w3c-xmlserializer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073" + integrity sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw== + dependencies: + xml-name-validator "^4.0.0" + +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + +whatwg-encoding@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== + dependencies: + iconv-lite "0.6.3" + +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== + +whatwg-url@^12.0.0, whatwg-url@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-12.0.1.tgz#fd7bcc71192e7c3a2a97b9a8d6b094853ed8773c" + integrity sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ== + dependencies: + tr46 "^4.1.1" + webidl-conversions "^7.0.0" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +ws@^8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + +xml-name-validator@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" + integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== diff --git a/extensions/npm/src/features/date.ts b/extensions/npm/src/features/date.ts new file mode 100644 index 00000000000..e2f3b44f818 --- /dev/null +++ b/extensions/npm/src/features/date.ts @@ -0,0 +1,201 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { l10n } from 'vscode'; + + +const minute = 60; +const hour = minute * 60; +const day = hour * 24; +const week = day * 7; +const month = day * 30; +const year = day * 365; + +/** + * Create a localized of the time between now and the specified date. + * @param date The date to generate the difference from. + * @param appendAgoLabel Whether to append the " ago" to the end. + * @param useFullTimeWords Whether to use full words (eg. seconds) instead of + * shortened (eg. secs). + * @param disallowNow Whether to disallow the string "now" when the difference + * is less than 30 seconds. + */ +export function fromNow(date: number | Date, appendAgoLabel?: boolean, useFullTimeWords?: boolean, disallowNow?: boolean): string { + if (typeof date !== 'number') { + date = date.getTime(); + } + + const seconds = Math.round((new Date().getTime() - date) / 1000); + if (seconds < -30) { + return l10n.t('in {0}', fromNow(new Date().getTime() + seconds * 1000, false)); + } + + if (!disallowNow && seconds < 30) { + return l10n.t('now'); + } + + let value: number; + if (seconds < minute) { + value = seconds; + + if (appendAgoLabel) { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} second ago', value) + : l10n.t('{0} sec ago', value); + } else { + return useFullTimeWords + ? l10n.t('{0} seconds ago', value) + : l10n.t('{0} secs ago', value); + } + } else { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} second', value) + : l10n.t('{0} sec', value); + } else { + return useFullTimeWords + ? l10n.t('{0} seconds', value) + : l10n.t('{0} secs', value); + } + } + } + + if (seconds < hour) { + value = Math.floor(seconds / minute); + if (appendAgoLabel) { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} minute ago', value) + : l10n.t('{0} min ago', value); + } else { + return useFullTimeWords + ? l10n.t('{0} minutes ago', value) + : l10n.t('{0} mins ago', value); + } + } else { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} minute', value) + : l10n.t('{0} min', value); + } else { + return useFullTimeWords + ? l10n.t('{0} minutes', value) + : l10n.t('{0} mins', value); + } + } + } + + if (seconds < day) { + value = Math.floor(seconds / hour); + if (appendAgoLabel) { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} hour ago', value) + : l10n.t('{0} hr ago', value); + } else { + return useFullTimeWords + ? l10n.t('{0} hours ago', value) + : l10n.t('{0} hrs ago', value); + } + } else { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} hour', value) + : l10n.t('{0} hr', value); + } else { + return useFullTimeWords + ? l10n.t('{0} hours', value) + : l10n.t('{0} hrs', value); + } + } + } + + if (seconds < week) { + value = Math.floor(seconds / day); + if (appendAgoLabel) { + return value === 1 + ? l10n.t('{0} day ago', value) + : l10n.t('{0} days ago', value); + } else { + return value === 1 + ? l10n.t('{0} day', value) + : l10n.t('{0} days', value); + } + } + + if (seconds < month) { + value = Math.floor(seconds / week); + if (appendAgoLabel) { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} week ago', value) + : l10n.t('{0} wk ago', value); + } else { + return useFullTimeWords + ? l10n.t('{0} weeks ago', value) + : l10n.t('{0} wks ago', value); + } + } else { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} week', value) + : l10n.t('{0} wk', value); + } else { + return useFullTimeWords + ? l10n.t('{0} weeks', value) + : l10n.t('{0} wks', value); + } + } + } + + if (seconds < year) { + value = Math.floor(seconds / month); + if (appendAgoLabel) { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} month ago', value) + : l10n.t('{0} mo ago', value); + } else { + return useFullTimeWords + ? l10n.t('{0} months ago', value) + : l10n.t('{0} mos ago', value); + } + } else { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} month', value) + : l10n.t('{0} mo', value); + } else { + return useFullTimeWords + ? l10n.t('{0} months', value) + : l10n.t('{0} mos', value); + } + } + } + + value = Math.floor(seconds / year); + if (appendAgoLabel) { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} year ago', value) + : l10n.t('{0} yr ago', value); + } else { + return useFullTimeWords + ? l10n.t('{0} years ago', value) + : l10n.t('{0} yrs ago', value); + } + } else { + if (value === 1) { + return useFullTimeWords + ? l10n.t('{0} year', value) + : l10n.t('{0} yr', value); + } else { + return useFullTimeWords + ? l10n.t('{0} years', value) + : l10n.t('{0} yrs', value); + } + } +} diff --git a/extensions/npm/src/features/packageJSONContribution.ts b/extensions/npm/src/features/packageJSONContribution.ts index 7368f8cbf86..5a9250d97de 100644 --- a/extensions/npm/src/features/packageJSONContribution.ts +++ b/extensions/npm/src/features/packageJSONContribution.ts @@ -10,6 +10,7 @@ import { Location } from 'jsonc-parser'; import * as cp from 'child_process'; import { dirname } from 'path'; +import { fromNow } from './date'; const LIMIT = 40; @@ -215,14 +216,14 @@ export class PackageJSONContribution implements IJSONContribution { return null; } - private getDocumentation(description: string | undefined, version: string | undefined, homepage: string | undefined): MarkdownString { + private getDocumentation(description: string | undefined, version: string | undefined, time: string | undefined, homepage: string | undefined): MarkdownString { const str = new MarkdownString(); if (description) { str.appendText(description); } if (version) { str.appendText('\n\n'); - str.appendText(l10n.t("Latest version: {0}", version)); + str.appendText(time ? l10n.t("Latest version: {0} published {1}", version, fromNow(Date.parse(time), true, true)) : l10n.t("Latest version: {0}", version)); } if (homepage) { str.appendText('\n\n'); @@ -241,7 +242,7 @@ export class PackageJSONContribution implements IJSONContribution { return this.fetchPackageInfo(name, resource).then(info => { if (info) { - item.documentation = this.getDocumentation(info.description, info.version, info.homepage); + item.documentation = this.getDocumentation(info.description, info.version, info.time, info.homepage); return item; } return null; @@ -283,15 +284,17 @@ export class PackageJSONContribution implements IJSONContribution { private npmView(npmCommandPath: string, pack: string, resource: Uri | undefined): Promise { return new Promise((resolve, _reject) => { - const args = ['view', '--json', pack, 'description', 'dist-tags.latest', 'homepage', 'version']; + const args = ['view', '--json', pack, 'description', 'dist-tags.latest', 'homepage', 'version', 'time']; const cwd = resource && resource.scheme === 'file' ? dirname(resource.fsPath) : undefined; cp.execFile(npmCommandPath, args, { cwd }, (error, stdout) => { if (!error) { try { const content = JSON.parse(stdout); + const version = content['dist-tags.latest'] || content['version']; resolve({ description: content['description'], - version: content['dist-tags.latest'] || content['version'], + version, + time: content.time?.[version], homepage: content['homepage'] }); return; @@ -316,6 +319,7 @@ export class PackageJSONContribution implements IJSONContribution { return { description: obj.description || '', version, + time: obj.time?.[version], homepage: obj.homepage || '' }; } @@ -334,7 +338,7 @@ export class PackageJSONContribution implements IJSONContribution { if (typeof pack === 'string') { return this.fetchPackageInfo(pack, resource).then(info => { if (info) { - return [this.getDocumentation(info.description, info.version, info.homepage)]; + return [this.getDocumentation(info.description, info.version, info.time, info.homepage)]; } return null; }); @@ -363,7 +367,7 @@ export class PackageJSONContribution implements IJSONContribution { proposal.kind = CompletionItemKind.Property; proposal.insertText = insertText; proposal.filterText = JSON.stringify(name); - proposal.documentation = this.getDocumentation(pack.description, pack.version, pack?.links?.homepage); + proposal.documentation = this.getDocumentation(pack.description, pack.version, undefined, pack?.links?.homepage); collector.add(proposal); } } @@ -379,5 +383,6 @@ interface SearchPackageInfo { interface ViewPackageInfo { description: string; version?: string; + time?: string; homepage?: string; } diff --git a/extensions/npm/src/preferred-pm.ts b/extensions/npm/src/preferred-pm.ts index f69933d10f1..92fcdfc8033 100644 --- a/extensions/npm/src/preferred-pm.ts +++ b/extensions/npm/src/preferred-pm.ts @@ -66,18 +66,18 @@ export async function findPreferredPM(pkgPath: string): Promise<{ name: string; detectedPackageManagerProperties.push(npmPreferred); } - const yarnPreferred = await isYarnPreferred(pkgPath); - if (yarnPreferred.isPreferred) { - detectedPackageManagerNames.push('yarn'); - detectedPackageManagerProperties.push(yarnPreferred); - } - const pnpmPreferred = await isPNPMPreferred(pkgPath); if (pnpmPreferred.isPreferred) { detectedPackageManagerNames.push('pnpm'); detectedPackageManagerProperties.push(pnpmPreferred); } + const yarnPreferred = await isYarnPreferred(pkgPath); + if (yarnPreferred.isPreferred) { + detectedPackageManagerNames.push('yarn'); + detectedPackageManagerProperties.push(yarnPreferred); + } + const pmUsedForInstallation: { name: string } | null = await whichPM(pkgPath); if (pmUsedForInstallation && !detectedPackageManagerNames.includes(pmUsedForInstallation.name)) { diff --git a/extensions/package.json b/extensions/package.json index 2b3c1aedf3a..1bc7e39d12b 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -4,7 +4,7 @@ "license": "MIT", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "^4.9.5" + "typescript": "5.0.2" }, "scripts": { "postinstall": "node ./postinstall.mjs" diff --git a/extensions/pug/cgmanifest.json b/extensions/pug/cgmanifest.json index 1575c2a5d4b..d0e3c6185ce 100644 --- a/extensions/pug/cgmanifest.json +++ b/extensions/pug/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "davidrios/pug-tmbundle", "repositoryUrl": "https://github.com/davidrios/pug-tmbundle", - "commitHash": "aee5f096dac969fe09afac55f05f3f4e774f61a3" + "commitHash": "ae1dd60ca4aa4b45617f236d584216cd8d19eecf" } }, "license": "MIT", diff --git a/extensions/pug/syntaxes/pug.tmLanguage.json b/extensions/pug/syntaxes/pug.tmLanguage.json index bd5517103ce..33d57431ee1 100644 --- a/extensions/pug/syntaxes/pug.tmLanguage.json +++ b/extensions/pug/syntaxes/pug.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/davidrios/pug-tmbundle/commit/aee5f096dac969fe09afac55f05f3f4e774f61a3", + "version": "https://github.com/davidrios/pug-tmbundle/commit/ae1dd60ca4aa4b45617f236d584216cd8d19eecf", "name": "Pug", "scopeName": "text.pug", "patterns": [ @@ -272,10 +272,10 @@ "begin": "^(\\s*)(?:(?=\\.$)|(?:(?=[\\w.#].*?\\.$)(?=(?:(?:(?:(?:(?:#[\\w-]+)|(?:\\.[\\w-]+))|(?:(?:[#!]\\{[^}]*\\})|(?:\\w(?:(?:[\\w:-]+[\\w-])|(?:[\\w-]*)))))(?:(?:#[\\w-]+)|(?:\\.[\\w-]+)|(?:\\((?:[^()\\'\\\"]*(?:(?:\\'(?:[^\\']|(?:(??/])|\\))", "name": "attribute_value", "patterns": [ - { - "include": "#string" - }, { "include": "#js_parens" }, @@ -758,9 +752,6 @@ "end": "$|(?=,|(?:\\s+[^!%&*\\-+~|<>?/])|\\))", "name": "attribute_value2", "patterns": [ - { - "include": "#string" - }, { "include": "#js_parens" }, @@ -979,23 +970,6 @@ } ] }, - "string": { - "begin": "(['\"])", - "end": "(?]*>)", "end": "$|(?=>)", diff --git a/extensions/references-view/package.nls.json b/extensions/references-view/package.nls.json index 0fed0b80fd5..a1a4b202a0f 100644 --- a/extensions/references-view/package.nls.json +++ b/extensions/references-view/package.nls.json @@ -5,7 +5,7 @@ "config.references.preferredLocation.peek": "Show references in peek editor.", "config.references.preferredLocation.view": "Show references in separate view.", "container.title": "References", - "view.title": "Results", + "view.title": "Reference Search Results", "cmd.category.references": "References", "cmd.references-view.findReferences": "Find All References", "cmd.references-view.findImplementations": "Find All Implementations", diff --git a/extensions/shellscript/cgmanifest.json b/extensions/shellscript/cgmanifest.json index e6df65116de..1b54ec84ee5 100644 --- a/extensions/shellscript/cgmanifest.json +++ b/extensions/shellscript/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "jeff-hykin/better-shell-syntax", "repositoryUrl": "https://github.com/jeff-hykin/better-shell-syntax", - "commitHash": "ab3c6da1c3651dff20651ebcf0ec5adb5fe413a0" + "commitHash": "f0becead09678ee025faef6bc062b33fab60274b" } }, "license": "MIT", - "version": "1.3.3" + "version": "1.5.0" } ], "version": 1 diff --git a/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json b/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json index 261d0529c2e..463517c92ee 100644 --- a/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json +++ b/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jeff-hykin/better-shell-syntax/commit/ab3c6da1c3651dff20651ebcf0ec5adb5fe413a0", + "version": "https://github.com/jeff-hykin/better-shell-syntax/commit/f0becead09678ee025faef6bc062b33fab60274b", "name": "Shell Script", "scopeName": "source.shell", "patterns": [ @@ -14,8 +14,8 @@ ], "repository": { "alias_statement": { - "begin": "(alias)\\s*+\\s*+(?:((?<=^|;|&|\\s)(?:export|declare|typeset|local|readonly)(?=\\s|;|&|$))\\s*+)?((?\\(\\)\\$`\\\\\"\\|]+(?!>))", + "match": "[ \\t]*+([^ \t\n'&;<>\\(\\)\\$`\\\\\"\\|]+(?!>))", "captures": { "1": { "name": "string.unquoted.argument.shell", @@ -112,14 +112,14 @@ } }, { - "include": "#statement_context" + "include": "#normal_statement_context" } ] }, "assignment": { "patterns": [ { - "begin": "\\s*+(?:((?<=^|;|&|\\s)(?:export|declare|typeset|local|readonly)(?=\\s|;|&|$))\\s*+)?((?|#|\\n|$|;|[ \\t]))(?!foreach\\b(?!\\/)|select\\b(?!\\/)|repeat\\b(?!\\/)|until\\b(?!\\/)|while\\b(?!\\/)|case\\b(?!\\/)|done\\b(?!\\/)|elif\\b(?!\\/)|else\\b(?!\\/)|esac\\b(?!\\/)|then\\b(?!\\/)|for\\b(?!\\/)|end\\b(?!\\/)|in\\b(?!\\/)|fi\\b(?!\\/)|do\\b(?!\\/)|if\\b(?!\\/))(?:((?<=^|;|&|[ \\t])(?:export|declare|typeset|local|readonly)(?=[ \\t]|;|&|$))|((?!\"|'|\\\\\\n?$)[^!'\" \\t\\n\\r]+?))(?:(?= |\\t)|(?=;|\\||&|\\n|\\)|\\`|\\{|\\}|[ \\t]*#|\\])(?|#|\\n|$|;|\\s))(?:\\s*+([^ \n'&;<>\\(\\)\\$`\\\\\"\\|]+(?!>)))?(?:(?:\\$')|'))|(\\s*+(?!(?:!|%|&|\\||\\(|\\)|\\{|\\[|<|>|#|\\n|$|;|\\s))(?:\\s*+([^ \n'&;<>\\(\\)\\$`\\\\\"\\|]+(?!>)))?(?:(?:\\$\")|\")))", - "end": "(?=;|\\||&|\\n|\\)|\\`|\\{|\\}| *#|\\])(?|#|\\n|$|;|\\s))(?:((?<=^|;|&|\\s)(?:export|declare|typeset|local|readonly)(?=\\s|;|&|$))|((?!\\\\\\n?$)(?:(?:\\$?\")|(?:.+?))))(?:(?=\\s)|(?=;|\\||&|\\n|\\)|\\`|\\{|\\}| *#|\\])(?|#|\\n|$|;|\\s))(?:((?<=^|;|&|\\s)(?:export|declare|typeset|local|readonly)(?=\\s|;|&|$))|((?!\\\\\\n?$)(?:(?:\\$?\")|(?:.+?))))(?:(?=\\s)|(?=;|\\||&|\\n|\\)|\\`|\\{|\\}| *#|\\])(?|#|\\n|$|;|[ \\t]))(?!foreach\\b(?!\\/)|select\\b(?!\\/)|repeat\\b(?!\\/)|until\\b(?!\\/)|while\\b(?!\\/)|case\\b(?!\\/)|done\\b(?!\\/)|elif\\b(?!\\/)|else\\b(?!\\/)|esac\\b(?!\\/)|then\\b(?!\\/)|for\\b(?!\\/)|end\\b(?!\\/)|in\\b(?!\\/)|fi\\b(?!\\/)|do\\b(?!\\/)|if\\b(?!\\/))(?!\\\\\\n?$)", + "end": "(?=;|\\||&|\\n|\\)|\\`|\\{|\\}|[ \\t]*#|\\])(?|#|\\n|$|;|\\s)))", - "end": "(?:(?=\\s)|(?=;|\\||&|\\n|\\)|\\`|\\{|\\}| *#|\\])(?|#|\\n|$|;|[ \\t])))", + "end": "(?:(?=[ \\t])|(?=;|\\||&|\\n|\\)|\\`|\\{|\\}|[ \\t]*#|\\])(?)", + "match": "(?<=[ \\t])(?:(1)|(2)|(\\d+))(?=>)", "captures": { "1": { "name": "keyword.operator.redirect.stdout.shell" @@ -1880,12 +1924,12 @@ ] }, "simple_options": { - "match": "(?:\\s++\\-\\w+)*", + "match": "(?:[ \\t]++\\-\\w+)*", "captures": { "0": { "patterns": [ { - "match": "\\s++(\\-)(\\w+)", + "match": "[ \\t]++(\\-)(\\w+)", "captures": { "1": { "name": "string.unquoted.argument.shell constant.other.option.dash.shell" @@ -1899,8 +1943,11 @@ } } }, + "start_of_command": { + "match": "[ \\t]*+(?!(?:!|%|&|\\||\\(|\\)|\\{|\\[|<|>|#|\\n|$|;|[ \\t]))(?!foreach\\b(?!\\/)|select\\b(?!\\/)|repeat\\b(?!\\/)|until\\b(?!\\/)|while\\b(?!\\/)|case\\b(?!\\/)|done\\b(?!\\/)|elif\\b(?!\\/)|else\\b(?!\\/)|esac\\b(?!\\/)|then\\b(?!\\/)|for\\b(?!\\/)|end\\b(?!\\/)|in\\b(?!\\/)|fi\\b(?!\\/)|do\\b(?!\\/)|if\\b(?!\\/))(?!\\\\\\n?$)" + }, "start_of_double_quoted_command_name": { - "match": "\\s*+(?!(?:!|%|&|\\||\\(|\\)|\\{|\\[|<|>|#|\\n|$|;|\\s))(?:\\s*+([^ \n'&;<>\\(\\)\\$`\\\\\"\\|]+(?!>)))?(?:(?:\\$\")|\")", + "match": "(?!(?:!|%|&|\\||\\(|\\)|\\{|\\[|<|>|#|\\n|$|;|[ \\t]))(?:[ \\t]*+([^ \t\n'&;<>\\(\\)\\$`\\\\\"\\|]+(?!>)))?(?:(?:\\$\")|\")", "captures": { "1": { "name": "entity.name.command.shell", @@ -1926,10 +1973,10 @@ ] } }, - "name": "meta.command_name.quoted.shell string.quoted.double.shell punctuation.definition.string.begin.shell entity.name.command.shell" + "name": "meta.statement.command.name.quoted.shell string.quoted.double.shell punctuation.definition.string.begin.shell entity.name.command.shell" }, "start_of_single_quoted_command_name": { - "match": "\\s*+(?!(?:!|%|&|\\||\\(|\\)|\\{|\\[|<|>|#|\\n|$|;|\\s))(?:\\s*+([^ \n'&;<>\\(\\)\\$`\\\\\"\\|]+(?!>)))?(?:(?:\\$')|')", + "match": "(?!(?:!|%|&|\\||\\(|\\)|\\{|\\[|<|>|#|\\n|$|;|[ \\t]))(?:[ \\t]*+([^ \t\n'&;<>\\(\\)\\$`\\\\\"\\|]+(?!>)))?(?:(?:\\$')|')", "captures": { "1": { "name": "entity.name.command.shell", @@ -1955,76 +2002,7 @@ ] } }, - "name": "meta.command_name.quoted.shell string.quoted.single.shell punctuation.definition.string.begin.shell entity.name.command.shell" - }, - "statement_context": { - "patterns": [ - { - "include": "#comment" - }, - { - "include": "#pipeline" - }, - { - "include": "#statement_seperator" - }, - { - "include": "#misc_ranges" - }, - { - "include": "#boolean" - }, - { - "include": "#redirect_number" - }, - { - "include": "#numeric_literal" - }, - { - "include": "#string" - }, - { - "include": "#variable" - }, - { - "include": "#interpolation" - }, - { - "include": "#heredoc" - }, - { - "include": "#herestring" - }, - { - "include": "#redirection" - }, - { - "include": "#pathname" - }, - { - "include": "#keyword" - }, - { - "include": "#support" - } - ] - }, - "statement_seperator": { - "match": "(?:(?:(?:(?:(;)|(&&))|(\\|\\|))|(&))|\\n)", - "captures": { - "1": { - "name": "punctuation.terminator.statement.semicolon.shell" - }, - "2": { - "name": "punctuation.separator.statement.and.shell" - }, - "3": { - "name": "punctuation.separator.statement.or.shell" - }, - "4": { - "name": "punctuation.separator.statement.background.shell" - } - } + "name": "meta.statement.command.name.quoted.shell string.quoted.single.shell punctuation.definition.string.begin.shell entity.name.command.shell" }, "string": { "patterns": [ @@ -2141,17 +2119,6 @@ } } }, - { - "match": "(\\$)(\\{[0-9]+\\}(?!\\w))", - "captures": { - "1": { - "name": "punctuation.definition.variable.shell variable.parameter.positional.shell" - }, - "2": { - "name": "variable.parameter.positional.shell" - } - } - }, { "match": "(\\$)([-*#?$!0_](?!\\w))", "captures": { @@ -2164,21 +2131,22 @@ } }, { - "begin": "(\\$)(\\{)", + "begin": "(\\$)(\\{)[ \\t]*+(?=\\d)", "end": "\\}", "beginCaptures": { "1": { - "name": "punctuation.definition.variable.shell punctuation.section.bracket.curly.variable.begin.shell" + "name": "punctuation.definition.variable.shell variable.parameter.positional.shell" }, "2": { - "name": "punctuation.section.bracket.curly.variable.begin.shell" + "name": "punctuation.section.bracket.curly.variable.begin.shell punctuation.definition.variable.shell variable.parameter.positional.shell" } }, "endCaptures": { "0": { - "name": "punctuation.section.bracket.curly.variable.end.shell" + "name": "punctuation.section.bracket.curly.variable.end.shell punctuation.definition.variable.shell variable.parameter.positional.shell" } }, + "contentName": "meta.parameter-expansion", "patterns": [ { "match": "!|:[-=?]?|\\*|@|##|#|%%|%|\\/", @@ -2195,6 +2163,59 @@ } } }, + { + "match": "[0-9]+", + "name": "variable.parameter.positional.shell" + }, + { + "match": "(?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?:&|{\\?]|$|;|^\\s*$|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", + "end": "(?=[,);}\\]=>:&|{\\?]|(extends\\s+)|$|;|^\\s*$|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ + { + "include": "#type-arguments" + }, { "include": "#expression" } @@ -3837,7 +3846,7 @@ "name": "keyword.operator.type.annotation.ts" } }, - "end": "(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + "end": "(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", "patterns": [ { "include": "#type" @@ -3852,7 +3861,7 @@ "name": "keyword.operator.type.annotation.ts" } }, - "end": "(?])|(?=^\\s*$)|((?<=\\S)(?=\\s*$))|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + "end": "(?])|(?=^\\s*$)|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", "patterns": [ { "include": "#type" @@ -4699,20 +4708,20 @@ "include": "#template-call" }, { - "name": "string.template.ts", + "contentName": "string.template.ts", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?(`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.ts" }, "2": { - "name": "punctuation.definition.string.template.begin.ts" + "name": "string.template.ts punctuation.definition.string.template.begin.ts" } }, "end": "`", "endCaptures": { "0": { - "name": "punctuation.definition.string.template.end.ts" + "name": "string.template.ts punctuation.definition.string.template.end.ts" } }, "patterns": [ @@ -4729,7 +4738,6 @@ "template-call": { "patterns": [ { - "name": "string.template.ts", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)", "end": "(?=`)", "patterns": [ @@ -4752,7 +4760,6 @@ ] }, { - "name": "string.template.ts", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?\\s*(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)`)", "beginCaptures": { "1": { @@ -4808,20 +4815,20 @@ "include": "#template-call" }, { - "name": "string.template.ts", + "contentName": "string.template.ts", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?(`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.ts" }, "2": { - "name": "punctuation.definition.string.template.begin.ts" + "name": "string.template.ts punctuation.definition.string.template.begin.ts" } }, "end": "`", "endCaptures": { "0": { - "name": "punctuation.definition.string.template.end.ts" + "name": "string.template.ts punctuation.definition.string.template.end.ts" } }, "patterns": [ diff --git a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json index 5f4c6aae7ef..bc4348140b5 100644 --- a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/8e4e371fe8dd57560b16a44474f8cf8ca981e715", + "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/0d73d1117e0a9b1d6635ebbe9aa37d615171b02d", "name": "TypeScriptReact", "scopeName": "source.tsx", "patterns": [ @@ -989,6 +989,9 @@ }, { "include": "#parameter-binding-element" + }, + { + "include": "#paren-expression" } ] }, @@ -1171,7 +1174,7 @@ "name": "keyword.operator.assignment.tsx" } }, - "end": "(?=[,);}\\]]|((?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?:&|{\\?]|$|;|^\\s*$|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", + "end": "(?=[,);}\\]=>:&|{\\?]|(extends\\s+)|$|;|^\\s*$|(?:^\\s*(?:abstract|async|class|const|declare|enum|export|function|import|interface|let|module|namespace|return|type|var)\\b))", "patterns": [ + { + "include": "#type-arguments" + }, { "include": "#expression" } @@ -3788,7 +3797,7 @@ "name": "keyword.operator.type.annotation.tsx" } }, - "end": "(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + "end": "(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", "patterns": [ { "include": "#type" @@ -3803,7 +3812,7 @@ "name": "keyword.operator.type.annotation.tsx" } }, - "end": "(?])|(?=^\\s*$)|((?<=\\S)(?=\\s*$))|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", + "end": "(?])|(?=^\\s*$)|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))", "patterns": [ { "include": "#type" @@ -4650,20 +4659,20 @@ "include": "#template-call" }, { - "name": "string.template.tsx", + "contentName": "string.template.tsx", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?(`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.tsx" }, "2": { - "name": "punctuation.definition.string.template.begin.tsx" + "name": "string.template.tsx punctuation.definition.string.template.begin.tsx" } }, "end": "`", "endCaptures": { "0": { - "name": "punctuation.definition.string.template.end.tsx" + "name": "string.template.tsx punctuation.definition.string.template.end.tsx" } }, "patterns": [ @@ -4680,7 +4689,6 @@ "template-call": { "patterns": [ { - "name": "string.template.tsx", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)", "end": "(?=`)", "patterns": [ @@ -4703,7 +4711,6 @@ ] }, { - "name": "string.template.tsx", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?\\s*(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)`)", "beginCaptures": { "1": { @@ -4759,20 +4766,20 @@ "include": "#template-call" }, { - "name": "string.template.tsx", + "contentName": "string.template.tsx", "begin": "([_$[:alpha:]][_$[:alnum:]]*)?(`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.tsx" }, "2": { - "name": "punctuation.definition.string.template.begin.tsx" + "name": "string.template.tsx punctuation.definition.string.template.begin.tsx" } }, "end": "`", "endCaptures": { "0": { - "name": "punctuation.definition.string.template.end.tsx" + "name": "string.template.tsx punctuation.definition.string.template.end.tsx" } }, "patterns": [ diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index fdf08f0d41a..d489483363d 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -47,7 +47,7 @@ "typescript.referencesCodeLens.showOnAllFunctions": "Enable/disable references CodeLens on all functions in TypeScript files.", "typescript.implementationsCodeLens.enabled": "Enable/disable implementations CodeLens. This CodeLens shows the implementers of an interface.", "typescript.openTsServerLog.title": "Open TS Server log", - "typescript.restartTsServer": "Restart TS server", + "typescript.restartTsServer": "Restart TS Server", "typescript.selectTypeScriptVersion.title": "Select TypeScript Version...", "typescript.reportStyleChecksAsWarnings": "Report style checks as warnings.", "typescript.npm": "Specifies the path to the npm executable used for [Automatic Type Acquisition](https://code.visualstudio.com/docs/nodejs/working-with-javascript#_typings-and-automatic-type-acquisition).", diff --git a/extensions/typescript-language-features/src/api.ts b/extensions/typescript-language-features/src/api.ts index 67ca8be1cf7..5c408f6f29b 100644 --- a/extensions/typescript-language-features/src/api.ts +++ b/extensions/typescript-language-features/src/api.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { PluginManager } from './utils/plugins'; +import { PluginManager } from './tsServer/plugins'; class ApiV0 { public constructor( diff --git a/extensions/typescript-language-features/src/commands/configurePlugin.ts b/extensions/typescript-language-features/src/commands/configurePlugin.ts index f781c4a50fa..356738294ad 100644 --- a/extensions/typescript-language-features/src/commands/configurePlugin.ts +++ b/extensions/typescript-language-features/src/commands/configurePlugin.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { PluginManager } from '../utils/plugins'; +import { PluginManager } from '../tsServer/plugins'; import { Command } from './commandManager'; export class ConfigurePluginCommand implements Command { diff --git a/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts b/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts index fde3a4e40db..0222f32aae8 100644 --- a/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts +++ b/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import TypeScriptServiceClientHost from '../typeScriptServiceClientHost'; -import { ActiveJsTsEditorTracker } from '../utils/activeJsTsEditorTracker'; +import { ActiveJsTsEditorTracker } from '../ui/activeJsTsEditorTracker'; import { Lazy } from '../utils/lazy'; -import { openProjectConfigForFile, ProjectType } from '../utils/tsconfig'; +import { openProjectConfigForFile, ProjectType } from '../tsconfig'; import { Command } from './commandManager'; export class TypeScriptGoToProjectConfigCommand implements Command { diff --git a/extensions/typescript-language-features/src/commands/index.ts b/extensions/typescript-language-features/src/commands/index.ts index 4b6f8d36ac3..919b1b749c5 100644 --- a/extensions/typescript-language-features/src/commands/index.ts +++ b/extensions/typescript-language-features/src/commands/index.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import TypeScriptServiceClientHost from '../typeScriptServiceClientHost'; -import { ActiveJsTsEditorTracker } from '../utils/activeJsTsEditorTracker'; +import { ActiveJsTsEditorTracker } from '../ui/activeJsTsEditorTracker'; import { Lazy } from '../utils/lazy'; -import { PluginManager } from '../utils/plugins'; +import { PluginManager } from '../tsServer/plugins'; import { CommandManager } from './commandManager'; import { ConfigurePluginCommand } from './configurePlugin'; import { JavaScriptGoToProjectConfigCommand, TypeScriptGoToProjectConfigCommand } from './goToProjectConfiguration'; diff --git a/extensions/typescript-language-features/src/commands/learnMoreAboutRefactorings.ts b/extensions/typescript-language-features/src/commands/learnMoreAboutRefactorings.ts index c1c21f363ee..212307f2cd8 100644 --- a/extensions/typescript-language-features/src/commands/learnMoreAboutRefactorings.ts +++ b/extensions/typescript-language-features/src/commands/learnMoreAboutRefactorings.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { isTypeScriptDocument } from '../utils/languageIds'; +import { isTypeScriptDocument } from '../configuration/languageIds'; import { Command } from './commandManager'; export class LearnMoreAboutRefactoringsCommand implements Command { diff --git a/extensions/typescript-language-features/src/utils/configuration.browser.ts b/extensions/typescript-language-features/src/configuration/configuration.browser.ts similarity index 100% rename from extensions/typescript-language-features/src/utils/configuration.browser.ts rename to extensions/typescript-language-features/src/configuration/configuration.browser.ts diff --git a/extensions/typescript-language-features/src/utils/configuration.electron.ts b/extensions/typescript-language-features/src/configuration/configuration.electron.ts similarity index 100% rename from extensions/typescript-language-features/src/utils/configuration.electron.ts rename to extensions/typescript-language-features/src/configuration/configuration.electron.ts diff --git a/extensions/typescript-language-features/src/utils/configuration.ts b/extensions/typescript-language-features/src/configuration/configuration.ts similarity index 97% rename from extensions/typescript-language-features/src/utils/configuration.ts rename to extensions/typescript-language-features/src/configuration/configuration.ts index 2436aae8368..4fb86157ce8 100644 --- a/extensions/typescript-language-features/src/utils/configuration.ts +++ b/extensions/typescript-language-features/src/configuration/configuration.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import * as Proto from '../tsServer/protocol/protocol'; import * as objects from '../utils/objects'; -import * as Proto from '../protocol'; export enum TsServerLogLevel { Off, @@ -200,7 +200,9 @@ export abstract class BaseServiceConfigurationProvider implements ServiceConfigu } protected readWatchOptions(configuration: vscode.WorkspaceConfiguration): Proto.WatchOptions | undefined { - return configuration.get('typescript.tsserver.watchOptions'); + const watchOptions = configuration.get('typescript.tsserver.watchOptions'); + // Returned value may be a proxy. Clone it into a normal object + return { ...(watchOptions ?? {}) }; } protected readIncludePackageJsonAutoImports(configuration: vscode.WorkspaceConfiguration): 'auto' | 'on' | 'off' | undefined { diff --git a/extensions/typescript-language-features/src/utils/documentSelector.ts b/extensions/typescript-language-features/src/configuration/documentSelector.ts similarity index 100% rename from extensions/typescript-language-features/src/utils/documentSelector.ts rename to extensions/typescript-language-features/src/configuration/documentSelector.ts diff --git a/extensions/typescript-language-features/src/utils/fileSchemes.ts b/extensions/typescript-language-features/src/configuration/fileSchemes.ts similarity index 96% rename from extensions/typescript-language-features/src/utils/fileSchemes.ts rename to extensions/typescript-language-features/src/configuration/fileSchemes.ts index 66d9b0aa3f3..b255f6de89c 100644 --- a/extensions/typescript-language-features/src/utils/fileSchemes.ts +++ b/extensions/typescript-language-features/src/configuration/fileSchemes.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { isWeb } from './platform'; import * as vscode from 'vscode'; +import { isWeb } from '../utils/platform'; export const file = 'file'; export const untitled = 'untitled'; diff --git a/extensions/typescript-language-features/src/utils/languageDescription.ts b/extensions/typescript-language-features/src/configuration/languageDescription.ts similarity index 100% rename from extensions/typescript-language-features/src/utils/languageDescription.ts rename to extensions/typescript-language-features/src/configuration/languageDescription.ts diff --git a/extensions/typescript-language-features/src/utils/languageIds.ts b/extensions/typescript-language-features/src/configuration/languageIds.ts similarity index 100% rename from extensions/typescript-language-features/src/utils/languageIds.ts rename to extensions/typescript-language-features/src/configuration/languageIds.ts diff --git a/extensions/typescript-language-features/src/utils/schemes.ts b/extensions/typescript-language-features/src/configuration/schemes.ts similarity index 100% rename from extensions/typescript-language-features/src/utils/schemes.ts rename to extensions/typescript-language-features/src/configuration/schemes.ts diff --git a/extensions/typescript-language-features/src/experimentTelemetryReporter.ts b/extensions/typescript-language-features/src/experimentTelemetryReporter.ts index ddd643fbc88..8fd7ce4aa66 100644 --- a/extensions/typescript-language-features/src/experimentTelemetryReporter.ts +++ b/extensions/typescript-language-features/src/experimentTelemetryReporter.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from 'vscode'; import VsCodeTelemetryReporter from '@vscode/extension-telemetry'; +import * as vscode from 'vscode'; import * as tas from 'vscode-tas-client'; export interface IExperimentationTelemetryReporter extends tas.IExperimentationTelemetry, vscode.Disposable { diff --git a/extensions/typescript-language-features/src/extension.browser.ts b/extensions/typescript-language-features/src/extension.browser.ts index 517c6f81d4b..5098231005a 100644 --- a/extensions/typescript-language-features/src/extension.browser.ts +++ b/extensions/typescript-language-features/src/extension.browser.ts @@ -11,18 +11,18 @@ import { registerBaseCommands } from './commands/index'; import { ExperimentationTelemetryReporter, IExperimentationTelemetryReporter } from './experimentTelemetryReporter'; import { createLazyClientHost, lazilyActivateClient } from './lazyClientHost'; import RemoteRepositories from './remoteRepositories.browser'; +import { API } from './tsServer/api'; import { noopRequestCancellerFactory } from './tsServer/cancellation'; import { noopLogDirectoryProvider } from './tsServer/logDirectoryProvider'; import { WorkerServerProcessFactory } from './tsServer/serverProcess.browser'; import { ITypeScriptVersionProvider, TypeScriptVersion, TypeScriptVersionSource } from './tsServer/versionProvider'; -import { ActiveJsTsEditorTracker } from './utils/activeJsTsEditorTracker'; -import API from './utils/api'; -import { TypeScriptServiceConfiguration } from './utils/configuration'; -import { BrowserServiceConfigurationProvider } from './utils/configuration.browser'; -import { Logger } from './utils/logger'; +import { ActiveJsTsEditorTracker } from './ui/activeJsTsEditorTracker'; +import { TypeScriptServiceConfiguration } from './configuration/configuration'; +import { BrowserServiceConfigurationProvider } from './configuration/configuration.browser'; +import { Logger } from './logging/logger'; import { getPackageInfo } from './utils/packageInfo'; import { isWebAndHasSharedArrayBuffers } from './utils/platform'; -import { PluginManager } from './utils/plugins'; +import { PluginManager } from './tsServer/plugins'; class StaticVersionProvider implements ITypeScriptVersionProvider { @@ -59,7 +59,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { new TypeScriptVersion( TypeScriptVersionSource.Bundled, vscode.Uri.joinPath(context.extensionUri, 'dist/browser/typescript/tsserver.web.js').toString(), - API.fromSimpleString('4.9.3'))); + API.fromSimpleString('5.0.1'))); let experimentTelemetryReporter: IExperimentationTelemetryReporter | undefined; const packageInfo = getPackageInfo(context); diff --git a/extensions/typescript-language-features/src/extension.ts b/extensions/typescript-language-features/src/extension.ts index b4072aadfd4..c92617f80a2 100644 --- a/extensions/typescript-language-features/src/extension.ts +++ b/extensions/typescript-language-features/src/extension.ts @@ -16,13 +16,13 @@ import { nodeRequestCancellerFactory } from './tsServer/cancellation.electron'; import { NodeLogDirectoryProvider } from './tsServer/logDirectoryProvider.electron'; import { ElectronServiceProcessFactory } from './tsServer/serverProcess.electron'; import { DiskTypeScriptVersionProvider } from './tsServer/versionProvider.electron'; +import { ActiveJsTsEditorTracker } from './ui/activeJsTsEditorTracker'; import { JsWalkthroughState, registerJsNodeWalkthrough } from './ui/jsNodeWalkthrough.electron'; -import { ActiveJsTsEditorTracker } from './utils/activeJsTsEditorTracker'; -import { ElectronServiceConfigurationProvider } from './utils/configuration.electron'; -import { onCaseInsensitiveFileSystem } from './utils/fileSystem.electron'; -import { Logger } from './utils/logger'; +import { ElectronServiceConfigurationProvider } from './configuration/configuration.electron'; +import { onCaseInsensitiveFileSystem } from './utils/fs.electron'; +import { Logger } from './logging/logger'; import { getPackageInfo } from './utils/packageInfo'; -import { PluginManager } from './utils/plugins'; +import { PluginManager } from './tsServer/plugins'; import * as temp from './utils/temp.electron'; export function activate( diff --git a/extensions/typescript-language-features/src/languageFeatures/callHierarchy.ts b/extensions/typescript-language-features/src/languageFeatures/callHierarchy.ts index 8cd56a01fbd..00adb9407c8 100644 --- a/extensions/typescript-language-features/src/languageFeatures/callHierarchy.ts +++ b/extensions/typescript-language-features/src/languageFeatures/callHierarchy.ts @@ -5,14 +5,14 @@ import * as path from 'path'; import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; -import * as PConst from '../protocol.const'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { API } from '../tsServer/api'; +import { parseKindModifier } from '../tsServer/protocol/modifiers'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as PConst from '../tsServer/protocol/protocol.const'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; -import { conditionalRegistration, requireMinVersion, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import { parseKindModifier } from '../utils/modifiers'; -import * as typeConverters from '../utils/typeConverters'; +import { conditionalRegistration, requireMinVersion, requireSomeCapability } from './util/dependentRegistration'; class TypeScriptCallHierarchySupport implements vscode.CallHierarchyProvider { public static readonly minVersion = API.v380; diff --git a/extensions/typescript-language-features/src/languageFeatures/codeLens/baseCodeLensProvider.ts b/extensions/typescript-language-features/src/languageFeatures/codeLens/baseCodeLensProvider.ts index 218424264d5..7c970e4212c 100644 --- a/extensions/typescript-language-features/src/languageFeatures/codeLens/baseCodeLensProvider.ts +++ b/extensions/typescript-language-features/src/languageFeatures/codeLens/baseCodeLensProvider.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../../protocol'; import { CachedResponse } from '../../tsServer/cachedResponse'; +import type * as Proto from '../../tsServer/protocol/protocol'; +import * as typeConverters from '../../typeConverters'; import { ITypeScriptServiceClient } from '../../typescriptService'; import { escapeRegExp } from '../../utils/regexp'; -import * as typeConverters from '../../utils/typeConverters'; export class ReferencesCodeLens extends vscode.CodeLens { diff --git a/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts b/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts index 0941a506ddb..b0346c8572b 100644 --- a/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts +++ b/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../../protocol'; -import * as PConst from '../../protocol.const'; +import { DocumentSelector } from '../../configuration/documentSelector'; +import { LanguageDescription } from '../../configuration/languageDescription'; import { CachedResponse } from '../../tsServer/cachedResponse'; +import type * as Proto from '../../tsServer/protocol/protocol'; +import * as PConst from '../../tsServer/protocol/protocol.const'; +import * as typeConverters from '../../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../../typescriptService'; -import { conditionalRegistration, requireGlobalConfiguration, requireSomeCapability } from '../../utils/dependentRegistration'; -import { DocumentSelector } from '../../utils/documentSelector'; -import { LanguageDescription } from '../../utils/languageDescription'; -import * as typeConverters from '../../utils/typeConverters'; -import { getSymbolRange, ReferencesCodeLens, TypeScriptBaseCodeLensProvider } from './baseCodeLensProvider'; +import { conditionalRegistration, requireGlobalConfiguration, requireSomeCapability } from '../util/dependentRegistration'; +import { ReferencesCodeLens, TypeScriptBaseCodeLensProvider, getSymbolRange } from './baseCodeLensProvider'; export default class TypeScriptImplementationsCodeLensProvider extends TypeScriptBaseCodeLensProvider { diff --git a/extensions/typescript-language-features/src/languageFeatures/codeLens/referencesCodeLens.ts b/extensions/typescript-language-features/src/languageFeatures/codeLens/referencesCodeLens.ts index 2a89bd6c127..d76db9f9b18 100644 --- a/extensions/typescript-language-features/src/languageFeatures/codeLens/referencesCodeLens.ts +++ b/extensions/typescript-language-features/src/languageFeatures/codeLens/referencesCodeLens.ts @@ -4,16 +4,16 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../../protocol'; -import * as PConst from '../../protocol.const'; +import { DocumentSelector } from '../../configuration/documentSelector'; +import { LanguageDescription } from '../../configuration/languageDescription'; import { CachedResponse } from '../../tsServer/cachedResponse'; +import type * as Proto from '../../tsServer/protocol/protocol'; +import * as PConst from '../../tsServer/protocol/protocol.const'; import { ExecutionTarget } from '../../tsServer/server'; +import * as typeConverters from '../../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../../typescriptService'; -import { conditionalRegistration, requireGlobalConfiguration, requireSomeCapability } from '../../utils/dependentRegistration'; -import { DocumentSelector } from '../../utils/documentSelector'; -import { LanguageDescription } from '../../utils/languageDescription'; -import * as typeConverters from '../../utils/typeConverters'; -import { getSymbolRange, ReferencesCodeLens, TypeScriptBaseCodeLensProvider } from './baseCodeLensProvider'; +import { conditionalRegistration, requireGlobalConfiguration, requireSomeCapability } from '../util/dependentRegistration'; +import { ReferencesCodeLens, TypeScriptBaseCodeLensProvider, getSymbolRange } from './baseCodeLensProvider'; export class TypeScriptReferencesCodeLensProvider extends TypeScriptBaseCodeLensProvider { diff --git a/extensions/typescript-language-features/src/languageFeatures/completions.ts b/extensions/typescript-language-features/src/languageFeatures/completions.ts index 3e3fd930bfd..9a6d8adffc9 100644 --- a/extensions/typescript-language-features/src/languageFeatures/completions.ts +++ b/extensions/typescript-language-features/src/languageFeatures/completions.ts @@ -5,22 +5,22 @@ import * as vscode from 'vscode'; import { Command, CommandManager } from '../commands/commandManager'; -import type * as Proto from '../protocol'; -import * as PConst from '../protocol.const'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { LanguageDescription } from '../configuration/languageDescription'; +import { TelemetryReporter } from '../logging/telemetry'; +import { API } from '../tsServer/api'; +import { parseKindModifier } from '../tsServer/protocol/modifiers'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as PConst from '../tsServer/protocol/protocol.const'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient, ServerResponse } from '../typescriptService'; -import API from '../utils/api'; +import TypingsStatus from '../ui/typingsStatus'; import { nulToken } from '../utils/cancellation'; -import { applyCodeAction } from '../utils/codeAction'; -import { conditionalRegistration, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import { LanguageDescription } from '../utils/languageDescription'; -import { parseKindModifier } from '../utils/modifiers'; -import * as Previewer from '../utils/previewer'; -import { snippetForFunctionCall } from '../utils/snippetForFunctionCall'; -import { TelemetryReporter } from '../utils/telemetry'; -import * as typeConverters from '../utils/typeConverters'; -import TypingsStatus from '../utils/typingsStatus'; import FileConfigurationManager from './fileConfigurationManager'; +import { applyCodeAction } from './util/codeAction'; +import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration'; +import { snippetForFunctionCall } from './util/snippetForFunctionCall'; +import * as Previewer from './util/textRendering'; interface DotAccessorContext { @@ -63,19 +63,21 @@ class MyCompletionItem extends vscode.CompletionItem { ) { super(tsEntry.name, MyCompletionItem.convertKind(tsEntry.kind)); - if (tsEntry.source && tsEntry.hasAction) { + if (tsEntry.source && tsEntry.hasAction && client.apiVersion.lt(API.v490)) { // De-prioritze auto-imports // https://github.com/microsoft/vscode/issues/40311 this.sortText = '\uffff' + tsEntry.sortText; + } else { + this.sortText = tsEntry.sortText; + } + if (tsEntry.source && tsEntry.hasAction) { // Render "fancy" when source is a workspace path const qualifierCandidate = vscode.workspace.asRelativePath(tsEntry.source); if (qualifierCandidate !== tsEntry.source) { this.label = { label: tsEntry.name, description: qualifierCandidate }; } - } else { - this.sortText = tsEntry.sortText; } const { sourceDisplay, isSnippet } = tsEntry; @@ -303,7 +305,7 @@ class MyCompletionItem extends vscode.CompletionItem { detail: Proto.CompletionEntryDetails, filepath: string ): { command?: vscode.Command; additionalTextEdits?: vscode.TextEdit[] } { - if (!detail.codeActions || !detail.codeActions.length) { + if (!detail.codeActions?.length) { return {}; } diff --git a/extensions/typescript-language-features/src/languageFeatures/definitionProviderBase.ts b/extensions/typescript-language-features/src/languageFeatures/definitionProviderBase.ts index df005110b37..7ebf7c89288 100644 --- a/extensions/typescript-language-features/src/languageFeatures/definitionProviderBase.ts +++ b/extensions/typescript-language-features/src/languageFeatures/definitionProviderBase.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import * as typeConverters from '../typeConverters'; import { ITypeScriptServiceClient } from '../typescriptService'; -import * as typeConverters from '../utils/typeConverters'; export default class TypeScriptDefinitionProviderBase { diff --git a/extensions/typescript-language-features/src/languageFeatures/definitions.ts b/extensions/typescript-language-features/src/languageFeatures/definitions.ts index 5d3bf1bcf5a..d7de10b1add 100644 --- a/extensions/typescript-language-features/src/languageFeatures/definitions.ts +++ b/extensions/typescript-language-features/src/languageFeatures/definitions.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { DocumentSelector } from '../configuration/documentSelector'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import { conditionalRegistration, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import * as typeConverters from '../utils/typeConverters'; import DefinitionProviderBase from './definitionProviderBase'; +import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration'; export default class TypeScriptDefinitionProvider extends DefinitionProviderBase implements vscode.DefinitionProvider { diff --git a/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts b/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts index 0be4cb767b7..bd1eecd3f82 100644 --- a/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts +++ b/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { DiagnosticLanguage } from '../configuration/languageDescription'; import * as arrays from '../utils/arrays'; import { Disposable } from '../utils/dispose'; -import { DiagnosticLanguage } from '../utils/languageDescription'; import { ResourceMap } from '../utils/resourceMap'; function diagnosticsEquals(a: vscode.Diagnostic, b: vscode.Diagnostic): boolean { @@ -53,7 +53,7 @@ class FileDiagnostics { } const existing = this._diagnostics.get(kind); - if (arrays.equals(existing || arrays.empty, diagnostics, diagnosticsEquals)) { + if (existing?.length === 0 && diagnostics.length === 0) { // No need to update return false; } @@ -103,7 +103,7 @@ interface LanguageDiagnosticSettings { function areLanguageDiagnosticSettingsEqual(currentSettings: LanguageDiagnosticSettings, newSettings: LanguageDiagnosticSettings): boolean { return currentSettings.validate === newSettings.validate - && currentSettings.enableSuggestions && currentSettings.enableSuggestions; + && currentSettings.enableSuggestions === newSettings.enableSuggestions; } class DiagnosticSettings { diff --git a/extensions/typescript-language-features/src/languageFeatures/directiveCommentCompletions.ts b/extensions/typescript-language-features/src/languageFeatures/directiveCommentCompletions.ts index 8cbb9ba4d3e..aa972ceb199 100644 --- a/extensions/typescript-language-features/src/languageFeatures/directiveCommentCompletions.ts +++ b/extensions/typescript-language-features/src/languageFeatures/directiveCommentCompletions.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { API } from '../tsServer/api'; import { ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; -import { DocumentSelector } from '../utils/documentSelector'; interface Directive { diff --git a/extensions/typescript-language-features/src/languageFeatures/documentHighlight.ts b/extensions/typescript-language-features/src/languageFeatures/documentHighlight.ts index 8c6ce2d6317..b3489ecdbc5 100644 --- a/extensions/typescript-language-features/src/languageFeatures/documentHighlight.ts +++ b/extensions/typescript-language-features/src/languageFeatures/documentHighlight.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import { DocumentSelector } from '../configuration/documentSelector'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as typeConverters from '../typeConverters'; import { ITypeScriptServiceClient } from '../typescriptService'; -import { DocumentSelector } from '../utils/documentSelector'; -import * as typeConverters from '../utils/typeConverters'; class TypeScriptDocumentHighlightProvider implements vscode.DocumentHighlightProvider { public constructor( @@ -33,10 +33,7 @@ class TypeScriptDocumentHighlightProvider implements vscode.DocumentHighlightPro return []; } - return response.body - .filter(highlight => highlight.file === file) - .map(convertDocumentHighlight) - .flat(); + return response.body.flatMap(convertDocumentHighlight); } } diff --git a/extensions/typescript-language-features/src/languageFeatures/documentSymbol.ts b/extensions/typescript-language-features/src/languageFeatures/documentSymbol.ts index c197031c7ee..ef2d47ef942 100644 --- a/extensions/typescript-language-features/src/languageFeatures/documentSymbol.ts +++ b/extensions/typescript-language-features/src/languageFeatures/documentSymbol.ts @@ -4,13 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; -import * as PConst from '../protocol.const'; +import { DocumentSelector } from '../configuration/documentSelector'; import { CachedResponse } from '../tsServer/cachedResponse'; +import { parseKindModifier } from '../tsServer/protocol/modifiers'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as PConst from '../tsServer/protocol/protocol.const'; +import * as typeConverters from '../typeConverters'; import { ITypeScriptServiceClient } from '../typescriptService'; -import { DocumentSelector } from '../utils/documentSelector'; -import { parseKindModifier } from '../utils/modifiers'; -import * as typeConverters from '../utils/typeConverters'; const getSymbolKind = (kind: string): vscode.SymbolKind => { switch (kind) { diff --git a/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts b/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts index 4df07ef7d96..1ae33ab2e67 100644 --- a/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts +++ b/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts @@ -5,12 +5,12 @@ import * as path from 'path'; import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import type * as Proto from '../tsServer/protocol/protocol'; +import { API } from '../tsServer/api'; import { ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; import { Disposable } from '../utils/dispose'; -import * as fileSchemes from '../utils/fileSchemes'; -import { isTypeScriptDocument } from '../utils/languageIds'; +import * as fileSchemes from '../configuration/fileSchemes'; +import { isTypeScriptDocument } from '../configuration/languageIds'; import { equals } from '../utils/objects'; import { ResourceMap } from '../utils/resourceMap'; diff --git a/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts b/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts index 2e28a14c587..3a475ac257b 100644 --- a/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts +++ b/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts @@ -5,10 +5,10 @@ import * as vscode from 'vscode'; import { Command, CommandManager } from '../commands/commandManager'; +import { isSupportedLanguageMode } from '../configuration/languageIds'; +import { API } from '../tsServer/api'; +import * as typeConverters from '../typeConverters'; import { ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; -import { isSupportedLanguageMode } from '../utils/languageIds'; -import * as typeConverters from '../utils/typeConverters'; class FileReferencesCommand implements Command { diff --git a/extensions/typescript-language-features/src/languageFeatures/fixAll.ts b/extensions/typescript-language-features/src/languageFeatures/fixAll.ts index bfa9d2b36c7..690439218a8 100644 --- a/extensions/typescript-language-features/src/languageFeatures/fixAll.ts +++ b/extensions/typescript-language-features/src/languageFeatures/fixAll.ts @@ -4,16 +4,16 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { API } from '../tsServer/api'; +import * as errorCodes from '../tsServer/protocol/errorCodes'; +import * as fixNames from '../tsServer/protocol/fixNames'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; -import { conditionalRegistration, requireMinVersion, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import * as errorCodes from '../utils/errorCodes'; -import * as fixNames from '../utils/fixNames'; -import * as typeConverters from '../utils/typeConverters'; import { DiagnosticsManager } from './diagnostics'; import FileConfigurationManager from './fileConfigurationManager'; +import { conditionalRegistration, requireMinVersion, requireSomeCapability } from './util/dependentRegistration'; interface AutoFix { @@ -219,10 +219,6 @@ class TypeScriptAutoFixProvider implements vscode.CodeActionProvider { } const actions = this.getFixAllActions(context.only); - if (this.client.bufferSyncSupport.hasPendingDiagnostics(document.uri)) { - return actions; - } - const diagnostics = this.diagnosticsManager.getDiagnostics(document.uri); if (!diagnostics.length) { // Actions are a no-op in this case but we still want to return them diff --git a/extensions/typescript-language-features/src/languageFeatures/folding.ts b/extensions/typescript-language-features/src/languageFeatures/folding.ts index a633e6e97a0..b8401d4ad60 100644 --- a/extensions/typescript-language-features/src/languageFeatures/folding.ts +++ b/extensions/typescript-language-features/src/languageFeatures/folding.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import { DocumentSelector } from '../configuration/documentSelector'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as typeConverters from '../typeConverters'; import { ITypeScriptServiceClient } from '../typescriptService'; import { coalesce } from '../utils/arrays'; -import { DocumentSelector } from '../utils/documentSelector'; -import * as typeConverters from '../utils/typeConverters'; class TypeScriptFoldingProvider implements vscode.FoldingRangeProvider { diff --git a/extensions/typescript-language-features/src/languageFeatures/formatting.ts b/extensions/typescript-language-features/src/languageFeatures/formatting.ts index f2a17da6ede..3b31499c37b 100644 --- a/extensions/typescript-language-features/src/languageFeatures/formatting.ts +++ b/extensions/typescript-language-features/src/languageFeatures/formatting.ts @@ -4,13 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { LanguageDescription } from '../configuration/languageDescription'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as typeConverters from '../typeConverters'; import { ITypeScriptServiceClient } from '../typescriptService'; -import { conditionalRegistration, requireGlobalConfiguration } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import { LanguageDescription } from '../utils/languageDescription'; -import * as typeConverters from '../utils/typeConverters'; import FileConfigurationManager from './fileConfigurationManager'; +import { conditionalRegistration, requireGlobalConfiguration } from './util/dependentRegistration'; class TypeScriptFormattingProvider implements vscode.DocumentRangeFormattingEditProvider, vscode.OnTypeFormattingEditProvider { public constructor( diff --git a/extensions/typescript-language-features/src/languageFeatures/hover.ts b/extensions/typescript-language-features/src/languageFeatures/hover.ts index c6982dfed10..52ea91a846f 100644 --- a/extensions/typescript-language-features/src/languageFeatures/hover.ts +++ b/extensions/typescript-language-features/src/languageFeatures/hover.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import type * as Proto from '../tsServer/protocol/protocol'; import { ClientCapability, ITypeScriptServiceClient, ServerType } from '../typescriptService'; -import { conditionalRegistration, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import { markdownDocumentation } from '../utils/previewer'; -import * as typeConverters from '../utils/typeConverters'; +import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { markdownDocumentation } from './util/textRendering'; +import * as typeConverters from '../typeConverters'; import FileConfigurationManager from './fileConfigurationManager'; diff --git a/extensions/typescript-language-features/src/languageFeatures/implementations.ts b/extensions/typescript-language-features/src/languageFeatures/implementations.ts index bf3ddfee414..b6b8aac1d29 100644 --- a/extensions/typescript-language-features/src/languageFeatures/implementations.ts +++ b/extensions/typescript-language-features/src/languageFeatures/implementations.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { DocumentSelector } from '../configuration/documentSelector'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import { conditionalRegistration, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; import DefinitionProviderBase from './definitionProviderBase'; +import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration'; class TypeScriptImplementationProvider extends DefinitionProviderBase implements vscode.ImplementationProvider { public provideImplementation(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { diff --git a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts index 14d5ef8f4c9..263f8f3bd72 100644 --- a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts +++ b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { LanguageDescription } from '../configuration/languageDescription'; +import { API } from '../tsServer/api'; +import type * as Proto from '../tsServer/protocol/protocol'; +import { Position } from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; -import { conditionalRegistration, requireMinVersion, requireSomeCapability } from '../utils/dependentRegistration'; import { Disposable } from '../utils/dispose'; -import { DocumentSelector } from '../utils/documentSelector'; -import { LanguageDescription } from '../utils/languageDescription'; -import { Position } from '../utils/typeConverters'; -import FileConfigurationManager, { getInlayHintsPreferences, InlayHintSettingNames } from './fileConfigurationManager'; +import FileConfigurationManager, { InlayHintSettingNames, getInlayHintsPreferences } from './fileConfigurationManager'; +import { conditionalRegistration, requireMinVersion, requireSomeCapability } from './util/dependentRegistration'; const inlayHintSettingNames = Object.freeze([ diff --git a/extensions/typescript-language-features/src/languageFeatures/jsDocCompletions.ts b/extensions/typescript-language-features/src/languageFeatures/jsDocCompletions.ts index 9b96186a904..7da9129cff5 100644 --- a/extensions/typescript-language-features/src/languageFeatures/jsDocCompletions.ts +++ b/extensions/typescript-language-features/src/languageFeatures/jsDocCompletions.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { LanguageDescription } from '../configuration/languageDescription'; +import * as typeConverters from '../typeConverters'; import { ITypeScriptServiceClient } from '../typescriptService'; -import { DocumentSelector } from '../utils/documentSelector'; -import { LanguageDescription } from '../utils/languageDescription'; -import * as typeConverters from '../utils/typeConverters'; import FileConfigurationManager from './fileConfigurationManager'; diff --git a/extensions/typescript-language-features/src/languageFeatures/organizeImports.ts b/extensions/typescript-language-features/src/languageFeatures/organizeImports.ts index 43d2af73c7c..1092e1f202b 100644 --- a/extensions/typescript-language-features/src/languageFeatures/organizeImports.ts +++ b/extensions/typescript-language-features/src/languageFeatures/organizeImports.ts @@ -5,16 +5,16 @@ import * as vscode from 'vscode'; import { Command, CommandManager } from '../commands/commandManager'; -import type * as Proto from '../protocol'; -import { OrganizeImportsMode } from '../protocol.const'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { TelemetryReporter } from '../logging/telemetry'; +import { API } from '../tsServer/api'; +import type * as Proto from '../tsServer/protocol/protocol'; +import { OrganizeImportsMode } from '../tsServer/protocol/protocol.const'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; import { nulToken } from '../utils/cancellation'; -import { conditionalRegistration, requireMinVersion, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import { TelemetryReporter } from '../utils/telemetry'; -import * as typeConverters from '../utils/typeConverters'; import FileConfigurationManager from './fileConfigurationManager'; +import { conditionalRegistration, requireMinVersion, requireSomeCapability } from './util/dependentRegistration'; interface OrganizeImportsCommandMetadata { @@ -133,7 +133,7 @@ class ImportsCodeActionProvider implements vscode.CodeActionProvider { return []; } - if (!context.only || !context.only.contains(this.commandMetadata.kind)) { + if (!context.only?.contains(this.commandMetadata.kind)) { return []; } diff --git a/extensions/typescript-language-features/src/languageFeatures/quickFix.ts b/extensions/typescript-language-features/src/languageFeatures/quickFix.ts index c2285dc04c9..515402f6e1e 100644 --- a/extensions/typescript-language-features/src/languageFeatures/quickFix.ts +++ b/extensions/typescript-language-features/src/languageFeatures/quickFix.ts @@ -5,19 +5,19 @@ import * as vscode from 'vscode'; import { Command, CommandManager } from '../commands/commandManager'; -import type * as Proto from '../protocol'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { TelemetryReporter } from '../logging/telemetry'; +import * as fixNames from '../tsServer/protocol/fixNames'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; import { nulToken } from '../utils/cancellation'; -import { applyCodeActionCommands, getEditForCodeAction } from '../utils/codeAction'; -import { conditionalRegistration, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import * as fixNames from '../utils/fixNames'; import { memoize } from '../utils/memoize'; import { equals } from '../utils/objects'; -import { TelemetryReporter } from '../utils/telemetry'; -import * as typeConverters from '../utils/typeConverters'; import { DiagnosticsManager } from './diagnostics'; import FileConfigurationManager from './fileConfigurationManager'; +import { applyCodeActionCommands, getEditForCodeAction } from './util/codeAction'; +import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration'; type ApplyCodeActionCommand_args = { readonly resource: vscode.Uri; @@ -395,6 +395,7 @@ const preferredFixes = new Map { + for (const command of commands) { + await vscode.commands.executeCommand(command.command, ...(command.arguments ?? [])); + } + } +} + +namespace DidApplyRefactoringCommand { + export interface Args { + readonly action: string; + } } class DidApplyRefactoringCommand implements Command { @@ -31,7 +59,7 @@ class DidApplyRefactoringCommand implements Command { private readonly telemetryReporter: TelemetryReporter ) { } - public async execute(args: DidApplyRefactoringCommand_Args): Promise { + public async execute(args: DidApplyRefactoringCommand.Args): Promise { /* __GDPR__ "refactor.execute" : { "owner": "mjbvz", @@ -42,32 +70,16 @@ class DidApplyRefactoringCommand implements Command { } */ this.telemetryReporter.logTelemetry('refactor.execute', { - action: args.codeAction.action, + action: args.action, }); - - if (!args.codeAction.edit?.size) { - vscode.window.showErrorMessage(vscode.l10n.t("Could not apply refactoring")); - return; - } - - const renameLocation = args.codeAction.renameLocation; - if (renameLocation) { - // Disable renames in interactive playground https://github.com/microsoft/vscode/issues/75137 - if (args.codeAction.document.uri.scheme !== fileSchemes.walkThroughSnippet) { - await vscode.commands.executeCommand('editor.action.rename', [ - args.codeAction.document.uri, - typeConverters.Position.fromLocation(renameLocation) - ]); - } - } } } - -interface SelectRefactorCommand_Args { - readonly action: vscode.CodeAction; - readonly document: vscode.TextDocument; - readonly info: Proto.ApplicableRefactorInfo; - readonly rangeOrSelection: vscode.Range | vscode.Selection; +namespace SelectRefactorCommand { + export interface Args { + readonly document: vscode.TextDocument; + readonly refactor: Proto.ApplicableRefactorInfo; + readonly rangeOrSelection: vscode.Range | vscode.Selection; + } } class SelectRefactorCommand implements Command { @@ -76,16 +88,16 @@ class SelectRefactorCommand implements Command { constructor( private readonly client: ITypeScriptServiceClient, - private readonly didApplyCommand: DidApplyRefactoringCommand ) { } - public async execute(args: SelectRefactorCommand_Args): Promise { + public async execute(args: SelectRefactorCommand.Args): Promise { const file = this.client.toOpenTsFilePath(args.document); if (!file) { return; } - const selected = await vscode.window.showQuickPick(args.info.actions.map((action): vscode.QuickPickItem => ({ + const selected = await vscode.window.showQuickPick(args.refactor.actions.map((action): vscode.QuickPickItem & { action: Proto.RefactorActionInfo } => ({ + action, label: action.name, description: action.description, }))); @@ -93,7 +105,7 @@ class SelectRefactorCommand implements Command { return; } - const tsAction = new InlinedCodeAction(this.client, args.action.title, args.action.kind, args.document, args.info.name, selected.label, args.rangeOrSelection); + const tsAction = new InlinedCodeAction(this.client, args.document, args.refactor, selected.action, args.rangeOrSelection); await tsAction.resolve(nulToken); if (tsAction.edit) { @@ -103,7 +115,120 @@ class SelectRefactorCommand implements Command { } } - await this.didApplyCommand.execute({ codeAction: tsAction }); + if (tsAction.command) { + await vscode.commands.executeCommand(tsAction.command.command, ...(tsAction.command.arguments ?? [])); + } + } +} + +namespace MoveToFileRefactorCommand { + export interface Args { + readonly document: vscode.TextDocument; + readonly action: Proto.RefactorActionInfo; + readonly range: vscode.Range; + } +} + +class MoveToFileRefactorCommand implements Command { + public static readonly ID = '_typescript.moveToFileRefactoring'; + public readonly id = MoveToFileRefactorCommand.ID; + + constructor( + private readonly client: ITypeScriptServiceClient, + private readonly didApplyCommand: DidApplyRefactoringCommand + ) { } + + public async execute(args: MoveToFileRefactorCommand.Args): Promise { + const file = this.client.toOpenTsFilePath(args.document); + if (!file) { + return; + } + + const targetFile = await this.getTargetFile(args.document, file, args.range); + if (!targetFile) { + return; + } + + const fileSuggestionArgs: Proto.GetEditsForMoveToFileRefactorRequestArgs = { + ...typeConverters.Range.toFileRangeRequestArgs(file, args.range), + filepath: targetFile, + action: 'Move to file', + refactor: 'Move to file', + }; + + const response = await this.client.execute('getEditsForMoveToFileRefactor', fileSuggestionArgs, nulToken); + if (response.type !== 'response' || !response.body) { + return; + } + const edit = toWorkspaceEdit(this.client, response.body.edits); + if (!(await vscode.workspace.applyEdit(edit))) { + vscode.window.showErrorMessage(vscode.l10n.t("Could not apply refactoring")); + return; + } + + await this.didApplyCommand.execute({ action: args.action.name }); + } + + private async getTargetFile(document: vscode.TextDocument, file: string, range: vscode.Range): Promise { + const args = typeConverters.Range.toFileRangeRequestArgs(file, range); + const response = await this.client.execute('getMoveToRefactoringFileSuggestions', args, nulToken); + if (response.type !== 'response' || !response.body) { + return; + } + + const selectFileItem: vscode.QuickPickItem = { + label: vscode.l10n.t("Select file..."), + detail: vscode.l10n.t("Select file or enter new file path..."), + }; + + type DestinationItem = vscode.QuickPickItem & { file: string }; + + const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri); + + const destinationItems = response.body.files.map((file): DestinationItem => { + const uri = this.client.toResource(file); + const parentDir = Utils.dirname(uri); + + let description; + if (workspaceFolder) { + if (uri.scheme === Schemes.file) { + description = path.relative(workspaceFolder.uri.fsPath, parentDir.fsPath); + } else { + description = path.posix.relative(workspaceFolder.uri.path, parentDir.path); + } + } else { + description = parentDir.fsPath; + } + + return { + file, + label: Utils.basename(uri), + description, + }; + }); + + const picked = await vscode.window.showQuickPick([ + selectFileItem, + { label: vscode.l10n.t("Destination Files"), kind: vscode.QuickPickItemKind.Separator }, + ...destinationItems + ], { + title: vscode.l10n.t("Move to File"), + placeHolder: vscode.l10n.t("Enter file path"), + }); + if (!picked) { + return; + } + + if (picked === selectFileItem) { + const picked = await vscode.window.showSaveDialog({ + title: vscode.l10n.t("Select move destination"), + saveLabel: vscode.l10n.t("Move to File"), + defaultUri: vscode.Uri.joinPath(Utils.dirname(document.uri), response.body.newFilename) + }); + return picked ? this.client.toTsFilePath(picked) : undefined; + } + + return (picked as DestinationItem).file; } } @@ -132,6 +257,11 @@ const Extract_Interface = Object.freeze({ matches: refactor => refactor.name.startsWith('Extract to interface') }); +const Move_File = Object.freeze({ + kind: vscode.CodeActionKind.RefactorMove.append('file'), + matches: refactor => refactor.name.startsWith('Move to file') +}); + const Move_NewFile = Object.freeze({ kind: vscode.CodeActionKind.RefactorMove.append('newFile'), matches: refactor => refactor.name.startsWith('Move to a new file') @@ -167,6 +297,7 @@ const allKnownCodeActionKinds = [ Extract_Constant, Extract_Type, Extract_Interface, + Move_File, Move_NewFile, Rewrite_Import, Rewrite_Export, @@ -178,18 +309,23 @@ const allKnownCodeActionKinds = [ class InlinedCodeAction extends vscode.CodeAction { constructor( public readonly client: ITypeScriptServiceClient, - title: string, - kind: vscode.CodeActionKind | undefined, public readonly document: vscode.TextDocument, - public readonly refactor: string, - public readonly action: string, + public readonly refactor: Proto.ApplicableRefactorInfo, + public readonly action: Proto.RefactorActionInfo, public readonly range: vscode.Range, ) { - super(title, kind); - } + super(action.description, InlinedCodeAction.getKind(action)); - // Filled in during resolve - public renameLocation?: Proto.Location; + if (action.notApplicableReason) { + this.disabled = { reason: action.notApplicableReason }; + } + + this.command = { + title: action.description, + command: DidApplyRefactoringCommand.ID, + arguments: [{ action: action.name }], + }; + } public async resolve(token: vscode.CancellationToken): Promise { const file = this.client.toOpenTsFilePath(this.document); @@ -199,8 +335,8 @@ class InlinedCodeAction extends vscode.CodeAction { const args: Proto.GetEditsForRefactorRequestArgs = { ...typeConverters.Range.toFileRangeRequestArgs(file, this.range), - refactor: this.refactor, - action: this.action, + refactor: this.refactor.name, + action: this.action.name, }; const response = await this.client.execute('getEditsForRefactor', args, token); @@ -208,26 +344,59 @@ class InlinedCodeAction extends vscode.CodeAction { return; } - // Resolve - this.edit = InlinedCodeAction.getWorkspaceEditForRefactoring(this.client, response.body); - this.renameLocation = response.body.renameLocation; + this.edit = toWorkspaceEdit(this.client, response.body.edits); + if (!this.edit.size) { + vscode.window.showErrorMessage(vscode.l10n.t("Could not apply refactoring")); + return; + } - return; - } - - private static getWorkspaceEditForRefactoring( - client: ITypeScriptServiceClient, - body: Proto.RefactorEditInfo, - ): vscode.WorkspaceEdit { - const workspaceEdit = new vscode.WorkspaceEdit(); - for (const edit of body.edits) { - const resource = client.toResource(edit.fileName); - if (resource.scheme === fileSchemes.file) { - workspaceEdit.createFile(resource, { ignoreIfExists: true }); + if (response.body.renameLocation) { + // Disable renames in interactive playground https://github.com/microsoft/vscode/issues/75137 + if (this.document.uri.scheme !== fileSchemes.walkThroughSnippet) { + this.command = { + command: CompositeCommand.ID, + title: '', + arguments: coalesce([ + this.command, + { + command: 'editor.action.rename', + arguments: [[ + this.document.uri, + typeConverters.Position.fromLocation(response.body.renameLocation) + ]] + } + ]) + }; } } - typeConverters.WorkspaceEdit.withFileCodeEdits(workspaceEdit, client, body.edits); - return workspaceEdit; + } + + private static getKind(refactor: Proto.RefactorActionInfo) { + if ((refactor as Proto.RefactorActionInfo & { kind?: string }).kind) { + return vscode.CodeActionKind.Empty.append((refactor as Proto.RefactorActionInfo & { kind?: string }).kind!); + } + const match = allKnownCodeActionKinds.find(kind => kind.matches(refactor)); + return match ? match.kind : vscode.CodeActionKind.Refactor; + } +} + +class MoveToFileCodeAction extends vscode.CodeAction { + constructor( + document: vscode.TextDocument, + action: Proto.RefactorActionInfo, + range: vscode.Range, + ) { + super(action.description, Move_File.kind); + + if (action.notApplicableReason) { + this.disabled = { reason: action.notApplicableReason }; + } + + this.command = { + title: action.description, + command: MoveToFileRefactorCommand.ID, + arguments: [{ action, document, range }] + }; } } @@ -241,12 +410,12 @@ class SelectCodeAction extends vscode.CodeAction { this.command = { title: info.description, command: SelectRefactorCommand.ID, - arguments: [{ action: this, document, info, rangeOrSelection }] + arguments: [{ action: this, document, refactor: info, rangeOrSelection }] }; } } -type TsCodeAction = InlinedCodeAction | SelectCodeAction; +type TsCodeAction = InlinedCodeAction | MoveToFileCodeAction | SelectCodeAction; class TypeScriptRefactorProvider implements vscode.CodeActionProvider { @@ -257,7 +426,9 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider { + const actions = Array.from(this.convertApplicableRefactors(document, response.body, rangeOrSelection)).filter(action => { if (this.client.apiVersion.lt(API.v430)) { // Don't show 'infer return type' refactoring unless it has been explicitly requested // https://github.com/microsoft/TypeScript/issues/42993 @@ -341,43 +512,34 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider { + for (const refactor of refactors) { + if (refactor.inlineable === false) { + yield new SelectCodeAction(refactor, document, rangeOrSelection); } else { - for (const action of info.actions) { - actions.push(this.refactorActionToCodeAction(action, document, info, rangeOrSelection, info.actions)); + for (const action of refactor.actions) { + yield this.refactorActionToCodeAction(document, refactor, action, rangeOrSelection, refactor.actions); } } } - return actions; } private refactorActionToCodeAction( - action: Proto.RefactorActionInfo, document: vscode.TextDocument, - info: Proto.ApplicableRefactorInfo, + refactor: Proto.ApplicableRefactorInfo, + action: Proto.RefactorActionInfo, rangeOrSelection: vscode.Range | vscode.Selection, allActions: readonly Proto.RefactorActionInfo[], - ): InlinedCodeAction { - const codeAction = new InlinedCodeAction(this.client, action.description, TypeScriptRefactorProvider.getKind(action), document, info.name, action.name, rangeOrSelection); - - // https://github.com/microsoft/TypeScript/pull/37871 - if (action.notApplicableReason) { - codeAction.disabled = { reason: action.notApplicableReason }; + ): TsCodeAction { + let codeAction: TsCodeAction; + if (action.name === 'Move to file') { + codeAction = new MoveToFileCodeAction(document, action, rangeOrSelection); } else { - codeAction.command = { - title: action.description, - command: DidApplyRefactoringCommand.ID, - arguments: [{ codeAction }], - }; + codeAction = new InlinedCodeAction(this.client, document, refactor, action, rangeOrSelection); } codeAction.isPreferred = TypeScriptRefactorProvider.isPreferred(action, allActions); @@ -394,14 +556,6 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider kind.matches(refactor)); - return match ? match.kind : vscode.CodeActionKind.Refactor; - } - private static isPreferred( action: Proto.RefactorActionInfo, allActions: readonly Proto.RefactorActionInfo[], diff --git a/extensions/typescript-language-features/src/languageFeatures/references.ts b/extensions/typescript-language-features/src/languageFeatures/references.ts index 5ca2518a2eb..1a39ffbc2eb 100644 --- a/extensions/typescript-language-features/src/languageFeatures/references.ts +++ b/extensions/typescript-language-features/src/languageFeatures/references.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { DocumentSelector } from '../configuration/documentSelector'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import { conditionalRegistration, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import * as typeConverters from '../utils/typeConverters'; +import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration'; class TypeScriptReferenceSupport implements vscode.ReferenceProvider { public constructor( diff --git a/extensions/typescript-language-features/src/languageFeatures/rename.ts b/extensions/typescript-language-features/src/languageFeatures/rename.ts index 71f790ebe0b..2e182d0999f 100644 --- a/extensions/typescript-language-features/src/languageFeatures/rename.ts +++ b/extensions/typescript-language-features/src/languageFeatures/rename.ts @@ -5,13 +5,13 @@ import * as path from 'path'; import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { API } from '../tsServer/api'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient, ServerResponse } from '../typescriptService'; -import API from '../utils/api'; -import { conditionalRegistration, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import * as typeConverters from '../utils/typeConverters'; import FileConfigurationManager from './fileConfigurationManager'; +import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration'; class TypeScriptRenameProvider implements vscode.RenameProvider { diff --git a/extensions/typescript-language-features/src/languageFeatures/semanticTokens.ts b/extensions/typescript-language-features/src/languageFeatures/semanticTokens.ts index 582ea7e661c..48c9af7a5a5 100644 --- a/extensions/typescript-language-features/src/languageFeatures/semanticTokens.ts +++ b/extensions/typescript-language-features/src/languageFeatures/semanticTokens.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as Proto from '../protocol'; +import * as Proto from '../tsServer/protocol/protocol'; +import { API } from '../tsServer/api'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; -import { conditionalRegistration, requireMinVersion, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; +import { conditionalRegistration, requireMinVersion, requireSomeCapability } from './util/dependentRegistration'; +import { DocumentSelector } from '../configuration/documentSelector'; // as we don't do deltas, for performance reasons, don't compute semantic tokens for documents above that limit const CONTENT_LENGTH_LIMIT = 100000; diff --git a/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts b/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts index 70b1f7084a7..80f1cf37abd 100644 --- a/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts +++ b/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import { DocumentSelector } from '../configuration/documentSelector'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import { conditionalRegistration, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import * as Previewer from '../utils/previewer'; -import * as typeConverters from '../utils/typeConverters'; +import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration'; +import * as Previewer from './util/textRendering'; class TypeScriptSignatureHelpProvider implements vscode.SignatureHelpProvider { diff --git a/extensions/typescript-language-features/src/languageFeatures/smartSelect.ts b/extensions/typescript-language-features/src/languageFeatures/smartSelect.ts index 5906cdeadb3..80887d65180 100644 --- a/extensions/typescript-language-features/src/languageFeatures/smartSelect.ts +++ b/extensions/typescript-language-features/src/languageFeatures/smartSelect.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { API } from '../tsServer/api'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as typeConverters from '../typeConverters'; import { ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; -import { conditionalRegistration, requireMinVersion } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; -import * as typeConverters from '../utils/typeConverters'; +import { conditionalRegistration, requireMinVersion } from './util/dependentRegistration'; class SmartSelection implements vscode.SelectionRangeProvider { public static readonly minVersion = API.v350; diff --git a/extensions/typescript-language-features/src/languageFeatures/sourceDefinition.ts b/extensions/typescript-language-features/src/languageFeatures/sourceDefinition.ts index 9e842d73813..301f8607a1e 100644 --- a/extensions/typescript-language-features/src/languageFeatures/sourceDefinition.ts +++ b/extensions/typescript-language-features/src/languageFeatures/sourceDefinition.ts @@ -5,10 +5,10 @@ import * as vscode from 'vscode'; import { Command, CommandManager } from '../commands/commandManager'; +import { isSupportedLanguageMode } from '../configuration/languageIds'; +import { API } from '../tsServer/api'; +import * as typeConverters from '../typeConverters'; import { ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; -import { isSupportedLanguageMode } from '../utils/languageIds'; -import * as typeConverters from '../utils/typeConverters'; class SourceDefinitionCommand implements Command { diff --git a/extensions/typescript-language-features/src/languageFeatures/tagClosing.ts b/extensions/typescript-language-features/src/languageFeatures/tagClosing.ts index 21677f47390..36c894e8e1e 100644 --- a/extensions/typescript-language-features/src/languageFeatures/tagClosing.ts +++ b/extensions/typescript-language-features/src/languageFeatures/tagClosing.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import type * as Proto from '../tsServer/protocol/protocol'; +import { API } from '../tsServer/api'; import { ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; -import { Condition, conditionalRegistration, requireMinVersion } from '../utils/dependentRegistration'; +import { Condition, conditionalRegistration, requireMinVersion } from './util/dependentRegistration'; import { Disposable } from '../utils/dispose'; -import { DocumentSelector } from '../utils/documentSelector'; -import { LanguageDescription } from '../utils/languageDescription'; -import * as typeConverters from '../utils/typeConverters'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { LanguageDescription } from '../configuration/languageDescription'; +import * as typeConverters from '../typeConverters'; class TagClosing extends Disposable { public static readonly minVersion = API.v300; diff --git a/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts b/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts index 1bc20abd55b..89f45060d2d 100644 --- a/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts +++ b/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts @@ -18,8 +18,8 @@ function mapChildren(node: jsonc.Node | undefined, f: (x: jsonc.Node) => R): const openExtendsLinkCommandId = '_typescript.openExtendsLink'; type OpenExtendsLinkCommandArgs = { - resourceUri: vscode.Uri; - extendsValue: string; + readonly resourceUri: vscode.Uri; + readonly extendsValue: string; }; @@ -53,7 +53,7 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider { } const args: OpenExtendsLinkCommandArgs = { - resourceUri: document.uri, + resourceUri: { ...document.uri.toJSON(), $mid: undefined }, // Prevent VS Code from trying to transform the uri extendsValue: extendsValue }; @@ -199,7 +199,7 @@ export function register() { return vscode.Disposable.from( vscode.commands.registerCommand(openExtendsLinkCommandId, async ({ resourceUri, extendsValue, }: OpenExtendsLinkCommandArgs) => { - const tsconfigPath = await getTsconfigPath(Utils.dirname(resourceUri), extendsValue); + const tsconfigPath = await getTsconfigPath(Utils.dirname(vscode.Uri.from(resourceUri)), extendsValue); if (tsconfigPath === undefined) { vscode.window.showErrorMessage(vscode.l10n.t("Failed to resolve {0} as module", extendsValue)); return; diff --git a/extensions/typescript-language-features/src/languageFeatures/typeDefinitions.ts b/extensions/typescript-language-features/src/languageFeatures/typeDefinitions.ts index 4aef4f41ed4..e6564749006 100644 --- a/extensions/typescript-language-features/src/languageFeatures/typeDefinitions.ts +++ b/extensions/typescript-language-features/src/languageFeatures/typeDefinitions.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { DocumentSelector } from '../configuration/documentSelector'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import { conditionalRegistration, requireSomeCapability } from '../utils/dependentRegistration'; -import { DocumentSelector } from '../utils/documentSelector'; import DefinitionProviderBase from './definitionProviderBase'; +import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration'; export default class TypeScriptTypeDefinitionProvider extends DefinitionProviderBase implements vscode.TypeDefinitionProvider { public provideTypeDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { diff --git a/extensions/typescript-language-features/src/languageFeatures/updatePathsOnRename.ts b/extensions/typescript-language-features/src/languageFeatures/updatePathsOnRename.ts index b52d201a944..1d55938685d 100644 --- a/extensions/typescript-language-features/src/languageFeatures/updatePathsOnRename.ts +++ b/extensions/typescript-language-features/src/languageFeatures/updatePathsOnRename.ts @@ -5,17 +5,17 @@ import * as path from 'path'; import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import * as fileSchemes from '../configuration/fileSchemes'; +import { doesResourceLookLikeATypeScriptFile } from '../configuration/languageDescription'; +import { API } from '../tsServer/api'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; import { Delayer } from '../utils/async'; import { nulToken } from '../utils/cancellation'; -import { conditionalRegistration, requireMinVersion, requireSomeCapability } from '../utils/dependentRegistration'; import { Disposable } from '../utils/dispose'; -import * as fileSchemes from '../utils/fileSchemes'; -import { doesResourceLookLikeATypeScriptFile } from '../utils/languageDescription'; -import * as typeConverters from '../utils/typeConverters'; import FileConfigurationManager from './fileConfigurationManager'; +import { conditionalRegistration, requireMinVersion, requireSomeCapability } from './util/dependentRegistration'; const updateImportsOnFileMoveName = 'updateImportsOnFileMove.enabled'; diff --git a/extensions/typescript-language-features/src/utils/codeAction.ts b/extensions/typescript-language-features/src/languageFeatures/util/codeAction.ts similarity index 87% rename from extensions/typescript-language-features/src/utils/codeAction.ts rename to extensions/typescript-language-features/src/languageFeatures/util/codeAction.ts index 6a7ad144482..c2197d593db 100644 --- a/extensions/typescript-language-features/src/utils/codeAction.ts +++ b/extensions/typescript-language-features/src/languageFeatures/util/codeAction.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; -import { ITypeScriptServiceClient } from '../typescriptService'; -import * as typeConverters from './typeConverters'; +import type * as Proto from '../../tsServer/protocol/protocol'; +import * as typeConverters from '../../typeConverters'; +import { ITypeScriptServiceClient } from '../../typescriptService'; export function getEditForCodeAction( client: ITypeScriptServiceClient, diff --git a/extensions/typescript-language-features/src/utils/dependentRegistration.ts b/extensions/typescript-language-features/src/languageFeatures/util/dependentRegistration.ts similarity index 93% rename from extensions/typescript-language-features/src/utils/dependentRegistration.ts rename to extensions/typescript-language-features/src/languageFeatures/util/dependentRegistration.ts index c53d553625c..e234acd1ab4 100644 --- a/extensions/typescript-language-features/src/utils/dependentRegistration.ts +++ b/extensions/typescript-language-features/src/languageFeatures/util/dependentRegistration.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import API from './api'; -import { Disposable } from './dispose'; +import { API } from '../../tsServer/api'; +import { ClientCapability, ITypeScriptServiceClient } from '../../typescriptService'; +import { Disposable } from '../../utils/dispose'; export class Condition extends Disposable { private _value: boolean; diff --git a/extensions/typescript-language-features/src/utils/snippetForFunctionCall.ts b/extensions/typescript-language-features/src/languageFeatures/util/snippetForFunctionCall.ts similarity index 96% rename from extensions/typescript-language-features/src/utils/snippetForFunctionCall.ts rename to extensions/typescript-language-features/src/languageFeatures/util/snippetForFunctionCall.ts index 2c5a0fd515c..def0895703f 100644 --- a/extensions/typescript-language-features/src/utils/snippetForFunctionCall.ts +++ b/extensions/typescript-language-features/src/languageFeatures/util/snippetForFunctionCall.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; -import * as PConst from '../protocol.const'; +import type * as Proto from '../../tsServer/protocol/protocol'; +import * as PConst from '../../tsServer/protocol/protocol.const'; export function snippetForFunctionCall( item: { insertText?: string | vscode.SnippetString; label: string }, diff --git a/extensions/typescript-language-features/src/utils/previewer.ts b/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts similarity index 99% rename from extensions/typescript-language-features/src/utils/previewer.ts rename to extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts index cc8125fc778..0d2cfc86e7b 100644 --- a/extensions/typescript-language-features/src/utils/previewer.ts +++ b/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import type * as Proto from '../../tsServer/protocol/protocol'; export interface IFilePathToResourceConverter { /** diff --git a/extensions/typescript-language-features/src/languageFeatures/workspaceSymbols.ts b/extensions/typescript-language-features/src/languageFeatures/workspaceSymbols.ts index 0072156efa9..f9cdbf79afb 100644 --- a/extensions/typescript-language-features/src/languageFeatures/workspaceSymbols.ts +++ b/extensions/typescript-language-features/src/languageFeatures/workspaceSymbols.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; -import * as PConst from '../protocol.const'; +import * as fileSchemes from '../configuration/fileSchemes'; +import { doesResourceLookLikeAJavaScriptFile, doesResourceLookLikeATypeScriptFile } from '../configuration/languageDescription'; +import { API } from '../tsServer/api'; +import { parseKindModifier } from '../tsServer/protocol/modifiers'; +import type * as Proto from '../tsServer/protocol/protocol'; +import * as PConst from '../tsServer/protocol/protocol.const'; +import * as typeConverters from '../typeConverters'; import { ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; -import * as fileSchemes from '../utils/fileSchemes'; -import { doesResourceLookLikeAJavaScriptFile, doesResourceLookLikeATypeScriptFile } from '../utils/languageDescription'; -import { parseKindModifier } from '../utils/modifiers'; -import * as typeConverters from '../utils/typeConverters'; function getSymbolKind(item: Proto.NavtoItem): vscode.SymbolKind { switch (item.kind) { diff --git a/extensions/typescript-language-features/src/languageProvider.ts b/extensions/typescript-language-features/src/languageProvider.ts index 321a2c845b3..a9ef3aea5a5 100644 --- a/extensions/typescript-language-features/src/languageProvider.ts +++ b/extensions/typescript-language-features/src/languageProvider.ts @@ -11,12 +11,12 @@ import FileConfigurationManager from './languageFeatures/fileConfigurationManage import { CachedResponse } from './tsServer/cachedResponse'; import { ClientCapability } from './typescriptService'; import TypeScriptServiceClient from './typescriptServiceClient'; +import TypingsStatus from './ui/typingsStatus'; import { Disposable } from './utils/dispose'; -import { DocumentSelector } from './utils/documentSelector'; -import * as fileSchemes from './utils/fileSchemes'; -import { LanguageDescription } from './utils/languageDescription'; -import { TelemetryReporter } from './utils/telemetry'; -import TypingsStatus from './utils/typingsStatus'; +import { DocumentSelector } from './configuration/documentSelector'; +import * as fileSchemes from './configuration/fileSchemes'; +import { LanguageDescription } from './configuration/languageDescription'; +import { TelemetryReporter } from './logging/telemetry'; const validateSetting = 'validate.enable'; diff --git a/extensions/typescript-language-features/src/lazyClientHost.ts b/extensions/typescript-language-features/src/lazyClientHost.ts index db8e23245b2..be832b3e169 100644 --- a/extensions/typescript-language-features/src/lazyClientHost.ts +++ b/extensions/typescript-language-features/src/lazyClientHost.ts @@ -11,14 +11,14 @@ import { ILogDirectoryProvider } from './tsServer/logDirectoryProvider'; import { TsServerProcessFactory } from './tsServer/server'; import { ITypeScriptVersionProvider } from './tsServer/versionProvider'; import TypeScriptServiceClientHost from './typeScriptServiceClientHost'; -import { ActiveJsTsEditorTracker } from './utils/activeJsTsEditorTracker'; -import { ServiceConfigurationProvider } from './utils/configuration'; -import * as fileSchemes from './utils/fileSchemes'; -import { standardLanguageDescriptions } from './utils/languageDescription'; +import { ActiveJsTsEditorTracker } from './ui/activeJsTsEditorTracker'; +import ManagedFileContextManager from './ui/managedFileContext'; +import { ServiceConfigurationProvider } from './configuration/configuration'; +import * as fileSchemes from './configuration/fileSchemes'; +import { standardLanguageDescriptions } from './configuration/languageDescription'; import { Lazy, lazy } from './utils/lazy'; -import { Logger } from './utils/logger'; -import ManagedFileContextManager from './utils/managedFileContext'; -import { PluginManager } from './utils/plugins'; +import { Logger } from './logging/logger'; +import { PluginManager } from './tsServer/plugins'; export function createLazyClientHost( context: vscode.ExtensionContext, diff --git a/extensions/typescript-language-features/src/utils/logLevelMonitor.ts b/extensions/typescript-language-features/src/logging/logLevelMonitor.ts similarity index 96% rename from extensions/typescript-language-features/src/utils/logLevelMonitor.ts rename to extensions/typescript-language-features/src/logging/logLevelMonitor.ts index f1140567d99..09d566b05bf 100644 --- a/extensions/typescript-language-features/src/utils/logLevelMonitor.ts +++ b/extensions/typescript-language-features/src/logging/logLevelMonitor.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { TsServerLogLevel } from './configuration'; -import { Disposable } from './dispose'; +import { TsServerLogLevel } from '../configuration/configuration'; +import { Disposable } from '../utils/dispose'; export class LogLevelMonitor extends Disposable { diff --git a/extensions/typescript-language-features/src/utils/logger.ts b/extensions/typescript-language-features/src/logging/logger.ts similarity index 97% rename from extensions/typescript-language-features/src/utils/logger.ts rename to extensions/typescript-language-features/src/logging/logger.ts index 7ecc48dfce3..96b7f95af14 100644 --- a/extensions/typescript-language-features/src/utils/logger.ts +++ b/extensions/typescript-language-features/src/logging/logger.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { memoize } from './memoize'; +import { memoize } from '../utils/memoize'; type LogLevel = 'Trace' | 'Info' | 'Error'; diff --git a/extensions/typescript-language-features/src/utils/telemetry.ts b/extensions/typescript-language-features/src/logging/telemetry.ts similarity index 100% rename from extensions/typescript-language-features/src/utils/telemetry.ts rename to extensions/typescript-language-features/src/logging/telemetry.ts diff --git a/extensions/typescript-language-features/src/utils/tracer.ts b/extensions/typescript-language-features/src/logging/tracer.ts similarity index 98% rename from extensions/typescript-language-features/src/utils/tracer.ts rename to extensions/typescript-language-features/src/logging/tracer.ts index de3b0c933c7..bebd9fc54d4 100644 --- a/extensions/typescript-language-features/src/utils/tracer.ts +++ b/extensions/typescript-language-features/src/logging/tracer.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import type * as Proto from '../tsServer/protocol/protocol'; import { Logger } from './logger'; enum Trace { diff --git a/extensions/typescript-language-features/src/protocol.d.ts b/extensions/typescript-language-features/src/protocol.d.ts deleted file mode 100644 index 38345971fc8..00000000000 --- a/extensions/typescript-language-features/src/protocol.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import * as ts from 'typescript/lib/tsserverlibrary'; -export = ts.server.protocol; - - -declare enum ServerType { - Syntax = 'syntax', - Semantic = 'semantic', -} - -declare module 'typescript/lib/tsserverlibrary' { - namespace server.protocol { - type TextInsertion = ts.TextInsertion; - type ScriptElementKind = ts.ScriptElementKind; - - interface Response { - readonly _serverType?: ServerType; - } - } -} diff --git a/extensions/typescript-language-features/src/task/taskProvider.ts b/extensions/typescript-language-features/src/task/taskProvider.ts index 05aeb1119a7..c1b14385603 100644 --- a/extensions/typescript-language-features/src/task/taskProvider.ts +++ b/extensions/typescript-language-features/src/task/taskProvider.ts @@ -11,9 +11,9 @@ import { ITypeScriptServiceClient, ServerResponse } from '../typescriptService'; import { coalesce } from '../utils/arrays'; import { Disposable } from '../utils/dispose'; import { exists } from '../utils/fs'; -import { isTsConfigFileName } from '../utils/languageDescription'; +import { isTsConfigFileName } from '../configuration/languageDescription'; import { Lazy } from '../utils/lazy'; -import { isImplicitProjectConfigFile } from '../utils/tsconfig'; +import { isImplicitProjectConfigFile } from '../tsconfig'; import { TSConfig, TsConfigProvider } from './tsconfigProvider'; diff --git a/extensions/typescript-language-features/src/test/smoke/completions.test.ts b/extensions/typescript-language-features/src/test/smoke/completions.test.ts index 4c0c5f61e5d..bdaeb858e25 100644 --- a/extensions/typescript-language-features/src/test/smoke/completions.test.ts +++ b/extensions/typescript-language-features/src/test/smoke/completions.test.ts @@ -6,7 +6,7 @@ import 'mocha'; import * as vscode from 'vscode'; import { acceptFirstSuggestion, typeCommitCharacter } from '../../test/suggestTestHelpers'; -import { assertEditorContents, Config, createTestEditor, enumerateConfig, joinLines, updateConfig, VsCodeConfiguration } from '../../test/testUtils'; +import { Config, VsCodeConfiguration, assertEditorContents, createTestEditor, enumerateConfig, joinLines, updateConfig } from '../../test/testUtils'; import { disposeAll } from '../../utils/dispose'; const testDocumentUri = vscode.Uri.parse('untitled:test.ts'); diff --git a/extensions/typescript-language-features/src/test/unit/cachedResponse.test.ts b/extensions/typescript-language-features/src/test/unit/cachedResponse.test.ts index 49a9049013a..5b024e59a4f 100644 --- a/extensions/typescript-language-features/src/test/unit/cachedResponse.test.ts +++ b/extensions/typescript-language-features/src/test/unit/cachedResponse.test.ts @@ -6,8 +6,8 @@ import * as assert from 'assert'; import 'mocha'; import * as vscode from 'vscode'; -import type * as Proto from '../../protocol'; import { CachedResponse } from '../../tsServer/cachedResponse'; +import type * as Proto from '../../tsServer/protocol/protocol'; import { ServerResponse } from '../../typescriptService'; suite('CachedResponse', () => { diff --git a/extensions/typescript-language-features/src/test/unit/functionCallSnippet.test.ts b/extensions/typescript-language-features/src/test/unit/functionCallSnippet.test.ts index 5b46a7f0e6d..ccda34396f3 100644 --- a/extensions/typescript-language-features/src/test/unit/functionCallSnippet.test.ts +++ b/extensions/typescript-language-features/src/test/unit/functionCallSnippet.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import 'mocha'; import * as vscode from 'vscode'; -import { snippetForFunctionCall } from '../../utils/snippetForFunctionCall'; +import { snippetForFunctionCall } from '../../languageFeatures/util/snippetForFunctionCall'; suite('typescript function call snippets', () => { test('Should use label as function name', async () => { diff --git a/extensions/typescript-language-features/src/test/unit/previewer.test.ts b/extensions/typescript-language-features/src/test/unit/previewer.test.ts index 75a4464610c..e9a4d1688ed 100644 --- a/extensions/typescript-language-features/src/test/unit/previewer.test.ts +++ b/extensions/typescript-language-features/src/test/unit/previewer.test.ts @@ -5,9 +5,9 @@ import * as assert from 'assert'; import 'mocha'; -import { SymbolDisplayPart } from '../../protocol'; import { Uri } from 'vscode'; -import { IFilePathToResourceConverter, markdownDocumentation, plainWithLinks, tagsMarkdownPreview } from '../../utils/previewer'; +import { IFilePathToResourceConverter, markdownDocumentation, plainWithLinks, tagsMarkdownPreview } from '../../languageFeatures/util/textRendering'; +import { SymbolDisplayPart } from '../../tsServer/protocol/protocol'; const noopToResource: IFilePathToResourceConverter = { toResource: (path) => Uri.file(path) diff --git a/extensions/typescript-language-features/src/test/unit/server.test.ts b/extensions/typescript-language-features/src/test/unit/server.test.ts index 29b3c20729a..4d086be5b88 100644 --- a/extensions/typescript-language-features/src/test/unit/server.test.ts +++ b/extensions/typescript-language-features/src/test/unit/server.test.ts @@ -6,14 +6,14 @@ import * as assert from 'assert'; import 'mocha'; import * as stream from 'stream'; -import type * as Proto from '../../protocol'; +import { Logger } from '../../logging/logger'; +import { TelemetryReporter } from '../../logging/telemetry'; +import Tracer from '../../logging/tracer'; import { NodeRequestCanceller } from '../../tsServer/cancellation.electron'; +import type * as Proto from '../../tsServer/protocol/protocol'; import { SingleTsServer, TsServerProcess } from '../../tsServer/server'; import { ServerType } from '../../typescriptService'; import { nulToken } from '../../utils/cancellation'; -import { Logger } from '../../utils/logger'; -import { TelemetryReporter } from '../../utils/telemetry'; -import Tracer from '../../utils/tracer'; const NoopTelemetryReporter = new class implements TelemetryReporter { diff --git a/extensions/typescript-language-features/src/utils/api.ts b/extensions/typescript-language-features/src/tsServer/api.ts similarity index 99% rename from extensions/typescript-language-features/src/utils/api.ts rename to extensions/typescript-language-features/src/tsServer/api.ts index fbf74fe993d..440c0b8fec4 100644 --- a/extensions/typescript-language-features/src/utils/api.ts +++ b/extensions/typescript-language-features/src/tsServer/api.ts @@ -7,7 +7,7 @@ import * as semver from 'semver'; import * as vscode from 'vscode'; -export default class API { +export class API { public static fromSimpleString(value: string): API { return new API(value, value, value); } diff --git a/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts b/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts index a4250ba430d..7ccfd67ba0f 100644 --- a/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts @@ -4,17 +4,17 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; +import { vscodeNotebookCell } from '../configuration/fileSchemes'; +import * as languageModeIds from '../configuration/languageIds'; +import * as typeConverters from '../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import API from '../utils/api'; import { coalesce } from '../utils/arrays'; import { Delayer, setImmediate } from '../utils/async'; import { nulToken } from '../utils/cancellation'; import { Disposable } from '../utils/dispose'; -import { vscodeNotebookCell } from '../utils/fileSchemes'; -import * as languageModeIds from '../utils/languageIds'; import { ResourceMap } from '../utils/resourceMap'; -import * as typeConverters from '../utils/typeConverters'; +import { API } from './api'; +import type * as Proto from './protocol/protocol'; const enum BufferKind { TypeScript = 1, diff --git a/extensions/typescript-language-features/src/tsServer/cachedResponse.ts b/extensions/typescript-language-features/src/tsServer/cachedResponse.ts index baa1a87a88a..cedc580761f 100644 --- a/extensions/typescript-language-features/src/tsServer/cachedResponse.ts +++ b/extensions/typescript-language-features/src/tsServer/cachedResponse.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; import { ServerResponse } from '../typescriptService'; +import type * as Proto from './protocol/protocol'; type Resolve = () => Promise>; diff --git a/extensions/typescript-language-features/src/tsServer/callbackMap.ts b/extensions/typescript-language-features/src/tsServer/callbackMap.ts index 4e0ec375ddc..57a80051e6d 100644 --- a/extensions/typescript-language-features/src/tsServer/callbackMap.ts +++ b/extensions/typescript-language-features/src/tsServer/callbackMap.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type * as Proto from '../protocol'; import { ServerResponse } from '../typescriptService'; +import type * as Proto from './protocol/protocol'; export interface CallbackItem { readonly onSuccess: (value: R) => void; diff --git a/extensions/typescript-language-features/src/tsServer/cancellation.electron.ts b/extensions/typescript-language-features/src/tsServer/cancellation.electron.ts index 853ca0c1594..29ab6b2710c 100644 --- a/extensions/typescript-language-features/src/tsServer/cancellation.electron.ts +++ b/extensions/typescript-language-features/src/tsServer/cancellation.electron.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; +import Tracer from '../logging/tracer'; import { getTempFile } from '../utils/temp.electron'; -import Tracer from '../utils/tracer'; import { OngoingRequestCanceller, OngoingRequestCancellerFactory } from './cancellation'; export class NodeRequestCanceller implements OngoingRequestCanceller { diff --git a/extensions/typescript-language-features/src/tsServer/cancellation.ts b/extensions/typescript-language-features/src/tsServer/cancellation.ts index 0eda4e574dc..051708a03d1 100644 --- a/extensions/typescript-language-features/src/tsServer/cancellation.ts +++ b/extensions/typescript-language-features/src/tsServer/cancellation.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import Tracer from '../utils/tracer'; +import Tracer from '../logging/tracer'; export interface OngoingRequestCanceller { readonly cancellationPipeName: string | undefined; diff --git a/extensions/typescript-language-features/src/tsServer/fileWatchingManager.ts b/extensions/typescript-language-features/src/tsServer/fileWatchingManager.ts index 3386067163e..bc4f6d5b973 100644 --- a/extensions/typescript-language-features/src/tsServer/fileWatchingManager.ts +++ b/extensions/typescript-language-features/src/tsServer/fileWatchingManager.ts @@ -5,9 +5,9 @@ import * as vscode from 'vscode'; import { Utils } from 'vscode-uri'; +import { Schemes } from '../configuration/schemes'; import { disposeAll, IDisposable } from '../utils/dispose'; import { ResourceMap } from '../utils/resourceMap'; -import { Schemes } from '../utils/schemes'; type DirWatcherEntry = { readonly uri: vscode.Uri; diff --git a/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts b/extensions/typescript-language-features/src/tsServer/pluginPathsProvider.ts similarity index 89% rename from extensions/typescript-language-features/src/utils/pluginPathsProvider.ts rename to extensions/typescript-language-features/src/tsServer/pluginPathsProvider.ts index c3a878a0bc2..a56076d3944 100644 --- a/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts +++ b/extensions/typescript-language-features/src/tsServer/pluginPathsProvider.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import * as vscode from 'vscode'; -import { TypeScriptServiceConfiguration } from './configuration'; -import { RelativeWorkspacePathResolver } from './relativePathResolver'; +import { RelativeWorkspacePathResolver } from '../utils/relativePathResolver'; +import { TypeScriptServiceConfiguration } from '../configuration/configuration'; export class TypeScriptPluginPathsProvider { diff --git a/extensions/typescript-language-features/src/utils/plugins.ts b/extensions/typescript-language-features/src/tsServer/plugins.ts similarity index 97% rename from extensions/typescript-language-features/src/utils/plugins.ts rename to extensions/typescript-language-features/src/tsServer/plugins.ts index 814f0e12016..6036e4c968b 100644 --- a/extensions/typescript-language-features/src/utils/plugins.ts +++ b/extensions/typescript-language-features/src/tsServer/plugins.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as arrays from './arrays'; -import { Disposable } from './dispose'; +import * as arrays from '../utils/arrays'; +import { Disposable } from '../utils/dispose'; export interface TypeScriptServerPlugin { readonly extension: vscode.Extension; diff --git a/extensions/typescript-language-features/src/utils/errorCodes.ts b/extensions/typescript-language-features/src/tsServer/protocol/errorCodes.ts similarity index 100% rename from extensions/typescript-language-features/src/utils/errorCodes.ts rename to extensions/typescript-language-features/src/tsServer/protocol/errorCodes.ts diff --git a/extensions/typescript-language-features/src/utils/fixNames.ts b/extensions/typescript-language-features/src/tsServer/protocol/fixNames.ts similarity index 95% rename from extensions/typescript-language-features/src/utils/fixNames.ts rename to extensions/typescript-language-features/src/tsServer/protocol/fixNames.ts index af5d7a3639c..82df3b9cc46 100644 --- a/extensions/typescript-language-features/src/utils/fixNames.ts +++ b/extensions/typescript-language-features/src/tsServer/protocol/fixNames.ts @@ -3,17 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +export const addMissingAwait = 'addMissingAwait'; +export const addMissingNewOperator = 'addMissingNewOperator'; +export const addMissingOverride = 'fixOverrideModifier'; export const annotateWithTypeFromJSDoc = 'annotateWithTypeFromJSDoc'; +export const awaitInSyncFunction = 'fixAwaitInSyncFunction'; +export const classDoesntImplementInheritedAbstractMember = 'fixClassDoesntImplementInheritedAbstractMember'; +export const classIncorrectlyImplementsInterface = 'fixClassIncorrectlyImplementsInterface'; export const constructorForDerivedNeedSuperCall = 'constructorForDerivedNeedSuperCall'; export const extendsInterfaceBecomesImplements = 'extendsInterfaceBecomesImplements'; -export const awaitInSyncFunction = 'fixAwaitInSyncFunction'; -export const classIncorrectlyImplementsInterface = 'fixClassIncorrectlyImplementsInterface'; -export const classDoesntImplementInheritedAbstractMember = 'fixClassDoesntImplementInheritedAbstractMember'; +export const fixImport = 'import'; +export const forgottenThisPropertyAccess = 'forgottenThisPropertyAccess'; +export const removeUnnecessaryAwait = 'removeUnnecessaryAwait'; +export const spelling = 'spelling'; export const unreachableCode = 'fixUnreachableCode'; export const unusedIdentifier = 'unusedIdentifier'; -export const forgottenThisPropertyAccess = 'forgottenThisPropertyAccess'; -export const spelling = 'spelling'; -export const fixImport = 'import'; -export const addMissingAwait = 'addMissingAwait'; -export const addMissingOverride = 'fixOverrideModifier'; -export const removeUnnecessaryAwait = 'removeUnnecessaryAwait'; diff --git a/extensions/typescript-language-features/src/utils/modifiers.ts b/extensions/typescript-language-features/src/tsServer/protocol/modifiers.ts similarity index 100% rename from extensions/typescript-language-features/src/utils/modifiers.ts rename to extensions/typescript-language-features/src/tsServer/protocol/modifiers.ts diff --git a/extensions/typescript-language-features/src/protocol.const.ts b/extensions/typescript-language-features/src/tsServer/protocol/protocol.const.ts similarity index 100% rename from extensions/typescript-language-features/src/protocol.const.ts rename to extensions/typescript-language-features/src/tsServer/protocol/protocol.const.ts diff --git a/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts b/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts new file mode 100644 index 00000000000..0018bc10451 --- /dev/null +++ b/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts @@ -0,0 +1,55 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as ts from 'typescript/lib/tsserverlibrary'; +export = ts.server.protocol; + + +declare enum ServerType { + Syntax = 'syntax', + Semantic = 'semantic', +} + +declare module 'typescript/lib/tsserverlibrary' { + namespace server.protocol { + type TextInsertion = ts.TextInsertion; + type ScriptElementKind = ts.ScriptElementKind; + + interface Response { + readonly _serverType?: ServerType; + } + + interface GetMoveToRefactoringFileSuggestionsRequest extends Request { + command: 'getMoveToRefactoringFileSuggestions'; + arguments: GetMoveToRefactoringFileSuggestionsRequestArgs; + } + + type GetMoveToRefactoringFileSuggestionsRequestArgs = FileLocationOrRangeRequestArgs & { + triggerReason?: RefactorTriggerReason; + kind?: string; + }; + + interface GetMoveToRefactoringFileSuggestionsResponse extends Response { + body?: { + newFilename: string; + files: string[]; + }; + } + + interface GetEditsForMoveToFileRefactorRequest extends Request { + command: 'getEditsForMoveToFileRefactor'; + arguments: GetEditsForMoveToFileRefactorRequestArgs; + } + + interface GetEditsForMoveToFileRefactorResponse extends Response { + body?: RefactorEditInfo; + } + + type GetEditsForMoveToFileRefactorRequestArgs = FileLocationOrRangeRequestArgs & { + refactor: string; + action: string; + filepath: string; + }; + } +} diff --git a/extensions/typescript-language-features/src/tsServer/requestQueue.ts b/extensions/typescript-language-features/src/tsServer/requestQueue.ts index 4b75833a1e9..e81da742fd5 100644 --- a/extensions/typescript-language-features/src/tsServer/requestQueue.ts +++ b/extensions/typescript-language-features/src/tsServer/requestQueue.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type * as Proto from '../protocol'; +import type * as Proto from './protocol/protocol'; export enum RequestQueueingType { /** diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 936ecebe727..7bdf6b83fe0 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -3,22 +3,22 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from 'vscode'; import { Cancellation } from '@vscode/sync-api-common/lib/common/messageCancellation'; -import type * as Proto from '../protocol'; -import { EventName } from '../protocol.const'; +import * as vscode from 'vscode'; +import { TypeScriptServiceConfiguration } from '../configuration/configuration'; +import { TelemetryReporter } from '../logging/telemetry'; +import Tracer from '../logging/tracer'; import { CallbackMap } from '../tsServer/callbackMap'; import { RequestItem, RequestQueue, RequestQueueingType } from '../tsServer/requestQueue'; import { TypeScriptServerError } from '../tsServer/serverError'; import { ServerResponse, ServerType, TypeScriptRequests } from '../typescriptService'; -import { TypeScriptServiceConfiguration } from '../utils/configuration'; import { Disposable } from '../utils/dispose'; -import { TelemetryReporter } from '../utils/telemetry'; -import Tracer from '../utils/tracer'; +import { isWebAndHasSharedArrayBuffers } from '../utils/platform'; import { OngoingRequestCanceller } from './cancellation'; +import type * as Proto from './protocol/protocol'; +import { EventName } from './protocol/protocol.const'; import { TypeScriptVersionManager } from './versionManager'; import { TypeScriptVersion } from './versionProvider'; -import { isWebAndHasSharedArrayBuffers } from '../utils/platform'; export enum ExecutionTarget { Semantic, @@ -239,7 +239,7 @@ export class SingleTsServer extends Disposable implements ITypeScriptServer { } }).catch((err: Error) => { if (err instanceof TypeScriptServerError) { - if (!executeInfo.token || !executeInfo.token.isCancellationRequested) { + if (!executeInfo.token?.isCancellationRequested) { /* __GDPR__ "languageServiceErrorResponse" : { "owner": "mjbvz", diff --git a/extensions/typescript-language-features/src/tsServer/serverError.ts b/extensions/typescript-language-features/src/tsServer/serverError.ts index be9a44d276d..7467c87f216 100644 --- a/extensions/typescript-language-features/src/tsServer/serverError.ts +++ b/extensions/typescript-language-features/src/tsServer/serverError.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type * as Proto from '../protocol'; +import type * as Proto from './protocol/protocol'; import { TypeScriptVersion } from './versionProvider'; diff --git a/extensions/typescript-language-features/src/tsServer/serverProcess.browser.ts b/extensions/typescript-language-features/src/tsServer/serverProcess.browser.ts index c5c2af3698e..cd54bdca2fb 100644 --- a/extensions/typescript-language-features/src/tsServer/serverProcess.browser.ts +++ b/extensions/typescript-language-features/src/tsServer/serverProcess.browser.ts @@ -6,9 +6,9 @@ import { ServiceConnection } from '@vscode/sync-api-common/browser'; import { ApiService, Requests } from '@vscode/sync-api-service'; import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; -import { TypeScriptServiceConfiguration } from '../utils/configuration'; +import { TypeScriptServiceConfiguration } from '../configuration/configuration'; import { FileWatcherManager } from './fileWatchingManager'; +import type * as Proto from './protocol/protocol'; import { TsServerLog, TsServerProcess, TsServerProcessFactory, TsServerProcessKind } from './server'; import { TypeScriptVersionManager } from './versionManager'; import { TypeScriptVersion } from './versionProvider'; diff --git a/extensions/typescript-language-features/src/tsServer/serverProcess.electron.ts b/extensions/typescript-language-features/src/tsServer/serverProcess.electron.ts index ab235c8cd76..b5848d5eb9f 100644 --- a/extensions/typescript-language-features/src/tsServer/serverProcess.electron.ts +++ b/extensions/typescript-language-features/src/tsServer/serverProcess.electron.ts @@ -8,10 +8,10 @@ import * as fs from 'fs'; import * as path from 'path'; import type { Readable } from 'stream'; import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; -import API from '../utils/api'; -import { TypeScriptServiceConfiguration } from '../utils/configuration'; +import { TypeScriptServiceConfiguration } from '../configuration/configuration'; import { Disposable } from '../utils/dispose'; +import { API } from './api'; +import type * as Proto from './protocol/protocol'; import { TsServerLog, TsServerProcess, TsServerProcessFactory, TsServerProcessKind } from './server'; import { TypeScriptVersionManager } from './versionManager'; import { TypeScriptVersion } from './versionProvider'; diff --git a/extensions/typescript-language-features/src/tsServer/spawner.ts b/extensions/typescript-language-features/src/tsServer/spawner.ts index 2c32cfb87f9..0fa9bedf4a6 100644 --- a/extensions/typescript-language-features/src/tsServer/spawner.ts +++ b/extensions/typescript-language-features/src/tsServer/spawner.ts @@ -4,21 +4,21 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { SyntaxServerConfiguration, TsServerLogLevel, TypeScriptServiceConfiguration } from '../configuration/configuration'; +import { Logger } from '../logging/logger'; +import { TelemetryReporter } from '../logging/telemetry'; +import Tracer from '../logging/tracer'; import { OngoingRequestCancellerFactory } from '../tsServer/cancellation'; import { ClientCapabilities, ClientCapability, ServerType } from '../typescriptService'; -import API from '../utils/api'; -import { SyntaxServerConfiguration, TsServerLogLevel, TypeScriptServiceConfiguration } from '../utils/configuration'; -import { Logger } from '../utils/logger'; +import { memoize } from '../utils/memoize'; import { isWeb, isWebAndHasSharedArrayBuffers } from '../utils/platform'; -import { TypeScriptPluginPathsProvider } from '../utils/pluginPathsProvider'; -import { PluginManager } from '../utils/plugins'; -import { TelemetryReporter } from '../utils/telemetry'; -import Tracer from '../utils/tracer'; +import { API } from './api'; import { ILogDirectoryProvider } from './logDirectoryProvider'; +import { TypeScriptPluginPathsProvider } from './pluginPathsProvider'; +import { PluginManager } from './plugins'; import { GetErrRoutingTsServer, ITypeScriptServer, SingleTsServer, SyntaxRoutingTsServer, TsServerDelegate, TsServerLog, TsServerProcessFactory, TsServerProcessKind } from './server'; import { TypeScriptVersionManager } from './versionManager'; import { ITypeScriptVersionProvider, TypeScriptVersion } from './versionProvider'; -import { memoize } from '../utils/memoize'; const enum CompositeServerType { /** Run a single server that handles all commands */ @@ -232,7 +232,7 @@ export class TypeScriptServerSpawner { tsServerLog = { type: 'file', uri: logFilePath }; args.push('--logVerbosity', TsServerLogLevel.toString(configuration.tsServerLogLevel)); - args.push('--logFile', logFilePath.path); + args.push('--logFile', logFilePath.fsPath); } } } diff --git a/extensions/typescript-language-features/src/tsServer/versionManager.ts b/extensions/typescript-language-features/src/tsServer/versionManager.ts index 68d44a76890..43a2413e383 100644 --- a/extensions/typescript-language-features/src/tsServer/versionManager.ts +++ b/extensions/typescript-language-features/src/tsServer/versionManager.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { TypeScriptServiceConfiguration } from '../configuration/configuration'; import { setImmediate } from '../utils/async'; -import { TypeScriptServiceConfiguration } from '../utils/configuration'; import { Disposable } from '../utils/dispose'; import { ITypeScriptVersionProvider, TypeScriptVersion } from './versionProvider'; diff --git a/extensions/typescript-language-features/src/tsServer/versionProvider.electron.ts b/extensions/typescript-language-features/src/tsServer/versionProvider.electron.ts index dca0fb21f1b..239519e6f6a 100644 --- a/extensions/typescript-language-features/src/tsServer/versionProvider.electron.ts +++ b/extensions/typescript-language-features/src/tsServer/versionProvider.electron.ts @@ -6,9 +6,9 @@ import * as fs from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; -import API from '../utils/api'; -import { TypeScriptServiceConfiguration } from '../utils/configuration'; +import { TypeScriptServiceConfiguration } from '../configuration/configuration'; import { RelativeWorkspacePathResolver } from '../utils/relativePathResolver'; +import { API } from './api'; import { ITypeScriptVersionProvider, TypeScriptVersion, TypeScriptVersionSource } from './versionProvider'; @@ -189,7 +189,7 @@ export class DiskTypeScriptVersionProvider implements ITypeScriptVersionProvider } catch (err) { return undefined; } - if (!desc || !desc.version) { + if (!desc?.version) { return undefined; } return desc.version ? API.fromVersionString(desc.version) : undefined; diff --git a/extensions/typescript-language-features/src/tsServer/versionProvider.ts b/extensions/typescript-language-features/src/tsServer/versionProvider.ts index bdf08a0e13d..2eaa0670551 100644 --- a/extensions/typescript-language-features/src/tsServer/versionProvider.ts +++ b/extensions/typescript-language-features/src/tsServer/versionProvider.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import API from '../utils/api'; -import { TypeScriptServiceConfiguration } from '../utils/configuration'; +import { TypeScriptServiceConfiguration } from '../configuration/configuration'; +import { API } from './api'; export const enum TypeScriptVersionSource { diff --git a/extensions/typescript-language-features/src/utils/tsconfig.ts b/extensions/typescript-language-features/src/tsconfig.ts similarity index 95% rename from extensions/typescript-language-features/src/utils/tsconfig.ts rename to extensions/typescript-language-features/src/tsconfig.ts index af25f38cf0c..ebbdd2a85cc 100644 --- a/extensions/typescript-language-features/src/utils/tsconfig.ts +++ b/extensions/typescript-language-features/src/tsconfig.ts @@ -5,10 +5,10 @@ import * as path from 'path'; import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; -import { ITypeScriptServiceClient, ServerResponse } from '../typescriptService'; -import { nulToken } from '../utils/cancellation'; -import { TypeScriptServiceConfiguration } from './configuration'; +import type * as Proto from './tsServer/protocol/protocol'; +import { ITypeScriptServiceClient, ServerResponse } from './typescriptService'; +import { nulToken } from './utils/cancellation'; +import { TypeScriptServiceConfiguration } from './configuration/configuration'; export const enum ProjectType { diff --git a/extensions/typescript-language-features/src/utils/typeConverters.ts b/extensions/typescript-language-features/src/typeConverters.ts similarity index 96% rename from extensions/typescript-language-features/src/utils/typeConverters.ts rename to extensions/typescript-language-features/src/typeConverters.ts index 2574fae4064..58babe2bda3 100644 --- a/extensions/typescript-language-features/src/utils/typeConverters.ts +++ b/extensions/typescript-language-features/src/typeConverters.ts @@ -8,9 +8,9 @@ */ import * as vscode from 'vscode'; -import type * as Proto from '../protocol'; -import * as PConst from '../protocol.const'; -import { ITypeScriptServiceClient } from '../typescriptService'; +import type * as Proto from './tsServer/protocol/protocol'; +import * as PConst from './tsServer/protocol/protocol.const'; +import { ITypeScriptServiceClient } from './typescriptService'; export namespace Range { export const fromTextSpan = (span: Proto.TextSpan): vscode.Range => diff --git a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts index d89bb33290e..7009799430e 100644 --- a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts +++ b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts @@ -10,31 +10,31 @@ import * as vscode from 'vscode'; import { CommandManager } from './commands/commandManager'; +import { ServiceConfigurationProvider } from './configuration/configuration'; +import { DiagnosticLanguage, LanguageDescription } from './configuration/languageDescription'; import { IExperimentationTelemetryReporter } from './experimentTelemetryReporter'; import { DiagnosticKind } from './languageFeatures/diagnostics'; import FileConfigurationManager from './languageFeatures/fileConfigurationManager'; import LanguageProvider from './languageProvider'; -import * as Proto from './protocol'; -import * as PConst from './protocol.const'; +import { LogLevelMonitor } from './logging/logLevelMonitor'; +import { Logger } from './logging/logger'; import { OngoingRequestCancellerFactory } from './tsServer/cancellation'; import { ILogDirectoryProvider } from './tsServer/logDirectoryProvider'; +import { PluginManager } from './tsServer/plugins'; +import * as errorCodes from './tsServer/protocol/errorCodes'; +import * as Proto from './tsServer/protocol/protocol'; +import * as PConst from './tsServer/protocol/protocol.const'; import { TsServerProcessFactory } from './tsServer/server'; import { ITypeScriptVersionProvider } from './tsServer/versionProvider'; +import * as typeConverters from './typeConverters'; import TypeScriptServiceClient from './typescriptServiceClient'; +import { ActiveJsTsEditorTracker } from './ui/activeJsTsEditorTracker'; import { IntellisenseStatus } from './ui/intellisenseStatus'; +import * as LargeProjectStatus from './ui/largeProjectStatus'; +import TypingsStatus, { AtaProgressReporter } from './ui/typingsStatus'; import { VersionStatus } from './ui/versionStatus'; -import { ActiveJsTsEditorTracker } from './utils/activeJsTsEditorTracker'; import { coalesce } from './utils/arrays'; -import { ServiceConfigurationProvider } from './utils/configuration'; import { Disposable } from './utils/dispose'; -import * as errorCodes from './utils/errorCodes'; -import { DiagnosticLanguage, LanguageDescription } from './utils/languageDescription'; -import * as LargeProjectStatus from './utils/largeProjectStatus'; -import { LogLevelMonitor } from './utils/logLevelMonitor'; -import { Logger } from './utils/logger'; -import { PluginManager } from './utils/plugins'; -import * as typeConverters from './utils/typeConverters'; -import TypingsStatus, { AtaProgressReporter } from './utils/typingsStatus'; // Style check diagnostics that can be reported as warnings const styleCheckDiagnostics = new Set([ @@ -250,7 +250,7 @@ export default class TypeScriptServiceClientHost extends Disposable { private configFileDiagnosticsReceived(event: Proto.ConfigFileDiagnosticEvent): void { // See https://github.com/microsoft/TypeScript/issues/10384 const body = event.body; - if (!body || !body.diagnostics || !body.configFile) { + if (!body?.diagnostics || !body.configFile) { return; } diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index faba971b1d6..1a79016273c 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as Proto from './protocol'; +import * as Proto from './tsServer/protocol/protocol'; import BufferSyncSupport from './tsServer/bufferSyncSupport'; import { ExecutionTarget } from './tsServer/server'; import { TypeScriptVersion } from './tsServer/versionProvider'; -import API from './utils/api'; -import { TypeScriptServiceConfiguration } from './utils/configuration'; -import { PluginManager } from './utils/plugins'; -import { TelemetryReporter } from './utils/telemetry'; +import { API } from './tsServer/api'; +import { TypeScriptServiceConfiguration } from './configuration/configuration'; +import { PluginManager } from './tsServer/plugins'; +import { TelemetryReporter } from './logging/telemetry'; export enum ServerType { Syntax = 'syntax', @@ -74,6 +74,8 @@ interface StandardTsServerRequests { 'provideInlayHints': [Proto.InlayHintsRequestArgs, Proto.InlayHintsResponse]; 'encodedSemanticClassifications-full': [Proto.EncodedSemanticClassificationsRequestArgs, Proto.EncodedSemanticClassificationsResponse]; 'findSourceDefinition': [Proto.FileLocationRequestArgs, Proto.DefinitionResponse]; + 'getMoveToRefactoringFileSuggestions': [Proto.GetMoveToRefactoringFileSuggestionsRequestArgs, Proto.GetMoveToRefactoringFileSuggestionsResponse]; + 'getEditsForMoveToFileRefactor': [Proto.GetEditsForMoveToFileRefactorRequestArgs, Proto.GetEditsForMoveToFileRefactorResponse]; } interface NoResponseTsServerRequests { diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 190c6730687..a3884bab936 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -7,28 +7,28 @@ import * as path from 'path'; import * as vscode from 'vscode'; import { IExperimentationTelemetryReporter } from './experimentTelemetryReporter'; import { DiagnosticKind, DiagnosticsManager } from './languageFeatures/diagnostics'; -import * as Proto from './protocol'; -import { EventName } from './protocol.const'; +import * as Proto from './tsServer/protocol/protocol'; +import { EventName } from './tsServer/protocol/protocol.const'; +import { API } from './tsServer/api'; import BufferSyncSupport from './tsServer/bufferSyncSupport'; import { OngoingRequestCancellerFactory } from './tsServer/cancellation'; import { ILogDirectoryProvider } from './tsServer/logDirectoryProvider'; +import { TypeScriptPluginPathsProvider } from './tsServer/pluginPathsProvider'; import { ITypeScriptServer, TsServerLog, TsServerProcessFactory, TypeScriptServerExitEvent } from './tsServer/server'; import { TypeScriptServerError } from './tsServer/serverError'; import { TypeScriptServerSpawner } from './tsServer/spawner'; import { TypeScriptVersionManager } from './tsServer/versionManager'; import { ITypeScriptVersionProvider, TypeScriptVersion } from './tsServer/versionProvider'; import { ClientCapabilities, ClientCapability, ExecConfig, ITypeScriptServiceClient, ServerResponse, TypeScriptRequests } from './typescriptService'; -import API from './utils/api'; -import { ServiceConfigurationProvider, SyntaxServerConfiguration, TsServerLogLevel, TypeScriptServiceConfiguration, areServiceConfigurationsEqual } from './utils/configuration'; +import { ServiceConfigurationProvider, SyntaxServerConfiguration, TsServerLogLevel, TypeScriptServiceConfiguration, areServiceConfigurationsEqual } from './configuration/configuration'; import { Disposable } from './utils/dispose'; -import * as fileSchemes from './utils/fileSchemes'; -import { Logger } from './utils/logger'; +import * as fileSchemes from './configuration/fileSchemes'; +import { Logger } from './logging/logger'; import { isWeb, isWebAndHasSharedArrayBuffers } from './utils/platform'; -import { TypeScriptPluginPathsProvider } from './utils/pluginPathsProvider'; -import { PluginManager, TypeScriptServerPlugin } from './utils/plugins'; -import { TelemetryProperties, TelemetryReporter, VSCodeTelemetryReporter } from './utils/telemetry'; -import Tracer from './utils/tracer'; -import { ProjectType, inferredProjectCompilerOptions } from './utils/tsconfig'; +import { PluginManager, TypeScriptServerPlugin } from './tsServer/plugins'; +import { TelemetryProperties, TelemetryReporter, VSCodeTelemetryReporter } from './logging/telemetry'; +import Tracer from './logging/tracer'; +import { ProjectType, inferredProjectCompilerOptions } from './tsconfig'; export interface TsDiagnostics { @@ -605,11 +605,14 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.lastStart = Date.now(); startService = false; this.hasServerFatallyCrashedTooManyTimes = true; - prompt = vscode.window.showErrorMessage( - this.pluginManager.plugins.length - ? vscode.l10n.t("The JS/TS language service immediately crashed 5 times. The service will not be restarted.\nThis may be caused by a plugin contributed by one of these extensions: {0}", pluginExtensionList) - : vscode.l10n.t("The JS/TS language service immediately crashed 5 times. The service will not be restarted."), - reportIssueItem); + if (this.pluginManager.plugins.length) { + prompt = vscode.window.showErrorMessage( + vscode.l10n.t("The JS/TS language service immediately crashed 5 times. The service will not be restarted.\nThis may be caused by a plugin contributed by one of these extensions: {0}.\nPlease try disabling these extensions before filing an issue against VS Code.", pluginExtensionList)); + } else { + prompt = vscode.window.showErrorMessage( + vscode.l10n.t("The JS/TS language service immediately crashed 5 times. The service will not be restarted."), + reportIssueItem); + } /* __GDPR__ "serviceExited" : { @@ -623,22 +626,28 @@ export default class TypeScriptServiceClient extends Disposable implements IType } else if (diff < 60 * 1000 * 5 /* 5 Minutes */) { this.lastStart = Date.now(); if (!this._isPromptingAfterCrash) { - prompt = vscode.window.showWarningMessage( - this.pluginManager.plugins.length - ? vscode.l10n.t("The JS/TS language service crashed 5 times in the last 5 Minutes.\nThis may be caused by a plugin contributed by one of these extensions: {0}", pluginExtensionList) - : vscode.l10n.t("The JS/TS language service crashed 5 times in the last 5 Minutes."), - reportIssueItem); + if (this.pluginManager.plugins.length) { + prompt = vscode.window.showWarningMessage( + vscode.l10n.t("The JS/TS language service crashed 5 times in the last 5 Minutes.\nThis may be caused by a plugin contributed by one of these extensions: {0}\nPlease try disabling these extensions before filing an issue against VS Code.", pluginExtensionList)); + } else { + prompt = vscode.window.showWarningMessage( + vscode.l10n.t("The JS/TS language service crashed 5 times in the last 5 Minutes."), + reportIssueItem); + } } } } else if (['vscode-insiders', 'code-oss'].includes(vscode.env.uriScheme)) { // Prompt after a single restart this.numberRestarts = 0; if (!this._isPromptingAfterCrash) { - prompt = vscode.window.showWarningMessage( - this.pluginManager.plugins.length - ? vscode.l10n.t("The JS/TS language service crashed.\nThis may be caused by a plugin contributed by one of these extensions: {0}", pluginExtensionList) - : vscode.l10n.t("The JS/TS language service crashed."), - reportIssueItem); + if (this.pluginManager.plugins.length) { + prompt = vscode.window.showWarningMessage( + vscode.l10n.t("The JS/TS language service crashed.\nThis may be caused by a plugin contributed by one of these extensions: {0}.\nPlease try disabling these extensions before filing an issue against VS Code.", pluginExtensionList)); + } else { + prompt = vscode.window.showWarningMessage( + vscode.l10n.t("The JS/TS language service crashed."), + reportIssueItem); + } } } @@ -688,12 +697,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType } if (resource.scheme === fileSchemes.file && !isWeb()) { - if (!resource.fsPath) { - return undefined; - } - - // Convert to posix style path - return path.posix.normalize(resource.fsPath.split(path.sep).join(path.posix.sep)); + return resource.fsPath; } return (this.isProjectWideIntellisenseOnWebEnabled() ? '' : this.inMemoryResourcePrefix) @@ -1047,7 +1051,7 @@ function getReportIssueArgsForError( [ `**Global TypeScript Server Plugins**`, `â—ï¸ Please test with extensions disabled. Extensions are the root cause of most TypeScript server crashes`, - globalPlugins.map(plugin => `- \`${plugin.name}\``).join('\n') + globalPlugins.map(plugin => `- \`${plugin.name}\` contributed by the \`${plugin.extension.id}\` extension`).join('\n') ].join('\n\n') ); } diff --git a/extensions/typescript-language-features/src/utils/activeJsTsEditorTracker.ts b/extensions/typescript-language-features/src/ui/activeJsTsEditorTracker.ts similarity index 92% rename from extensions/typescript-language-features/src/utils/activeJsTsEditorTracker.ts rename to extensions/typescript-language-features/src/ui/activeJsTsEditorTracker.ts index ab9e9576d67..e7ad8d7ea09 100644 --- a/extensions/typescript-language-features/src/utils/activeJsTsEditorTracker.ts +++ b/extensions/typescript-language-features/src/ui/activeJsTsEditorTracker.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { Disposable } from './dispose'; -import { isJsConfigOrTsConfigFileName } from './languageDescription'; -import { isSupportedLanguageMode } from './languageIds'; +import { isJsConfigOrTsConfigFileName } from '../configuration/languageDescription'; +import { isSupportedLanguageMode } from '../configuration/languageIds'; +import { Disposable } from '../utils/dispose'; /** * Tracks the active JS/TS editor. diff --git a/extensions/typescript-language-features/src/ui/intellisenseStatus.ts b/extensions/typescript-language-features/src/ui/intellisenseStatus.ts index 2334e7d2e64..61aff6cda2f 100644 --- a/extensions/typescript-language-features/src/ui/intellisenseStatus.ts +++ b/extensions/typescript-language-features/src/ui/intellisenseStatus.ts @@ -5,11 +5,11 @@ import * as vscode from 'vscode'; import { CommandManager } from '../commands/commandManager'; +import { isSupportedLanguageMode, isTypeScriptDocument, jsTsLanguageModes } from '../configuration/languageIds'; +import { ProjectType, isImplicitProjectConfigFile, openOrCreateConfig, openProjectConfigForFile, openProjectConfigOrPromptToCreate } from '../tsconfig'; import { ClientCapability, ITypeScriptServiceClient } from '../typescriptService'; -import { ActiveJsTsEditorTracker } from '../utils/activeJsTsEditorTracker'; import { Disposable } from '../utils/dispose'; -import { isSupportedLanguageMode, isTypeScriptDocument, jsTsLanguageModes } from '../utils/languageIds'; -import { isImplicitProjectConfigFile, openOrCreateConfig, openProjectConfigForFile, openProjectConfigOrPromptToCreate, ProjectType } from '../utils/tsconfig'; +import { ActiveJsTsEditorTracker } from './activeJsTsEditorTracker'; namespace IntellisenseState { diff --git a/extensions/typescript-language-features/src/ui/jsNodeWalkthrough.electron.ts b/extensions/typescript-language-features/src/ui/jsNodeWalkthrough.electron.ts index a1a6bd2ac2d..1c9ceeb87ff 100644 --- a/extensions/typescript-language-features/src/ui/jsNodeWalkthrough.electron.ts +++ b/extensions/typescript-language-features/src/ui/jsNodeWalkthrough.electron.ts @@ -3,11 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from 'vscode'; import * as cp from 'child_process'; +import * as vscode from 'vscode'; -import { Disposable } from '../utils/dispose'; import { CommandManager } from '../commands/commandManager'; +import { Disposable } from '../utils/dispose'; export async function nodeWasResolvable(): Promise { diff --git a/extensions/typescript-language-features/src/utils/largeProjectStatus.ts b/extensions/typescript-language-features/src/ui/largeProjectStatus.ts similarity index 96% rename from extensions/typescript-language-features/src/utils/largeProjectStatus.ts rename to extensions/typescript-language-features/src/ui/largeProjectStatus.ts index 8dacf80dab2..4fd094d2969 100644 --- a/extensions/typescript-language-features/src/utils/largeProjectStatus.ts +++ b/extensions/typescript-language-features/src/ui/largeProjectStatus.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { TelemetryReporter } from '../logging/telemetry'; +import { isImplicitProjectConfigFile, openOrCreateConfig, ProjectType } from '../tsconfig'; import { ITypeScriptServiceClient } from '../typescriptService'; -import { TelemetryReporter } from './telemetry'; -import { isImplicitProjectConfigFile, openOrCreateConfig, ProjectType } from './tsconfig'; interface Hint { @@ -15,7 +15,7 @@ interface Hint { class ExcludeHintItem { public configFileName?: string; - private _item: vscode.StatusBarItem; + private readonly _item: vscode.StatusBarItem; private _currentHint?: Hint; constructor( diff --git a/extensions/typescript-language-features/src/utils/managedFileContext.ts b/extensions/typescript-language-features/src/ui/managedFileContext.ts similarity index 87% rename from extensions/typescript-language-features/src/utils/managedFileContext.ts rename to extensions/typescript-language-features/src/ui/managedFileContext.ts index 09942b0c82b..0b929f85277 100644 --- a/extensions/typescript-language-features/src/utils/managedFileContext.ts +++ b/extensions/typescript-language-features/src/ui/managedFileContext.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { disabledSchemes } from '../configuration/fileSchemes'; +import { isJsConfigOrTsConfigFileName } from '../configuration/languageDescription'; +import { isSupportedLanguageMode } from '../configuration/languageIds'; +import { Disposable } from '../utils/dispose'; import { ActiveJsTsEditorTracker } from './activeJsTsEditorTracker'; -import { Disposable } from './dispose'; -import { disabledSchemes } from './fileSchemes'; -import { isJsConfigOrTsConfigFileName } from './languageDescription'; -import { isSupportedLanguageMode } from './languageIds'; /**E * When clause context set when the current file is managed by vscode's built-in typescript extension. diff --git a/extensions/typescript-language-features/src/utils/typingsStatus.ts b/extensions/typescript-language-features/src/ui/typingsStatus.ts similarity index 98% rename from extensions/typescript-language-features/src/utils/typingsStatus.ts rename to extensions/typescript-language-features/src/ui/typingsStatus.ts index 4924a93ad24..2e0d53b363e 100644 --- a/extensions/typescript-language-features/src/utils/typingsStatus.ts +++ b/extensions/typescript-language-features/src/ui/typingsStatus.ts @@ -5,7 +5,7 @@ import * as vscode from 'vscode'; import { ITypeScriptServiceClient } from '../typescriptService'; -import { Disposable } from './dispose'; +import { Disposable } from '../utils/dispose'; const typingsInstallTimeout = 30 * 1000; diff --git a/extensions/typescript-language-features/src/ui/versionStatus.ts b/extensions/typescript-language-features/src/ui/versionStatus.ts index 3e1629d8f1f..a4f377782a8 100644 --- a/extensions/typescript-language-features/src/ui/versionStatus.ts +++ b/extensions/typescript-language-features/src/ui/versionStatus.ts @@ -5,10 +5,10 @@ import * as vscode from 'vscode'; import { SelectTypeScriptVersionCommand } from '../commands/selectTypeScriptVersion'; +import { jsTsLanguageModes } from '../configuration/languageIds'; import { TypeScriptVersion } from '../tsServer/versionProvider'; import { ITypeScriptServiceClient } from '../typescriptService'; import { Disposable } from '../utils/dispose'; -import { jsTsLanguageModes } from '../utils/languageIds'; export class VersionStatus extends Disposable { diff --git a/extensions/typescript-language-features/src/utils/fileSystem.electron.ts b/extensions/typescript-language-features/src/utils/fs.electron.ts similarity index 100% rename from extensions/typescript-language-features/src/utils/fileSystem.electron.ts rename to extensions/typescript-language-features/src/utils/fs.electron.ts diff --git a/extensions/typescript-language-features/src/utils/resourceMap.ts b/extensions/typescript-language-features/src/utils/resourceMap.ts index cf97365831c..a024a761da3 100644 --- a/extensions/typescript-language-features/src/utils/resourceMap.ts +++ b/extensions/typescript-language-features/src/utils/resourceMap.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as fileSchemes from '../utils/fileSchemes'; +import * as fileSchemes from '../configuration/fileSchemes'; /** * Maps of file resources diff --git a/extensions/vscode-api-tests/package.json b/extensions/vscode-api-tests/package.json index 5044b091bb1..835214dbd88 100644 --- a/extensions/vscode-api-tests/package.json +++ b/extensions/vscode-api-tests/package.json @@ -18,7 +18,6 @@ "findTextInFiles", "fsChunks", "notebookCellExecutionState", - "notebookControllerKind", "notebookDeprecated", "notebookLiveShare", "notebookMessaging", diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts index 4f8a1211c2d..c85fdcb4c81 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts @@ -20,6 +20,7 @@ async function createInteractiveWindow(kernel: Kernel) { `vscode.vscode-api-tests/${kernel.controller.id}`, undefined )) as unknown as INativeInteractiveWindow; + assert.ok(notebookEditor, 'Interactive Window was not created successfully'); return { notebookEditor, inputUri }; } @@ -29,16 +30,25 @@ async function addCell(code: string, notebook: vscode.NotebookDocument) { const edit = vscode.NotebookEdit.insertCells(notebook.cellCount, [cell]); const workspaceEdit = new vscode.WorkspaceEdit(); workspaceEdit.set(notebook.uri, [edit]); + const event = asPromise(vscode.workspace.onDidChangeNotebookDocument); await vscode.workspace.applyEdit(workspaceEdit); + await event; return notebook.cellAt(notebook.cellCount - 1); } -async function addCellAndRun(code: string, notebook: vscode.NotebookDocument, i: number) { +async function addCellAndRun(code: string, notebook: vscode.NotebookDocument) { + const initialCellCount = notebook.cellCount; const cell = await addCell(code, notebook); + const event = asPromise(vscode.workspace.onDidChangeNotebookDocument); - await vscode.commands.executeCommand('notebook.cell.execute', { start: i, end: i + 1 }, notebook.uri); - await event; - assert.strictEqual(cell.outputs.length, 1, 'execute failed'); + await vscode.commands.executeCommand('notebook.cell.execute', { start: initialCellCount, end: initialCellCount + 1 }, notebook.uri); + try { + await event; + } catch (e) { + const result = notebook.cellAt(notebook.cellCount - 1); + assert.fail(`Notebook change event was not triggered after executing newly added cell. Initial Cell count: ${initialCellCount}. Current cell count: ${notebook.cellCount}. execution summary: ${JSON.stringify(result.executionSummary)}`); + } + assert.strictEqual(cell.outputs.length, 1, `Executed cell has no output. Initial Cell count: ${initialCellCount}. Current cell count: ${notebook.cellCount}. execution summary: ${JSON.stringify(cell.executionSummary)}`); return cell; } @@ -66,7 +76,6 @@ async function addCellAndRun(code: string, notebook: vscode.NotebookDocument, i: test('Can open an interactive window and execute from input box', async () => { assert.ok(vscode.workspace.workspaceFolders); const { notebookEditor, inputUri } = await createInteractiveWindow(defaultKernel); - assert.ok(notebookEditor); const inputBox = vscode.window.visibleTextEditors.find( (e) => e.document.uri.path === inputUri.path @@ -83,11 +92,10 @@ async function addCellAndRun(code: string, notebook: vscode.NotebookDocument, i: test('Interactive window scrolls after execute', async () => { assert.ok(vscode.workspace.workspaceFolders); const { notebookEditor } = await createInteractiveWindow(defaultKernel); - assert.ok(notebookEditor); // Run and add a bunch of cells for (let i = 0; i < 10; i++) { - await addCellAndRun(`print ${i}`, notebookEditor.notebook, i); + await addCellAndRun(`print ${i}`, notebookEditor.notebook); } // Verify visible range has the last cell @@ -97,19 +105,18 @@ async function addCellAndRun(code: string, notebook: vscode.NotebookDocument, i: test('Interactive window has the correct kernel', async () => { assert.ok(vscode.workspace.workspaceFolders); - const { notebookEditor } = await createInteractiveWindow(defaultKernel); - assert.ok(notebookEditor); + await createInteractiveWindow(defaultKernel); await vscode.commands.executeCommand('workbench.action.closeActiveEditor'); // Create a new interactive window with a different kernel - const { notebookEditor: notebookEditor2 } = await createInteractiveWindow(secondKernel); - assert.ok(notebookEditor2); + const { notebookEditor } = await createInteractiveWindow(secondKernel); + assert.ok(notebookEditor); // Verify the kernel is the secondary one - await addCellAndRun(`print`, notebookEditor2.notebook, 0); + await addCellAndRun(`print`, notebookEditor.notebook); - assert.strictEqual(secondKernel.associatedNotebooks.has(notebookEditor2.notebook.uri.toString()), true, `Secondary kernel was not set as the kernel for the interactive window`); + assert.strictEqual(secondKernel.associatedNotebooks.has(notebookEditor.notebook.uri.toString()), true, `Secondary kernel was not set as the kernel for the interactive window`); }); }); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts index 5632c7e96d3..ce245f31116 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -939,7 +939,7 @@ suite('vscode API - workspace', () => { } } - test('The api workspace.applyEdit failed for some case of mixing resourceChange and textEdit #80688', async function () { + test('The api workspace.applyEdit failed for some case of mixing resourceChange and textEdit #80688, 1/2', async function () { const file1 = await createRandomFile(); const file2 = await createRandomFile(); const we = new vscode.WorkspaceEdit(); @@ -958,7 +958,7 @@ suite('vscode API - workspace', () => { assert.strictEqual(document.getText(), expected2); }); - test('The api workspace.applyEdit failed for some case of mixing resourceChange and textEdit #80688', async function () { + test('The api workspace.applyEdit failed for some case of mixing resourceChange and textEdit #80688, 2/2', async function () { const file1 = await createRandomFile(); const file2 = await createRandomFile(); const we = new vscode.WorkspaceEdit(); diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test-173216_sh.json b/extensions/vscode-colorize-tests/test/colorize-results/test-173216_sh.json index b4506179a82..08df18f6b4a 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test-173216_sh.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test-173216_sh.json @@ -29,7 +29,7 @@ }, { "c": "declare", - "t": "source.shell meta.statement.shell meta.command.shell meta.command_name.shell storage.modifier.declare.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell storage.modifier.declare.shell", "r": { "dark_plus": "storage.modifier: #569CD6", "light_plus": "storage.modifier: #0000FF", @@ -43,7 +43,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.command.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -57,7 +57,7 @@ }, { "c": "-", - "t": "source.shell meta.statement.shell meta.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -71,7 +71,7 @@ }, { "c": "A", - "t": "source.shell meta.statement.shell meta.command.shell string.unquoted.argument constant.other.option", + "t": "source.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument constant.other.option", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -85,7 +85,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -99,7 +99,7 @@ }, { "c": "juices=", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.argument.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -113,7 +113,7 @@ }, { "c": "(", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -211,21 +211,21 @@ }, { "c": "=", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell keyword.operator.assignment.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell", "r": { - "dark_plus": "keyword.operator: #D4D4D4", - "light_plus": "keyword.operator: #000000", - "dark_vs": "keyword.operator: #D4D4D4", - "light_vs": "keyword.operator: #000000", - "hc_black": "keyword.operator: #D4D4D4", - "dark_plus_experimental": "keyword.operator: #D4D4D4", - "hc_light": "keyword.operator: #000000", - "light_plus_experimental": "keyword.operator: #000000" + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_plus_experimental": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_plus_experimental": "default: #3B3B3B" } }, { "c": "'", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.quoted.single.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.quoted.shell string.quoted.single.shell punctuation.definition.string.begin.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -239,7 +239,7 @@ }, { "c": "Apple Juice", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.quoted.single.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.continuation string.quoted.single entity.name.command", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -253,7 +253,7 @@ }, { "c": "'", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.quoted.single.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell string.quoted.single.shell punctuation.definition.string.end.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -351,21 +351,21 @@ }, { "c": "=", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell keyword.operator.assignment.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell", "r": { - "dark_plus": "keyword.operator: #D4D4D4", - "light_plus": "keyword.operator: #000000", - "dark_vs": "keyword.operator: #D4D4D4", - "light_vs": "keyword.operator: #000000", - "hc_black": "keyword.operator: #D4D4D4", - "dark_plus_experimental": "keyword.operator: #D4D4D4", - "hc_light": "keyword.operator: #000000", - "light_plus_experimental": "keyword.operator: #000000" + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_plus_experimental": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_plus_experimental": "default: #3B3B3B" } }, { "c": "'", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.quoted.single.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.quoted.shell string.quoted.single.shell punctuation.definition.string.begin.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -379,7 +379,7 @@ }, { "c": "Orange Juice", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.quoted.single.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.continuation string.quoted.single entity.name.command", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -393,7 +393,7 @@ }, { "c": "'", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.quoted.single.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell string.quoted.single.shell punctuation.definition.string.end.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -449,7 +449,7 @@ }, { "c": "echo", - "t": "source.shell meta.statement.shell meta.command.shell entity.name.command.shell support.function.builtin.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell support.function.builtin.shell", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -463,7 +463,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -477,7 +477,7 @@ }, { "c": "\"", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -491,7 +491,7 @@ }, { "c": "$", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell punctuation.section.bracket.curly.variable.begin.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -505,7 +505,7 @@ }, { "c": "{", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.begin.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.begin.shell punctuation.definition.variable.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -519,21 +519,21 @@ }, { "c": "juices", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion variable.other.normal.shell", "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "string: #CE9178", "light_vs": "string: #A31515", - "hc_black": "string: #CE9178", - "dark_plus_experimental": "string: #CE9178", - "hc_light": "string: #0F4A85", - "light_plus_experimental": "string: #A31515" + "hc_black": "variable: #9CDCFE", + "dark_plus_experimental": "variable: #9CDCFE", + "hc_light": "variable: #001080", + "light_plus_experimental": "variable: #001080" } }, { "c": "[", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.array.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion punctuation.section.array.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -547,7 +547,7 @@ }, { "c": "'apple'", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -561,7 +561,7 @@ }, { "c": "]", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.array.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion punctuation.section.array.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -575,7 +575,7 @@ }, { "c": "}", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.end.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.end.shell punctuation.definition.variable.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -589,7 +589,7 @@ }, { "c": "\"", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test-173336_sh.json b/extensions/vscode-colorize-tests/test/colorize-results/test-173336_sh.json index 55f5a27eb5f..65fefcd51f5 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test-173336_sh.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test-173336_sh.json @@ -267,7 +267,7 @@ }, { "c": "$", - "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell punctuation.definition.variable.shell punctuation.section.bracket.curly.variable.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell punctuation.definition.variable.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -281,7 +281,7 @@ }, { "c": "{", - "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell punctuation.section.bracket.curly.variable.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell punctuation.section.bracket.curly.variable.begin.shell punctuation.definition.variable.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -295,7 +295,7 @@ }, { "c": "#", - "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell keyword.operator.expansion.shell", + "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell meta.parameter-expansion keyword.operator.expansion.shell", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -309,21 +309,21 @@ }, { "c": "cmd", - "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell", + "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell meta.parameter-expansion variable.other.normal.shell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_plus_experimental": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_plus_experimental": "default: #3B3B3B" + "hc_black": "variable: #9CDCFE", + "dark_plus_experimental": "variable: #9CDCFE", + "hc_light": "variable: #001080", + "light_plus_experimental": "variable: #001080" } }, { "c": "[", - "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell punctuation.section.array.shell", + "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell meta.parameter-expansion punctuation.section.array.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -337,7 +337,7 @@ }, { "c": "@", - "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell", + "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell meta.parameter-expansion", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -351,7 +351,7 @@ }, { "c": "]", - "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell punctuation.section.array.shell", + "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell meta.parameter-expansion punctuation.section.array.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -365,7 +365,7 @@ }, { "c": "}", - "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell punctuation.section.bracket.curly.variable.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.arithmetic.shell punctuation.section.bracket.curly.variable.end.shell punctuation.definition.variable.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -463,7 +463,7 @@ }, { "c": "\"", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.command_name.quoted.shell string.quoted.double.shell punctuation.definition.string.begin.shell entity.name.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.quoted.shell string.quoted.double.shell punctuation.definition.string.begin.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -477,7 +477,7 @@ }, { "c": "$", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.command_name.continuation string.quoted.double entity.name.command punctuation.definition.variable.shell punctuation.section.bracket.curly.variable.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.continuation string.quoted.double entity.name.command punctuation.definition.variable.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -491,7 +491,7 @@ }, { "c": "{", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.command_name.continuation string.quoted.double entity.name.command punctuation.section.bracket.curly.variable.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.continuation string.quoted.double entity.name.command punctuation.section.bracket.curly.variable.begin.shell punctuation.definition.variable.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -505,21 +505,21 @@ }, { "c": "cmd", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.command_name.continuation string.quoted.double entity.name.command", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.continuation string.quoted.double entity.name.command meta.parameter-expansion variable.other.normal.shell", "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "string: #CE9178", "light_vs": "string: #A31515", - "hc_black": "string: #CE9178", - "dark_plus_experimental": "string: #CE9178", - "hc_light": "string: #0F4A85", - "light_plus_experimental": "string: #A31515" + "hc_black": "variable: #9CDCFE", + "dark_plus_experimental": "variable: #9CDCFE", + "hc_light": "variable: #001080", + "light_plus_experimental": "variable: #001080" } }, { "c": "[", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.command_name.continuation string.quoted.double entity.name.command punctuation.section.array.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.continuation string.quoted.double entity.name.command meta.parameter-expansion punctuation.section.array.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -533,7 +533,7 @@ }, { "c": "@", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.command_name.continuation string.quoted.double entity.name.command", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.continuation string.quoted.double entity.name.command meta.parameter-expansion", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -547,7 +547,7 @@ }, { "c": "]", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.command_name.continuation string.quoted.double entity.name.command punctuation.section.array.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.continuation string.quoted.double entity.name.command meta.parameter-expansion punctuation.section.array.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -561,7 +561,7 @@ }, { "c": "}", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.command_name.continuation string.quoted.double entity.name.command punctuation.section.bracket.curly.variable.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell meta.statement.command.name.continuation string.quoted.double entity.name.command punctuation.section.bracket.curly.variable.end.shell punctuation.definition.variable.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -575,16 +575,16 @@ }, { "c": "\"", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell punctuation.definition.string.end.shell entity.name.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell string.quoted.double.shell punctuation.definition.string.end.shell entity.name.command.shell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_plus_experimental": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_plus_experimental": "default: #3B3B3B" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -603,21 +603,21 @@ }, { "c": "printf", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell support.function.builtin.shell", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", + "dark_plus": "support.function: #DCDCAA", + "light_plus": "support.function: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_plus_experimental": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_plus_experimental": "default: #3B3B3B" + "hc_black": "support.function: #DCDCAA", + "dark_plus_experimental": "support.function: #DCDCAA", + "hc_light": "support.function: #5E2CBC", + "light_plus_experimental": "support.function: #795E26" } }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -631,7 +631,7 @@ }, { "c": "'", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.single.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.single.shell punctuation.definition.string.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -645,7 +645,7 @@ }, { "c": "%s", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.single.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.single.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -659,7 +659,7 @@ }, { "c": "'", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.single.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.single.shell punctuation.definition.string.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -673,7 +673,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -687,7 +687,7 @@ }, { "c": "\"", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -701,7 +701,7 @@ }, { "c": "$", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell punctuation.section.bracket.curly.variable.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -715,7 +715,7 @@ }, { "c": "{", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.begin.shell punctuation.definition.variable.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -729,21 +729,21 @@ }, { "c": "cmd", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion variable.other.normal.shell", "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "string: #CE9178", "light_vs": "string: #A31515", - "hc_black": "string: #CE9178", - "dark_plus_experimental": "string: #CE9178", - "hc_light": "string: #0F4A85", - "light_plus_experimental": "string: #A31515" + "hc_black": "variable: #9CDCFE", + "dark_plus_experimental": "variable: #9CDCFE", + "hc_light": "variable: #001080", + "light_plus_experimental": "variable: #001080" } }, { "c": "[", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.array.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion punctuation.section.array.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -757,7 +757,7 @@ }, { "c": "@", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -771,7 +771,7 @@ }, { "c": "]", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.array.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion punctuation.section.array.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -785,7 +785,7 @@ }, { "c": "}", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.end.shell punctuation.definition.variable.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -799,7 +799,7 @@ }, { "c": "\"", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test-4287_pug.json b/extensions/vscode-colorize-tests/test/colorize-results/test-4287_pug.json index 0b4101aa160..96f7cac13a9 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test-4287_pug.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test-4287_pug.json @@ -1,16 +1,16 @@ [ { "c": ".ssdsd", - "t": "text.pug entity.other.attribute-name.class.pug", + "t": "text.pug meta.selector.css entity.other.attribute-name.class.css.pug", "r": { - "dark_plus": "entity.other.attribute-name: #9CDCFE", - "light_plus": "entity.other.attribute-name: #E50000", - "dark_vs": "entity.other.attribute-name: #9CDCFE", - "light_vs": "entity.other.attribute-name: #E50000", - "hc_black": "entity.other.attribute-name: #9CDCFE", - "dark_plus_experimental": "entity.other.attribute-name: #9CDCFE", - "hc_light": "entity.other.attribute-name: #264F78", - "light_plus_experimental": "entity.other.attribute-name: #E50000" + "dark_plus": "entity.other.attribute-name.class.css: #D7BA7D", + "light_plus": "entity.other.attribute-name.class.css: #800000", + "dark_vs": "entity.other.attribute-name.class.css: #D7BA7D", + "light_vs": "entity.other.attribute-name.class.css: #800000", + "hc_black": "entity.other.attribute-name.class.css: #D7BA7D", + "dark_plus_experimental": "entity.other.attribute-name.class.css: #D7BA7D", + "hc_light": "entity.other.attribute-name.class.css: #0F4A85", + "light_plus_experimental": "entity.other.attribute-name.class.css: #800000" } }, { diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test-strings_ts.json b/extensions/vscode-colorize-tests/test/colorize-results/test-strings_ts.json index 150fb748f40..72cf1ed35ee 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test-strings_ts.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test-strings_ts.json @@ -393,12 +393,12 @@ }, { "c": "tag", - "t": "source.ts string.template.ts entity.name.function.tagged-template.ts", + "t": "source.ts entity.name.function.tagged-template.ts", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "entity.name.function: #DCDCAA", "dark_plus_experimental": "entity.name.function: #DCDCAA", "hc_light": "entity.name.function: #5E2CBC", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_bib.json b/extensions/vscode-colorize-tests/test/colorize-results/test_bib.json index 5b38da10f3d..3913908ff54 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_bib.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_bib.json @@ -1,7 +1,21 @@ [ { - "c": "% a sample bibliography file", - "t": "text.bibtex comment.block.bibtex", + "c": "%", + "t": "text.bibtex comment.line.percentage.bibtex punctuation.definition.comment.bibtex", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_plus_experimental": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_plus_experimental": "comment: #008000" + } + }, + { + "c": " a sample bibliography file", + "t": "text.bibtex comment.line.percentage.bibtex", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -15,7 +29,7 @@ }, { "c": "%", - "t": "text.bibtex comment.block.bibtex", + "t": "text.bibtex comment.line.percentage.bibtex punctuation.definition.comment.bibtex", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1372,8 +1386,8 @@ } }, { - "c": "% The authors mentioned here are almost, but not quite,", - "t": "text.bibtex comment.block.bibtex", + "c": "%", + "t": "text.bibtex comment.line.percentage.bibtex punctuation.definition.comment.bibtex", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1386,8 +1400,36 @@ } }, { - "c": "% entirely unrelated to Matt Groening.", - "t": "text.bibtex comment.block.bibtex", + "c": " The authors mentioned here are almost, but not quite,", + "t": "text.bibtex comment.line.percentage.bibtex", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_plus_experimental": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_plus_experimental": "comment: #008000" + } + }, + { + "c": "%", + "t": "text.bibtex comment.line.percentage.bibtex punctuation.definition.comment.bibtex", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668", + "dark_plus_experimental": "comment: #6A9955", + "hc_light": "comment: #515151", + "light_plus_experimental": "comment: #008000" + } + }, + { + "c": " entirely unrelated to Matt Groening.", + "t": "text.bibtex comment.line.percentage.bibtex", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_html.json b/extensions/vscode-colorize-tests/test/colorize-results/test_html.json index 19bd221616f..e4fab060509 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_html.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_html.json @@ -2478,8 +2478,22 @@ } }, { - "c": "{ ", - "t": "text.html.derivative meta.embedded.block.html source.js meta.objectliteral.js", + "c": "{", + "t": "text.html.derivative meta.embedded.block.html source.js meta.objectliteral.js meta.block.js punctuation.definition.block.js", + "r": { + "dark_plus": "meta.embedded: #D4D4D4", + "light_plus": "meta.embedded: #000000", + "dark_vs": "meta.embedded: #D4D4D4", + "light_vs": "meta.embedded: #000000", + "hc_black": "meta.embedded: #FFFFFF", + "dark_plus_experimental": "meta.embedded: #D4D4D4", + "hc_light": "meta.embedded: #292929", + "light_plus_experimental": "meta.embedded: #000000" + } + }, + { + "c": " ", + "t": "text.html.derivative meta.embedded.block.html source.js meta.objectliteral.js meta.block.js", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -2493,7 +2507,7 @@ }, { "c": "modules", - "t": "text.html.derivative meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js variable.other.readwrite.js", + "t": "text.html.derivative meta.embedded.block.html source.js meta.objectliteral.js meta.block.js variable.other.readwrite.js", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -2507,7 +2521,21 @@ }, { "c": " ", - "t": "text.html.derivative meta.embedded.block.html source.js meta.objectliteral.js meta.object.member.js", + "t": "text.html.derivative meta.embedded.block.html source.js meta.objectliteral.js meta.block.js", + "r": { + "dark_plus": "meta.embedded: #D4D4D4", + "light_plus": "meta.embedded: #000000", + "dark_vs": "meta.embedded: #D4D4D4", + "light_vs": "meta.embedded: #000000", + "hc_black": "meta.embedded: #FFFFFF", + "dark_plus_experimental": "meta.embedded: #D4D4D4", + "hc_light": "meta.embedded: #292929", + "light_plus_experimental": "meta.embedded: #000000" + } + }, + { + "c": "}", + "t": "text.html.derivative meta.embedded.block.html source.js meta.objectliteral.js meta.block.js punctuation.definition.block.js", "r": { "dark_plus": "meta.embedded: #D4D4D4", "light_plus": "meta.embedded: #000000", @@ -2533,20 +2561,6 @@ "light_plus_experimental": "meta.embedded: #000000" } }, - { - "c": "}", - "t": "text.html.derivative meta.embedded.block.html source.js", - "r": { - "dark_plus": "meta.embedded: #D4D4D4", - "light_plus": "meta.embedded: #000000", - "dark_vs": "meta.embedded: #D4D4D4", - "light_vs": "meta.embedded: #000000", - "hc_black": "meta.embedded: #FFFFFF", - "dark_plus_experimental": "meta.embedded: #D4D4D4", - "hc_light": "meta.embedded: #292929", - "light_plus_experimental": "meta.embedded: #000000" - } - }, { "c": ",", "t": "text.html.derivative meta.embedded.block.html source.js punctuation.separator.comma.js", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_pug.json b/extensions/vscode-colorize-tests/test/colorize-results/test_pug.json index 02989476982..6937100ab9f 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_pug.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_pug.json @@ -154,17 +154,45 @@ } }, { - "c": "'width: '", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "'", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "width: ", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "'", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -266,17 +294,45 @@ } }, { - "c": "'%'", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "'", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "%", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "'", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -532,17 +588,45 @@ } }, { - "c": "'width: '", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "'", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "width: ", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "'", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -644,17 +728,45 @@ } }, { - "c": "'%'", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "'", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "%", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "'", + "t": "text.pug meta.tag.other attribute_value string.quoted.single.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -1121,16 +1233,16 @@ }, { "c": ".welcomebox", - "t": "text.pug entity.other.attribute-name.class.pug", + "t": "text.pug meta.selector.css entity.other.attribute-name.class.css.pug", "r": { - "dark_plus": "entity.other.attribute-name: #9CDCFE", - "light_plus": "entity.other.attribute-name: #E50000", - "dark_vs": "entity.other.attribute-name: #9CDCFE", - "light_vs": "entity.other.attribute-name: #E50000", - "hc_black": "entity.other.attribute-name: #9CDCFE", - "dark_plus_experimental": "entity.other.attribute-name: #9CDCFE", - "hc_light": "entity.other.attribute-name: #264F78", - "light_plus_experimental": "entity.other.attribute-name: #E50000" + "dark_plus": "entity.other.attribute-name.class.css: #D7BA7D", + "light_plus": "entity.other.attribute-name.class.css: #800000", + "dark_vs": "entity.other.attribute-name.class.css: #D7BA7D", + "light_vs": "entity.other.attribute-name.class.css: #800000", + "hc_black": "entity.other.attribute-name.class.css: #D7BA7D", + "dark_plus_experimental": "entity.other.attribute-name.class.css: #D7BA7D", + "hc_light": "entity.other.attribute-name.class.css: #0F4A85", + "light_plus_experimental": "entity.other.attribute-name.class.css: #800000" } }, { @@ -1317,16 +1429,16 @@ }, { "c": ".loginbox", - "t": "text.pug entity.other.attribute-name.class.pug", + "t": "text.pug meta.selector.css entity.other.attribute-name.class.css.pug", "r": { - "dark_plus": "entity.other.attribute-name: #9CDCFE", - "light_plus": "entity.other.attribute-name: #E50000", - "dark_vs": "entity.other.attribute-name: #9CDCFE", - "light_vs": "entity.other.attribute-name: #E50000", - "hc_black": "entity.other.attribute-name: #9CDCFE", - "dark_plus_experimental": "entity.other.attribute-name: #9CDCFE", - "hc_light": "entity.other.attribute-name: #264F78", - "light_plus_experimental": "entity.other.attribute-name: #E50000" + "dark_plus": "entity.other.attribute-name.class.css: #D7BA7D", + "light_plus": "entity.other.attribute-name.class.css: #800000", + "dark_vs": "entity.other.attribute-name.class.css: #D7BA7D", + "light_vs": "entity.other.attribute-name.class.css: #800000", + "hc_black": "entity.other.attribute-name.class.css: #D7BA7D", + "dark_plus_experimental": "entity.other.attribute-name.class.css: #D7BA7D", + "hc_light": "entity.other.attribute-name.class.css: #0F4A85", + "light_plus_experimental": "entity.other.attribute-name.class.css: #800000" } }, { @@ -1400,17 +1512,45 @@ } }, { - "c": "\"login\"", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "login", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -1456,17 +1596,45 @@ } }, { - "c": "\"/login\"", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "/login", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -1512,17 +1680,45 @@ } }, { - "c": "\"post\"", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "post", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -1610,17 +1806,45 @@ } }, { - "c": "\"text\"", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "text", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -1666,17 +1890,45 @@ } }, { - "c": "\"user\"", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "user", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -1764,17 +2016,45 @@ } }, { - "c": "\"password\"", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "password", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -1820,17 +2100,45 @@ } }, { - "c": "\"pass\"", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "pass", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -1918,17 +2226,45 @@ } }, { - "c": "\"submit\"", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "submit", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { @@ -1974,17 +2310,45 @@ } }, { - "c": "\"login\"", - "t": "text.pug meta.tag.other attribute_value string.quoted.pug", + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.begin.js", "r": { "dark_plus": "string: #CE9178", - "light_plus": "string.quoted.pug: #0000FF", + "light_plus": "string: #A31515", "dark_vs": "string: #CE9178", - "light_vs": "string.quoted.pug: #0000FF", + "light_vs": "string: #A31515", "hc_black": "string: #CE9178", "dark_plus_experimental": "string: #CE9178", - "hc_light": "string.quoted.pug: #0F4A85", - "light_plus_experimental": "string.quoted.pug: #0000FF" + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "login", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" + } + }, + { + "c": "\"", + "t": "text.pug meta.tag.other attribute_value string.quoted.double.js punctuation.definition.string.end.js", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_plus_experimental": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_plus_experimental": "string: #A31515" } }, { diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_sh.json b/extensions/vscode-colorize-tests/test/colorize-results/test_sh.json index 2da8eabe682..c8b7d26b661 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_sh.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_sh.json @@ -603,7 +603,7 @@ }, { "c": "echo", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell entity.name.command.shell support.function.builtin.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell support.function.builtin.shell", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -617,7 +617,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -631,7 +631,7 @@ }, { "c": "\"", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -645,7 +645,7 @@ }, { "c": "$", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -659,7 +659,7 @@ }, { "c": "1", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell variable.parameter.positional.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell variable.parameter.positional.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -673,7 +673,7 @@ }, { "c": "\"", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -687,7 +687,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -729,7 +729,7 @@ }, { "c": "echo", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell entity.name.command.shell support.function.builtin.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell support.function.builtin.shell", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -743,7 +743,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -757,7 +757,7 @@ }, { "c": "\"", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -771,7 +771,7 @@ }, { "c": "$", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.other.normal.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.other.normal.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -785,7 +785,7 @@ }, { "c": "PWD", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell variable.other.normal.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell variable.other.normal.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -799,7 +799,7 @@ }, { "c": "/", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -813,49 +813,49 @@ }, { "c": "$", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell punctuation.section.bracket.curly.variable.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.shell", "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "string: #CE9178", "light_vs": "string: #A31515", - "hc_black": "string: #CE9178", - "dark_plus_experimental": "string: #CE9178", - "hc_light": "string: #0F4A85", - "light_plus_experimental": "string: #A31515" + "hc_black": "variable: #9CDCFE", + "dark_plus_experimental": "variable: #9CDCFE", + "hc_light": "variable: #001080", + "light_plus_experimental": "variable: #001080" } }, { "c": "{", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.begin.shell punctuation.definition.variable.shell variable.parameter.positional.shell", "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "string: #CE9178", "light_vs": "string: #A31515", - "hc_black": "string: #CE9178", - "dark_plus_experimental": "string: #CE9178", - "hc_light": "string: #0F4A85", - "light_plus_experimental": "string: #A31515" + "hc_black": "variable: #9CDCFE", + "dark_plus_experimental": "variable: #9CDCFE", + "hc_light": "variable: #001080", + "light_plus_experimental": "variable: #001080" } }, { "c": "1", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion variable.parameter.positional.shell", "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "string: #CE9178", "light_vs": "string: #A31515", - "hc_black": "string: #CE9178", - "dark_plus_experimental": "string: #CE9178", - "hc_light": "string: #0F4A85", - "light_plus_experimental": "string: #A31515" + "hc_black": "variable: #9CDCFE", + "dark_plus_experimental": "variable: #9CDCFE", + "hc_light": "variable: #001080", + "light_plus_experimental": "variable: #001080" } }, { "c": "#", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell keyword.operator.expansion.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion keyword.operator.expansion.shell", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -869,7 +869,7 @@ }, { "c": ".", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -883,7 +883,7 @@ }, { "c": "/", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell keyword.operator.expansion.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell meta.parameter-expansion keyword.operator.expansion.shell", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -897,21 +897,21 @@ }, { "c": "}", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.section.bracket.curly.variable.end.shell punctuation.definition.variable.shell variable.parameter.positional.shell", "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "string: #CE9178", "light_vs": "string: #A31515", - "hc_black": "string: #CE9178", - "dark_plus_experimental": "string: #CE9178", - "hc_light": "string: #0F4A85", - "light_plus_experimental": "string: #A31515" + "hc_black": "variable: #9CDCFE", + "dark_plus_experimental": "variable: #9CDCFE", + "hc_light": "variable: #001080", + "light_plus_experimental": "variable: #001080" } }, { "c": "\"", - "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1023,7 +1023,7 @@ }, { "c": "dirname", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1037,7 +1037,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1051,7 +1051,7 @@ }, { "c": "$(", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1065,7 +1065,7 @@ }, { "c": "dirname", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1079,7 +1079,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1093,7 +1093,7 @@ }, { "c": "$(", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1107,7 +1107,7 @@ }, { "c": "realpath", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1121,7 +1121,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1135,7 +1135,7 @@ }, { "c": "\"", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1149,7 +1149,7 @@ }, { "c": "$", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1163,7 +1163,7 @@ }, { "c": "0", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell variable.parameter.positional.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell variable.parameter.positional.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1177,7 +1177,7 @@ }, { "c": "\"", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1191,7 +1191,7 @@ }, { "c": ")", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1205,7 +1205,7 @@ }, { "c": ")", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1303,7 +1303,7 @@ }, { "c": "dirname", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1317,7 +1317,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1331,7 +1331,7 @@ }, { "c": "$(", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1345,7 +1345,7 @@ }, { "c": "dirname", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1359,7 +1359,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1373,7 +1373,7 @@ }, { "c": "$(", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.begin.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1387,7 +1387,7 @@ }, { "c": "readlink", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1401,7 +1401,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1415,7 +1415,7 @@ }, { "c": "-", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1429,7 +1429,7 @@ }, { "c": "f", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell string.unquoted.argument constant.other.option", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument constant.other.option", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1443,7 +1443,7 @@ }, { "c": " ", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1457,7 +1457,7 @@ }, { "c": "$", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell punctuation.definition.variable.shell variable.parameter.positional.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell punctuation.definition.variable.shell variable.parameter.positional.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1471,7 +1471,7 @@ }, { "c": "0", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell variable.parameter.positional.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell variable.parameter.positional.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1485,7 +1485,7 @@ }, { "c": ")", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1499,7 +1499,7 @@ }, { "c": ")", - "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.end.shell", + "t": "source.shell meta.scope.if-block.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.interpolated.dollar.shell punctuation.definition.evaluation.parens.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1583,7 +1583,7 @@ }, { "c": "xcode-select", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1597,7 +1597,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1611,7 +1611,7 @@ }, { "c": "-", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1625,7 +1625,7 @@ }, { "c": "print-path", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell string.unquoted.argument constant.other.option", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument constant.other.option", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1695,7 +1695,7 @@ }, { "c": "xcrun", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1709,7 +1709,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1723,7 +1723,7 @@ }, { "c": "-", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1737,7 +1737,7 @@ }, { "c": "sdk", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell string.unquoted.argument constant.other.option", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument constant.other.option", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1751,7 +1751,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1765,7 +1765,7 @@ }, { "c": "iphoneos", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.argument.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1779,7 +1779,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1793,7 +1793,7 @@ }, { "c": "-", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1807,7 +1807,7 @@ }, { "c": "find", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell string.unquoted.argument constant.other.option", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument constant.other.option", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1821,7 +1821,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1835,7 +1835,7 @@ }, { "c": "lipo", - "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.argument.shell", + "t": "source.shell meta.statement.shell meta.expression.assignment.shell string.interpolated.dollar.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1863,7 +1863,7 @@ }, { "c": "cat", - "t": "source.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1877,7 +1877,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1891,7 +1891,7 @@ }, { "c": "<<-", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell keyword.operator.heredoc.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell keyword.operator.heredoc.shell", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1905,7 +1905,7 @@ }, { "c": "EOF", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell punctuation.definition.string.heredoc.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell punctuation.definition.string.heredoc.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1919,7 +1919,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1933,7 +1933,7 @@ }, { "c": ">", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell keyword.operator.redirect.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell keyword.operator.redirect.shell", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1947,7 +1947,7 @@ }, { "c": " /path/file", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1961,7 +1961,7 @@ }, { "c": "\t# A heredoc with a variable ", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.heredoc.indent", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.heredoc.indent", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1975,7 +1975,7 @@ }, { "c": "$", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.heredoc.indent punctuation.definition.variable.shell variable.other.normal.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.heredoc.indent punctuation.definition.variable.shell variable.other.normal.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1989,7 +1989,7 @@ }, { "c": "DEVELOPER", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.heredoc.indent variable.other.normal.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.heredoc.indent variable.other.normal.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -2003,7 +2003,7 @@ }, { "c": "\tsome more file", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.heredoc.indent", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.heredoc.indent", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2017,7 +2017,7 @@ }, { "c": "EOF", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell punctuation.definition.string.heredoc.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell punctuation.definition.string.heredoc.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2030,7 +2030,7 @@ } }, { - "c": "function ", + "c": "function", "t": "source.shell meta.function.shell storage.type.function.shell", "r": { "dark_plus": "storage.type: #569CD6", @@ -2043,6 +2043,20 @@ "light_plus_experimental": "storage.type: #0000FF" } }, + { + "c": " ", + "t": "source.shell meta.function.shell", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_plus_experimental": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_plus_experimental": "default: #3B3B3B" + } + }, { "c": "code", "t": "source.shell meta.function.shell entity.name.function.shell", @@ -2115,7 +2129,7 @@ }, { "c": "cd", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell entity.name.command.shell support.function.builtin.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell support.function.builtin.shell", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -2129,7 +2143,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2143,7 +2157,7 @@ }, { "c": "$", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell punctuation.definition.variable.shell variable.other.normal.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell punctuation.definition.variable.shell variable.other.normal.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -2157,7 +2171,7 @@ }, { "c": "ROOT", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell variable.other.normal.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell variable.other.normal.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -2227,7 +2241,7 @@ }, { "c": "test", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell entity.name.command.shell support.function.builtin.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell support.function.builtin.shell", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -2241,7 +2255,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2255,7 +2269,7 @@ }, { "c": "-", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument.shell constant.other.option.dash.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2269,7 +2283,7 @@ }, { "c": "d", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell string.unquoted.argument constant.other.option", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell string.unquoted.argument constant.other.option", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2283,7 +2297,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2297,7 +2311,7 @@ }, { "c": "node_modules", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2311,7 +2325,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2352,22 +2366,8 @@ } }, { - "c": ".", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell entity.name.command.shell support.function.builtin.shell", - "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA", - "dark_plus_experimental": "support.function: #DCDCAA", - "hc_light": "support.function: #5E2CBC", - "light_plus_experimental": "support.function: #795E26" - } - }, - { - "c": "/scripts/npm.sh", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "c": "./scripts/npm.sh", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2381,7 +2381,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2395,7 +2395,7 @@ }, { "c": "install", - "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2885,7 +2885,7 @@ }, { "c": "exec", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell entity.name.command.shell support.function.builtin.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell support.function.builtin.shell", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -2899,7 +2899,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2913,7 +2913,7 @@ }, { "c": "./.build/electron/Electron.app/Contents/MacOS/Electron", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2927,7 +2927,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2941,7 +2941,7 @@ }, { "c": ".", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2955,7 +2955,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2969,7 +2969,7 @@ }, { "c": "\"", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2983,7 +2983,7 @@ }, { "c": "$", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.all.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.all.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -2997,7 +2997,7 @@ }, { "c": "@", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell variable.parameter.positional.all.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell variable.parameter.positional.all.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -3011,7 +3011,7 @@ }, { "c": "\"", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -3067,7 +3067,7 @@ }, { "c": "exec", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell entity.name.command.shell support.function.builtin.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell support.function.builtin.shell", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -3081,7 +3081,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -3095,7 +3095,7 @@ }, { "c": "./.build/electron/electron", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -3109,7 +3109,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -3123,7 +3123,7 @@ }, { "c": ".", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.unquoted.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.unquoted.argument.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -3137,7 +3137,7 @@ }, { "c": " ", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -3151,7 +3151,7 @@ }, { "c": "\"", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -3165,7 +3165,7 @@ }, { "c": "$", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.all.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.all.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -3179,7 +3179,7 @@ }, { "c": "@", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell variable.parameter.positional.all.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell variable.parameter.positional.all.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -3193,7 +3193,7 @@ }, { "c": "\"", - "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.function.shell meta.function.body.shell meta.scope.if-block.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -3249,7 +3249,7 @@ }, { "c": "code", - "t": "source.shell meta.statement.shell meta.command.shell entity.name.command.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.statement.command.name.shell entity.name.command.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -3263,7 +3263,7 @@ }, { "c": " ", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -3277,7 +3277,7 @@ }, { "c": "\"", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.begin.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -3291,7 +3291,7 @@ }, { "c": "$", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.all.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.variable.shell variable.parameter.positional.all.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -3305,7 +3305,7 @@ }, { "c": "@", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell variable.parameter.positional.all.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell variable.parameter.positional.all.shell", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -3319,7 +3319,7 @@ }, { "c": "\"", - "t": "source.shell meta.statement.shell meta.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", + "t": "source.shell meta.statement.shell meta.statement.command.shell meta.argument.shell string.quoted.double.shell punctuation.definition.string.end.shell", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_sql.json b/extensions/vscode-colorize-tests/test/colorize-results/test_sql.json index 93b9a0656c2..393a6d72e4c 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_sql.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_sql.json @@ -448,7 +448,35 @@ } }, { - "c": " STATS;", + "c": " ", + "t": "source.sql", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_plus_experimental": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_plus_experimental": "default: #3B3B3B" + } + }, + { + "c": "STATS", + "t": "source.sql keyword.other.sql", + "r": { + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6", + "dark_plus_experimental": "keyword: #569CD6", + "hc_light": "keyword: #0F4A85", + "light_plus_experimental": "keyword: #0000FF" + } + }, + { + "c": ";", "t": "source.sql", "r": { "dark_plus": "default: #D4D4D4", diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 0c09ae0b431..ef51562d373 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@^4.9.5: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.2.tgz#891e1a90c5189d8506af64b9ef929fca99ba1ee5" + integrity sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw== vscode-grammar-updater@^1.1.0: version "1.1.0" diff --git a/package.json b/package.json index 1da790a529a..4ab0e2a7989 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", - "version": "1.76.0", - "distro": "cd6d83a02668b3ee1577d32ede0540c6e71b8119", + "version": "1.78.0", + "distro": "f2b77191fb66fe38026a11ba5a5e2e9debeda960", "author": { "name": "Microsoft Corporation" }, @@ -48,6 +48,7 @@ "compile-web": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js compile-web", "watch-web": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js watch-web", "eslint": "node build/eslint", + "stylelint": "node build/stylelint", "playwright-install": "node build/azure-pipelines/common/installPlaywright.js", "compile-build": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js compile-build", "compile-extensions-build": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js compile-extensions-build", @@ -57,7 +58,6 @@ "hygiene": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js hygiene", "core-ci": "node --max_old_space_size=8095 ./node_modules/gulp/bin/gulp.js core-ci", "extensions-ci": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js extensions-ci", - "webview-generate-csp-hash": "npx github:apaatsio/csp-hash-from-html csp-hash ./src/vs/workbench/contrib/webview/browser/pre/index.html", "perf": "node scripts/code-perf.js" }, "dependencies": { @@ -66,7 +66,7 @@ "@parcel/watcher": "2.1.0", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/policy-watcher": "^1.1.4", - "@vscode/ripgrep": "^1.14.2", + "@vscode/ripgrep": "^1.15.0", "@vscode/sqlite3": "5.1.2-vscode", "@vscode/sudo-prompt": "9.3.1", "@vscode/vscode-languagedetection": "1.0.21", @@ -77,29 +77,29 @@ "keytar": "7.9.0", "minimist": "^1.2.6", "native-is-elevated": "0.4.3", - "native-keymap": "3.3.2", - "native-watchdog": "1.4.1", - "node-pty": "0.11.0-beta29", + "native-keymap": "^3.3.2", + "native-watchdog": "^1.4.1", + "node-pty": "0.11.0-beta31", "spdlog": "^0.13.0", "tas-client-umd": "0.1.6", "v8-inspect-profiler": "^0.1.0", "vscode-oniguruma": "1.7.0", "vscode-proxy-agent": "^0.12.0", "vscode-regexpp": "^3.1.0", - "vscode-textmate": "8.0.0", - "xterm": "5.2.0-beta.29", - "xterm-addon-canvas": "0.4.0-beta.7", + "vscode-textmate": "9.0.0", + "xterm": "5.2.0-beta.35", + "xterm-addon-canvas": "0.4.0-beta.9", "xterm-addon-search": "0.11.0", "xterm-addon-serialize": "0.9.0", "xterm-addon-unicode11": "0.5.0", - "xterm-addon-webgl": "0.15.0-beta.7", - "xterm-headless": "5.2.0-beta.29", + "xterm-addon-webgl": "0.15.0-beta.8", + "xterm-headless": "5.2.0-beta.35", "yauzl": "^2.9.2", "yazl": "^2.4.3" }, "devDependencies": { "7zip": "0.0.6", - "@playwright/test": "1.27.1", + "@playwright/test": "1.32.1", "@swc/cli": "0.1.57", "@swc/core": "1.3.32", "@types/cookie": "^0.3.3", @@ -126,11 +126,11 @@ "@types/winreg": "^1.2.30", "@types/yauzl": "^2.9.1", "@types/yazl": "^2.4.2", - "@typescript-eslint/eslint-plugin": "^5.39.0", - "@typescript-eslint/experimental-utils": "^5.39.0", - "@typescript-eslint/parser": "^5.39.0", + "@typescript-eslint/eslint-plugin": "^5.57.0", + "@typescript-eslint/experimental-utils": "^5.57.0", + "@typescript-eslint/parser": "^5.57.0", "@vscode/l10n-dev": "0.0.21", - "@vscode/telemetry-extractor": "^1.9.8", + "@vscode/telemetry-extractor": "^1.9.9", "@vscode/test-web": "^0.0.34", "@vscode/vscode-perf": "^0.0.6", "ansi-colors": "^3.2.3", @@ -144,7 +144,7 @@ "debounce": "^1.0.0", "deemon": "^1.8.0", "electron": "19.1.9", - "eslint": "8.7.0", + "eslint": "8.36.0", "eslint-plugin-header": "3.1.1", "eslint-plugin-jsdoc": "^39.3.2", "eslint-plugin-local": "^1.0.0", @@ -210,7 +210,7 @@ "ts-loader": "^9.2.7", "ts-node": "^10.9.1", "tsec": "0.1.4", - "typescript": "^5.0.0-dev.20230209", + "typescript": "^5.1.0-dev.20230328", "typescript-formatter": "7.1.0", "underscore": "^1.12.1", "util": "^0.12.4", @@ -240,4 +240,4 @@ "elliptic": "^6.5.3", "nwmatcher": "^1.4.4" } -} \ No newline at end of file +} diff --git a/product.json b/product.json index 212ad63ab68..468039e8be2 100644 --- a/product.json +++ b/product.json @@ -47,7 +47,7 @@ }, { "name": "ms-vscode.js-debug", - "version": "1.75.1", + "version": "1.77.1", "repo": "https://github.com/microsoft/vscode-js-debug", "metadata": { "id": "25629058-ddac-4e17-abba-74678e126c5d", diff --git a/remote/package.json b/remote/package.json index d39cdb49361..ed567745d70 100644 --- a/remote/package.json +++ b/remote/package.json @@ -7,7 +7,7 @@ "@microsoft/1ds-post-js": "^3.2.2", "@parcel/watcher": "2.1.0", "@vscode/iconv-lite-umd": "0.7.0", - "@vscode/ripgrep": "^1.14.2", + "@vscode/ripgrep": "^1.15.0", "@vscode/vscode-languagedetection": "1.0.21", "cookie": "^0.4.0", "graceful-fs": "4.2.8", @@ -16,21 +16,21 @@ "jschardet": "3.0.0", "keytar": "7.9.0", "minimist": "^1.2.6", - "native-watchdog": "1.4.1", - "node-pty": "0.11.0-beta29", + "native-watchdog": "^1.4.1", + "node-pty": "0.11.0-beta31", "spdlog": "^0.13.0", "tas-client-umd": "0.1.6", "vscode-oniguruma": "1.7.0", "vscode-proxy-agent": "^0.12.0", "vscode-regexpp": "^3.1.0", - "vscode-textmate": "8.0.0", - "xterm": "5.2.0-beta.29", - "xterm-addon-canvas": "0.4.0-beta.7", + "vscode-textmate": "9.0.0", + "xterm": "5.2.0-beta.35", + "xterm-addon-canvas": "0.4.0-beta.9", "xterm-addon-search": "0.11.0", "xterm-addon-serialize": "0.9.0", "xterm-addon-unicode11": "0.5.0", - "xterm-addon-webgl": "0.15.0-beta.7", - "xterm-headless": "5.2.0-beta.29", + "xterm-addon-webgl": "0.15.0-beta.8", + "xterm-headless": "5.2.0-beta.35", "yauzl": "^2.9.2", "yazl": "^2.4.3" }, diff --git a/remote/web/package.json b/remote/web/package.json index 53620ea494a..1d15da91cf3 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -10,11 +10,11 @@ "jschardet": "3.0.0", "tas-client-umd": "0.1.6", "vscode-oniguruma": "1.7.0", - "vscode-textmate": "8.0.0", - "xterm": "5.2.0-beta.29", - "xterm-addon-canvas": "0.4.0-beta.7", + "vscode-textmate": "9.0.0", + "xterm": "5.2.0-beta.35", + "xterm-addon-canvas": "0.4.0-beta.9", "xterm-addon-search": "0.11.0", "xterm-addon-unicode11": "0.5.0", - "xterm-addon-webgl": "0.15.0-beta.7" + "xterm-addon-webgl": "0.15.0-beta.8" } } diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index 79830abf89f..54f9a742693 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -63,15 +63,15 @@ vscode-oniguruma@1.7.0: resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== -vscode-textmate@8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" - integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== +vscode-textmate@9.0.0: + version "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.4.0-beta.7: - version "0.4.0-beta.7" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.4.0-beta.7.tgz#ae365d8e10c900292186529f70f7f275ac94b3d5" - integrity sha512-r1hbQTsulI49orR5G3qWrJCwn2dKsEUCrgj6xsmgXuTeoUcGfed6lly+MvYlL3P8aPrxS2fC2TEzSM0Au4SX+w== +xterm-addon-canvas@0.4.0-beta.9: + version "0.4.0-beta.9" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.4.0-beta.9.tgz#e570fa4592890f92cc86706f2bba0dd128a8641d" + integrity sha512-BWRVWyUW7NY2g4BBMm3ecPQvbdyKXFgABnpmh4m0TVHqFJMNeXdNuTc94KiDbE+cvw8jtAY9NC/OIM4HcgjAIQ== xterm-addon-search@0.11.0: version "0.11.0" @@ -83,12 +83,12 @@ xterm-addon-unicode11@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-webgl@0.15.0-beta.7: - version "0.15.0-beta.7" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.15.0-beta.7.tgz#ab247b499f61e8eebff92e08ec5ca999d87e06af" - integrity sha512-7WCI/D6uFNp3y9TeTsbSo1h7gCy4h/yP2lWn8ZEjCaiGvO11DbKMq17fbiwaR3YmGWXoRKkcLaNIiqxFnjKO4w== +xterm-addon-webgl@0.15.0-beta.8: + version "0.15.0-beta.8" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.15.0-beta.8.tgz#2005198582f6f1f4a9b2612b9354c0bcc9f148d8" + integrity sha512-HjTr9bi3FvdOIPaaIpih6qdHX2z+H7sQPluLj5KzwCqRiEVUVRi19dl8SdHjf6dCmN3GahMhjV7D+zxHi2pLTw== -xterm@5.2.0-beta.29: - version "5.2.0-beta.29" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.29.tgz#99764aff5cd8cdb4335f5d59466b134cfcb45e3e" - integrity sha512-zx5RKcQqo78bza4R/m3WtxAJCBAF4U61fy6cxqb1PkqXF9/qdYlySUCVOauMxv+6n6cAxt3EQWwLlgvbvQBbsw== +xterm@5.2.0-beta.35: + version "5.2.0-beta.35" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.35.tgz#4a0c0aa81c89c42167c22d023648cced44fa3c25" + integrity sha512-6x6i61lucRrLWRKFeMO/ZOx5anvYR6FHpReLO2g0y1bp5zYWyZFzM6DepMV50729gubzxSLB8mvbmb9EpeIugQ== diff --git a/remote/yarn.lock b/remote/yarn.lock index efc0ca00a26..1fae3d896ae 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -58,10 +58,10 @@ resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48" integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg== -"@vscode/ripgrep@^1.14.2": - version "1.14.2" - resolved "https://registry.yarnpkg.com/@vscode/ripgrep/-/ripgrep-1.14.2.tgz#47c0eec2b64f53d8f7e1b5ffd22a62e229191c34" - integrity sha512-KDaehS8Jfdg1dqStaIPDKYh66jzKd5jy5aYEPzIv0JYFLADPsCSQPBUdsJVXnr0t72OlDcj96W05xt/rSnNFFQ== +"@vscode/ripgrep@^1.15.0": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@vscode/ripgrep/-/ripgrep-1.15.0.tgz#d6fec68d7c44d594967f21a6e6c97416cc7fb2bc" + integrity sha512-qbLYP3XPTfS5a80+WnGvDLhsD01LDrs03zjbbtWWnvwt8G9hP3j8mc3ckaIid7pj86MBSTyUb/ECaIWmJIGBYw== dependencies: https-proxy-agent "^5.0.0" proxy-from-env "^1.1.0" @@ -473,10 +473,10 @@ napi-build-utils@^1.0.1: resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== -native-watchdog@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/native-watchdog/-/native-watchdog-1.4.1.tgz#f5462cb878796c75f8a6c3c71aa0aa52d4992e05" - integrity sha512-RzGXNgoe54BmkkIFwegz7eeJm7xovTj/VG5qREfF+KeSqiVzHGnVwFoLzNLlYsqSSdIOIYoCOFlEhoS+asRVyQ== +native-watchdog@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/native-watchdog/-/native-watchdog-1.4.2.tgz#cf9f913157ee992723aa372b6137293c663be9b7" + integrity sha512-iT3Uj6FFdrW5vHbQ/ybiznLus9oiUoMJ8A8nyugXv9rV3EBhIodmGs+mztrwQyyBc+PB5/CrskAH/WxaUVRRSQ== node-abi@^3.3.0: version "3.8.0" @@ -505,10 +505,10 @@ node-gyp-build@^4.3.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== -node-pty@0.11.0-beta29: - version "0.11.0-beta29" - resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.11.0-beta29.tgz#863bce79346b453ed199614686008d1a3220abe8" - integrity sha512-pkSldLXjjwFrGd3EJWI0Pu1jnxeQaW0P9i2EQtO2RaK/pZ22pf99lQ8OfptYTPK2oKZbkjwzqh05uJJ2krH9iA== +node-pty@0.11.0-beta31: + version "0.11.0-beta31" + resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.11.0-beta31.tgz#f1e7b79d437a96b50c23580475eb7d4bdceb577f" + integrity sha512-fqsvKbdP1NuaFxu2zXborL/b5+CDrLruRK7CU0YaTjgbrYUsCR6IITCs1mORb1ZpIZ26ccvcc8TVfstGqwgl9g== dependencies: nan "^2.17.0" @@ -810,10 +810,10 @@ vscode-regexpp@^3.1.0: resolved "https://registry.yarnpkg.com/vscode-regexpp/-/vscode-regexpp-3.1.0.tgz#42d059b6fffe99bd42939c0d013f632f0cad823f" integrity sha512-pqtN65VC1jRLawfluX4Y80MMG0DHJydWhe5ZwMHewZD6sys4LbU6lHwFAHxeuaVE6Y6+xZOtAw+9hvq7/0ejkg== -vscode-textmate@8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" - integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== +vscode-textmate@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-9.0.0.tgz#313c6c8792b0507aef35aeb81b6b370b37c44d6c" + integrity sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg== vscode-windows-ca-certs@^0.3.0: version "0.3.0" @@ -841,10 +841,10 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -xterm-addon-canvas@0.4.0-beta.7: - version "0.4.0-beta.7" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.4.0-beta.7.tgz#ae365d8e10c900292186529f70f7f275ac94b3d5" - integrity sha512-r1hbQTsulI49orR5G3qWrJCwn2dKsEUCrgj6xsmgXuTeoUcGfed6lly+MvYlL3P8aPrxS2fC2TEzSM0Au4SX+w== +xterm-addon-canvas@0.4.0-beta.9: + version "0.4.0-beta.9" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.4.0-beta.9.tgz#e570fa4592890f92cc86706f2bba0dd128a8641d" + integrity sha512-BWRVWyUW7NY2g4BBMm3ecPQvbdyKXFgABnpmh4m0TVHqFJMNeXdNuTc94KiDbE+cvw8jtAY9NC/OIM4HcgjAIQ== xterm-addon-search@0.11.0: version "0.11.0" @@ -861,20 +861,20 @@ xterm-addon-unicode11@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-webgl@0.15.0-beta.7: - version "0.15.0-beta.7" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.15.0-beta.7.tgz#ab247b499f61e8eebff92e08ec5ca999d87e06af" - integrity sha512-7WCI/D6uFNp3y9TeTsbSo1h7gCy4h/yP2lWn8ZEjCaiGvO11DbKMq17fbiwaR3YmGWXoRKkcLaNIiqxFnjKO4w== +xterm-addon-webgl@0.15.0-beta.8: + version "0.15.0-beta.8" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.15.0-beta.8.tgz#2005198582f6f1f4a9b2612b9354c0bcc9f148d8" + integrity sha512-HjTr9bi3FvdOIPaaIpih6qdHX2z+H7sQPluLj5KzwCqRiEVUVRi19dl8SdHjf6dCmN3GahMhjV7D+zxHi2pLTw== -xterm-headless@5.2.0-beta.29: - version "5.2.0-beta.29" - resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.2.0-beta.29.tgz#dd08312fdb4292c217e685d9e2e8b1957364e298" - integrity sha512-1P4urIeDTkl2C+zGb4WUnKJMACZMPGYHwVXMjkB0WhMISbkt6M34MH9ljxHhnL99dHwlx2Lvi6wvhnpyZucWCg== +xterm-headless@5.2.0-beta.35: + version "5.2.0-beta.35" + resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.2.0-beta.35.tgz#8c3d4d06747e27a5bc4f0bf914479820a5b8f529" + integrity sha512-tq/zKnXEsVXGlhXHGNqPO47x9Fvew2avZ0wfMI1G80AEYrjxGY/3Quxwe9/C5ngIuPwk2CMbgDZwHhSFvyOrMA== -xterm@5.2.0-beta.29: - version "5.2.0-beta.29" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.29.tgz#99764aff5cd8cdb4335f5d59466b134cfcb45e3e" - integrity sha512-zx5RKcQqo78bza4R/m3WtxAJCBAF4U61fy6cxqb1PkqXF9/qdYlySUCVOauMxv+6n6cAxt3EQWwLlgvbvQBbsw== +xterm@5.2.0-beta.35: + version "5.2.0-beta.35" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.35.tgz#4a0c0aa81c89c42167c22d023648cced44fa3c25" + integrity sha512-6x6i61lucRrLWRKFeMO/ZOx5anvYR6FHpReLO2g0y1bp5zYWyZFzM6DepMV50729gubzxSLB8mvbmb9EpeIugQ== yallist@^4.0.0: version "4.0.0" diff --git a/resources/linux/snap/electron-launch b/resources/linux/snap/electron-launch index 87011928b49..cf2b931f3fe 100755 --- a/resources/linux/snap/electron-launch +++ b/resources/linux/snap/electron-launch @@ -4,6 +4,64 @@ # We need to handle that case and reset $SNAP SNAP=$(echo "$SNAP" | sed -e "s|/var/lib/snapd||g") +# +# Exports are based on https://github.com/snapcore/snapcraft/blob/master/extensions/desktop/common/desktop-exports +# + +# ensure_dir_exists calls `mkdir -p` if the given path is not a directory. +# This speeds up execution time by avoiding unnecessary calls to mkdir. +# +# Usage: ensure_dir_exists []... +# +function ensure_dir_exists() { + [ -d "$1" ] || mkdir -p "$@" +} + +declare -A PIDS +function async_exec() { + "$@" & + PIDS[$!]=$* +} +function wait_for_async_execs() { + for pid in "${!PIDS[@]}" + do + wait "$pid" && continue || echo "ERROR: ${PIDS[$pid]} exited abnormally with status $?" + done +} + +function prepend_dir() { + local -n var="$1" + local dir="$2" + # We can't check if the dir exists when the dir contains variables + if [[ "$dir" == *"\$"* || -d "$dir" ]]; then + export "${!var}=${dir}${var:+:$var}" + fi +} + +function append_dir() { + local -n var="$1" + local dir="$2" + # We can't check if the dir exists when the dir contains variables + if [[ "$dir" == *"\$"* || -d "$dir" ]]; then + export "${!var}=${var:+$var:}${dir}" + fi +} + +# shellcheck source=/dev/null +source "$SNAP_USER_DATA/.last_revision" 2>/dev/null || true +if [ "$SNAP_DESKTOP_LAST_REVISION" = "$SNAP_VERSION" ]; then + needs_update=false +else + needs_update=true +fi + +# Set $REALHOME to the users real home directory +REALHOME=$(getent passwd $UID | cut -d ':' -f 6) + +# Set config folder to local path +ensure_dir_exists "$SNAP_USER_DATA/.config" +chmod 700 "$SNAP_USER_DATA/.config" + if [ "$SNAP_ARCH" == "amd64" ]; then ARCH="x86_64-linux-gnu" elif [ "$SNAP_ARCH" == "armhf" ]; then @@ -14,21 +72,171 @@ else ARCH="$SNAP_ARCH-linux-gnu" fi -GDK_CACHE_DIR="$SNAP_USER_COMMON/.cache" -if [[ -d "$SNAP_USER_DATA/.cache" && ! -e "$GDK_CACHE_DIR" ]]; then +export SNAP_LAUNCHER_ARCH_TRIPLET="$ARCH" + +function is_subpath() { + dir="$(realpath "$1")" + parent="$(realpath "$2")" + [ "${dir##"${parent}"/}" != "${dir}" ] && return 0 || return 1 +} + +function can_open_file() { + [ -f "$1" ] && [ -r "$1" ] +} + +# XDG Config +prepend_dir XDG_CONFIG_DIRS "$SNAP/etc/xdg" + +# Define snaps' own data dir +prepend_dir XDG_DATA_DIRS "$SNAP/usr/share" +prepend_dir XDG_DATA_DIRS "$SNAP/share" +prepend_dir XDG_DATA_DIRS "$SNAP/data-dir" +prepend_dir XDG_DATA_DIRS "$SNAP_USER_DATA" + +# Set XDG_DATA_HOME to local path +ensure_dir_exists "$SNAP_USER_DATA/.local/share" + +# Workaround for GLib < 2.53.2 not searching for schemas in $XDG_DATA_HOME: +# https://bugzilla.gnome.org/show_bug.cgi?id=741335 +prepend_dir XDG_DATA_DIRS "$SNAP_USER_DATA/.local/share" + +# Set cache folder to local path +if [[ -d "$SNAP_USER_DATA/.cache" && ! -e "$SNAP_USER_COMMON/.cache" ]]; then # the .cache directory used to be stored under $SNAP_USER_DATA, migrate it mv "$SNAP_USER_DATA/.cache" "$SNAP_USER_COMMON/" fi -[ ! -d "$GDK_CACHE_DIR" ] && mkdir -p "$GDK_CACHE_DIR" +ensure_dir_exists "$SNAP_USER_COMMON/.cache" -# Gdk-pixbuf loaders -export GDK_PIXBUF_MODULE_FILE="$GDK_CACHE_DIR/gdk-pixbuf-loaders.cache" -export GDK_PIXBUF_MODULEDIR="$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/2.10.0/loaders" -if [ -f "$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders" ]; then - "$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders" > "$GDK_PIXBUF_MODULE_FILE" +# Create $XDG_RUNTIME_DIR if not exists (to be removed when LP: #1656340 is fixed) +# shellcheck disable=SC2174 +ensure_dir_exists "$XDG_RUNTIME_DIR" -m 700 + +# Ensure the app finds locale definitions (requires locales-all to be installed) +append_dir LOCPATH "$SNAP/usr/lib/locale" + +# If detect wayland server socket, then set environment so applications prefer +# wayland, and setup compat symlink (until we use user mounts. Remember, +# XDG_RUNTIME_DIR is /run/user//snap.$SNAP so look in the parent directory +# for the socket. For details: +# https://forum.snapcraft.io/t/wayland-dconf-and-xdg-runtime-dir/186/10 +# Applications that don't support wayland natively may define DISABLE_WAYLAND +# (to any non-empty value) to skip that logic entirely. +wayland_available=false +if [[ -n "$XDG_RUNTIME_DIR" && -z "$DISABLE_WAYLAND" ]]; then + wdisplay="wayland-0" + if [ -n "$WAYLAND_DISPLAY" ]; then + wdisplay="$WAYLAND_DISPLAY" + fi + wayland_sockpath="$XDG_RUNTIME_DIR/../$wdisplay" + wayland_snappath="$XDG_RUNTIME_DIR/$wdisplay" + if [ -S "$wayland_sockpath" ]; then + # if running under wayland, use it + #export WAYLAND_DEBUG=1 + # shellcheck disable=SC2034 + wayland_available=true + # create the compat symlink for now + if [ ! -e "$wayland_snappath" ]; then + ln -s "$wayland_sockpath" "$wayland_snappath" + fi + fi fi -# Create $XDG_RUNTIME_DIR if not exists (to be removed when https://pad.lv/1656340 is fixed) -[ -n "$XDG_RUNTIME_DIR" ] && mkdir -p -m 700 "$XDG_RUNTIME_DIR" +# Keep an array of data dirs, for looping through them +IFS=':' read -r -a data_dirs_array <<< "$XDG_DATA_DIRS" + +# Build mime.cache +# needed for gtk and qt icon +if [ "$needs_update" = true ]; then + rm -rf "$SNAP_USER_DATA/.local/share/mime" + if [ ! -f "$SNAP/usr/share/mime/mime.cache" ]; then + if command -v update-mime-database >/dev/null; then + cp --preserve=timestamps -dR "$SNAP/usr/share/mime" "$SNAP_USER_DATA/.local/share" + async_exec update-mime-database "$SNAP_USER_DATA/.local/share/mime" + fi + fi +fi + +# Gio modules and cache (including gsettings module) +export GIO_MODULE_DIR="$SNAP_USER_COMMON/.cache/gio-modules" +function compile_giomodules { + if [ -f "$1/glib-2.0/gio-querymodules" ]; then + rm -rf "$GIO_MODULE_DIR" + ensure_dir_exists "$GIO_MODULE_DIR" + ln -s "$1"/gio/modules/*.so "$GIO_MODULE_DIR" + "$1/glib-2.0/gio-querymodules" "$GIO_MODULE_DIR" + fi +} +if [ "$needs_update" = true ]; then + async_exec compile_giomodules "$SNAP/usr/lib/$ARCH" +fi + +# Setup compiled gsettings schema +GS_SCHEMA_DIR="$SNAP_USER_DATA/.local/share/glib-2.0/schemas" +function compile_schemas { + if [ -f "$1" ]; then + rm -rf "$GS_SCHEMA_DIR" + ensure_dir_exists "$GS_SCHEMA_DIR" + for ((i = 0; i < ${#data_dirs_array[@]}; i++)); do + schema_dir="${data_dirs_array[$i]}/glib-2.0/schemas" + if [ -f "$schema_dir/gschemas.compiled" ]; then + # This directory already has compiled schemas + continue + fi + if [ -n "$(ls -A "$schema_dir"/*.xml 2>/dev/null)" ]; then + ln -s "$schema_dir"/*.xml "$GS_SCHEMA_DIR" + fi + if [ -n "$(ls -A "$schema_dir"/*.override 2>/dev/null)" ]; then + ln -s "$schema_dir"/*.override "$GS_SCHEMA_DIR" + fi + done + # Only compile schemas if we copied anything + if [ -n "$(ls -A "$GS_SCHEMA_DIR"/*.xml "$GS_SCHEMA_DIR"/*.override 2>/dev/null)" ]; then + "$1" "$GS_SCHEMA_DIR" + fi + fi +} +if [ "$needs_update" = true ]; then + async_exec compile_schemas "$SNAP/usr/lib/$ARCH/glib-2.0/glib-compile-schemas" +fi + +# Gdk-pixbuf loaders +export GDK_PIXBUF_MODULE_FILE="$SNAP_USER_COMMON/.cache/gdk-pixbuf-loaders.cache" +export GDK_PIXBUF_MODULEDIR="$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/2.10.0/loaders" +if [ "$needs_update" = true ] || [ ! -f "$GDK_PIXBUF_MODULE_FILE" ]; then + rm -f "$GDK_PIXBUF_MODULE_FILE" + if [ -f "$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders" ]; then + async_exec "$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders" > "$GDK_PIXBUF_MODULE_FILE" + fi +fi + +# shellcheck disable=SC2154 +if [ "$wayland_available" = true ]; then + export GDK_BACKEND="wayland" +fi + +append_dir GTK_PATH "$SNAP/usr/lib/$ARCH/gtk-3.0" +append_dir GTK_PATH "$SNAP/usr/lib/gtk-3.0" +# We don't have gtk libraries in this path but +# enforcing this environment variable will disallow +# gtk binaries like `gtk-query-immodules` to not search +# in system default library paths. +# Based on https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkmodules.c#L104-136 +export GTK_EXE_PREFIX="$SNAP/usr" + +# ibus and fcitx integration +GTK_IM_MODULE_DIR="$SNAP_USER_COMMON/.cache/immodules" +export GTK_IM_MODULE_FILE="$GTK_IM_MODULE_DIR/immodules.cache" +# shellcheck disable=SC2154 +if [ "$needs_update" = true ]; then + rm -rf "$GTK_IM_MODULE_DIR" + ensure_dir_exists "$GTK_IM_MODULE_DIR" + ln -s "$SNAP"/usr/lib/"$ARCH"/gtk-3.0/3.0.0/immodules/*.so "$GTK_IM_MODULE_DIR" + async_exec "$SNAP/usr/lib/$ARCH/libgtk-3-0/gtk-query-immodules-3.0" > "$GTK_IM_MODULE_FILE" +fi + +# shellcheck disable=SC2154 +[ "$needs_update" = true ] && echo "SNAP_DESKTOP_LAST_REVISION=$SNAP_VERSION" > "$SNAP_USER_DATA/.last_revision" + +wait_for_async_execs exec "$@" diff --git a/resources/linux/snap/snapcraft.yaml b/resources/linux/snap/snapcraft.yaml index fc775b6554f..77602957fea 100644 --- a/resources/linux/snap/snapcraft.yaml +++ b/resources/linux/snap/snapcraft.yaml @@ -12,55 +12,74 @@ architectures: grade: stable confinement: classic +base: core20 +compression: lzo parts: - gnome: - plugin: nil - build-packages: - - software-properties-common - override-pull: | - add-apt-repository -y ppa:ubuntu-desktop/gnome-3-26 - apt -y update - code: - after: - - gnome plugin: dump source: . stage-packages: - - ibus-gtk3 - - fcitx-frontend-gtk3 - - gvfs-libs + - ca-certificates - libasound2 - - libgconf-2-4 - - libglib2.0-bin - - libgnome-keyring0 + - libatk-bridge2.0-0 + - libatk1.0-0 + - libatspi2.0-0 + - libcairo2 + - libcanberra-gtk3-module + - libcurl3-gnutls + - libcurl3-nss + - libcurl4 + - libdrm2 - libgbm1 + - libgl1 + - libglib2.0-0 - libgtk-3-0 - - libnotify4 - - libnspr4 + - libibus-1.0-5 - libnss3 - - libpcre3 - - libpulse0 + - libpango-1.0-0 - libsecret-1-0 + - libxcomposite1 + - libxdamage1 + - libxfixes3 + - libxkbcommon0 + - libxkbfile1 + - libxrandr2 - libxss1 - - libxtst6 - - zlib1g + - locales-all + - packagekit-gtk3-module + - xdg-utils prime: - -usr/share/doc - -usr/share/fonts - -usr/share/icons - -usr/share/lintian - -usr/share/man + override-build: | + snapcraftctl build + patchelf --force-rpath --set-rpath '$ORIGIN/../../lib/x86_64-linux-gnu:$ORIGIN:/snap/core20/current/lib/x86_64-linux-gnu' $SNAPCRAFT_PART_INSTALL/usr/share/@@NAME@@/chrome_crashpad_handler + cleanup: + after: + - code + plugin: nil + build-snaps: + - core20 + override-prime: | + set -eux + for snap in "core20"; do + cd "/snap/$snap/current" && find . -type f,l -exec rm -f "$SNAPCRAFT_PRIME/{}" \; + done + patchelf --print-rpath $SNAPCRAFT_PRIME/usr/share/@@NAME@@/chrome_crashpad_handler + apps: @@NAME@@: command: electron-launch $SNAP/usr/share/@@NAME@@/bin/@@NAME@@ --no-sandbox common-id: @@NAME@@.desktop environment: - GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas + GTK_USE_PORTAL: 1 url-handler: command: electron-launch $SNAP/usr/share/@@NAME@@/bin/@@NAME@@ --open-url --no-sandbox environment: - GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas + GTK_USE_PORTAL: 1 diff --git a/scripts/code-perf.js b/scripts/code-perf.js index d4bfd72c2b4..4bc431479f3 100644 --- a/scripts/code-perf.js +++ b/scripts/code-perf.js @@ -7,13 +7,12 @@ const path = require('path'); const perf = require('@vscode/vscode-perf'); -const minimist = require('minimist'); const VSCODE_FOLDER = path.join(__dirname, '..'); async function main() { - const args = [...process.argv]; + const args = process.argv; /** @type {string | undefined} */ let build = undefined; @@ -43,10 +42,13 @@ async function main() { args.push(path.join(VSCODE_FOLDER, 'package.json')); } - await perf.run(build ? { - ...minimist(args), - build - } : undefined); + if (build) { + args.push('--build'); + args.push(build); + } + + await perf.run(); + process.exit(0); } /** diff --git a/src/bootstrap-amd.js b/src/bootstrap-amd.js index 462b3b6dc8a..9905289f5d8 100644 --- a/src/bootstrap-amd.js +++ b/src/bootstrap-amd.js @@ -51,9 +51,9 @@ if (nlsConfig && nlsConfig.pseudo) { } /** - * @param {string} entrypoint - * @param {(value: any) => void} onLoad - * @param {(err: Error) => void} onError + * @param {string=} entrypoint + * @param {(value: any) => void=} onLoad + * @param {(err: Error) => void=} onError */ exports.load = function (entrypoint, onLoad, onError) { if (!entrypoint) { @@ -73,6 +73,6 @@ exports.load = function (entrypoint, onLoad, onError) { onLoad = onLoad || function () { }; onError = onError || function (err) { console.error(err); }; - performance.mark(`code/fork/willLoadCode`); + performance.mark('code/fork/willLoadCode'); loader([entrypoint], onLoad, onError); }; diff --git a/src/bootstrap-fork.js b/src/bootstrap-fork.js index b9d66d444a8..e3671222ccd 100644 --- a/src/bootstrap-fork.js +++ b/src/bootstrap-fork.js @@ -12,6 +12,9 @@ performance.mark('code/fork/start'); const bootstrap = require('./bootstrap'); const bootstrapNode = require('./bootstrap-node'); +// Crash reporter +configureCrashReporter(); + // Remove global paths from the node module lookup bootstrapNode.removeGlobalNodeModuleLookupPaths(); @@ -232,4 +235,27 @@ function terminateWhenParentTerminates() { } } +// TODO@bpasero remove this when sandbox is final +function configureCrashReporter() { + const crashReporterSandboxedHint = process.env['VSCODE_CRASH_REPORTER_SANDBOXED_HINT']; + if (crashReporterSandboxedHint) { + addCrashReporterParameter('_sandboxed', 'true'); + } + + const crashReporterProcessType = process.env['VSCODE_CRASH_REPORTER_PROCESS_TYPE']; + if (crashReporterProcessType) { + addCrashReporterParameter('processType', crashReporterProcessType); + } +} + +function addCrashReporterParameter(key, value) { + try { + if (process['crashReporter'] && typeof process['crashReporter'].addExtraParameter === 'function' /* Electron only */) { + process['crashReporter'].addExtraParameter(key, value); + } + } catch (error) { + console.error(error); + } +} + //#endregion diff --git a/src/buildfile.js b/src/buildfile.js index de976f51000..c7a24fd2850 100644 --- a/src/buildfile.js +++ b/src/buildfile.js @@ -54,6 +54,7 @@ exports.workerProfileAnalysis = [createEditorWorkerModuleDescription('vs/platfor exports.workbenchDesktop = [ createEditorWorkerModuleDescription('vs/workbench/contrib/output/common/outputLinkComputer'), + createEditorWorkerModuleDescription('vs/workbench/services/textMate/browser/worker/textMate.worker'), createModuleDescription('vs/workbench/contrib/debug/node/telemetryApp'), createModuleDescription('vs/platform/files/node/watcher/watcherMain'), createModuleDescription('vs/platform/terminal/node/ptyHostMain'), @@ -62,6 +63,7 @@ exports.workbenchDesktop = [ exports.workbenchWeb = [ createEditorWorkerModuleDescription('vs/workbench/contrib/output/common/outputLinkComputer'), + createEditorWorkerModuleDescription('vs/workbench/services/textMate/browser/worker/textMate.worker'), createModuleDescription('vs/code/browser/workbench/workbench', ['vs/workbench/workbench.web.main']) ]; @@ -76,7 +78,7 @@ exports.code = [ createModuleDescription('vs/code/node/cli'), createModuleDescription('vs/code/node/cliProcessMain', ['vs/code/node/cli']), createModuleDescription('vs/code/electron-sandbox/issue/issueReporterMain'), - createModuleDescription('vs/code/electron-browser/sharedProcess/sharedProcessMain'), + createModuleDescription('vs/code/node/sharedProcess/sharedProcessMain'), createModuleDescription('vs/code/electron-sandbox/processExplorer/processExplorerMain') ]; diff --git a/src/main.js b/src/main.js index 99f828167b5..8a83d12d94d 100644 --- a/src/main.js +++ b/src/main.js @@ -92,11 +92,28 @@ registerListeners(); */ let nlsConfigurationPromise = undefined; +/** + * @type {String} + **/ +let osLocale = 'en'; +// This if statement can be simplified once +// VS Code moves to Electron 22. +// Ref https://github.com/microsoft/vscode/issues/159813 +// and https://github.com/electron/electron/pull/36035 +if ('getPreferredSystemLanguages' in app + && typeof app.getPreferredSystemLanguages === 'function') { + // Use the most preferred OS language for language recommendation. + // The API might return an empty array on Linux, such as when + // the 'C' locale is the user's only configured locale. + // No matter the OS, if the array is empty, default back to 'en'. + const resolved = app.getPreferredSystemLanguages()?.[0] ?? 'en'; + osLocale = processZhLocale(resolved.toLowerCase()); +} const metaDataFile = path.join(__dirname, 'nls.metadata.json'); const locale = getUserDefinedLocale(argvConfig); if (locale) { const { getNLSConfiguration } = require('./vs/base/node/languagePacks'); - nlsConfigurationPromise = getNLSConfiguration(product.commit, userDataPath, metaDataFile, locale); + nlsConfigurationPromise = getNLSConfiguration(product.commit, userDataPath, metaDataFile, locale, osLocale); } // Pass in the locale to Electron so that the @@ -554,6 +571,10 @@ async function mkdirpIgnoreError(dir) { //#region NLS Support +/** + * @param {string} appLocale + * @returns string + */ function processZhLocale(appLocale) { if (appLocale.startsWith('zh')) { const region = appLocale.split('-')[1]; @@ -584,46 +605,28 @@ async function resolveNlsConfiguration() { // First, we need to test a user defined locale. If it fails we try the app locale. // If that fails we fall back to English. let nlsConfiguration = nlsConfigurationPromise ? await nlsConfigurationPromise : undefined; - if (!nlsConfiguration) { - - // Try to use the app locale. Please note that the app locale is only - // valid after we have received the app ready event. This is why the - // code is here. - - /** - * @type string - */ - let appLocale = app.getLocale(); - - // This if statement can be simplified once - // VS Code moves to Electron 22. - // Ref https://github.com/microsoft/vscode/issues/159813 - // and https://github.com/electron/electron/pull/36035 - if ((process.platform === 'win32' || process.platform === 'linux') - && 'getPreferredSystemLanguages' in app - && typeof app.getPreferredSystemLanguages === 'function' - && app.getPreferredSystemLanguages().length) { - // Use the most preferred OS language for language recommendation. - appLocale = app.getPreferredSystemLanguages()[0]; - } - - if (!appLocale) { - nlsConfiguration = { locale: 'en', availableLanguages: {} }; - } else { - // See above the comment about the loader and case sensitiveness - appLocale = processZhLocale(appLocale.toLowerCase()); - - const { getNLSConfiguration } = require('./vs/base/node/languagePacks'); - nlsConfiguration = await getNLSConfiguration(product.commit, userDataPath, metaDataFile, appLocale); - if (!nlsConfiguration) { - nlsConfiguration = { locale: appLocale, availableLanguages: {} }; - } - } - } else { - // We received a valid nlsConfig from a user defined locale + if (nlsConfiguration) { + return nlsConfiguration; } - return nlsConfiguration; + // Try to use the app locale. Please note that the app locale is only + // valid after we have received the app ready event. This is why the + // code is here. + + /** + * @type string + */ + let appLocale = app.getLocale(); + if (!appLocale) { + return { locale: 'en', osLocale, availableLanguages: {} }; + } + + // See above the comment about the loader and case sensitiveness + appLocale = processZhLocale(appLocale.toLowerCase()); + + const { getNLSConfiguration } = require('./vs/base/node/languagePacks'); + nlsConfiguration = await getNLSConfiguration(product.commit, userDataPath, metaDataFile, appLocale, osLocale); + return nlsConfiguration ?? { locale: 'en', osLocale, availableLanguages: {} }; } /** diff --git a/src/vs/base/browser/defaultWorkerFactory.ts b/src/vs/base/browser/defaultWorkerFactory.ts index f7c76d14b53..4fe7e01e806 100644 --- a/src/vs/base/browser/defaultWorkerFactory.ts +++ b/src/vs/base/browser/defaultWorkerFactory.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { COI } from 'vs/base/common/network'; -import { globals } from 'vs/base/common/platform'; import { IWorker, IWorkerCallback, IWorkerFactory, logOnceWebWorkerWarning } from 'vs/base/common/worker/simpleWorker'; const ttPolicy = window.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value }); @@ -18,12 +17,17 @@ export function createBlobWorker(blobUrl: string, options?: WorkerOptions): Work function getWorker(label: string): Worker | Promise { // Option for hosts to overwrite the worker script (used in the standalone editor) - if (globals.MonacoEnvironment) { - if (typeof globals.MonacoEnvironment.getWorker === 'function') { - return globals.MonacoEnvironment.getWorker('workerMain.js', label); + interface IMonacoEnvironment { + getWorker?(moduleId: string, label: string): Worker | Promise; + getWorkerUrl?(moduleId: string, label: string): string; + } + const monacoEnvironment: IMonacoEnvironment | undefined = (globalThis as any).MonacoEnvironment; + if (monacoEnvironment) { + if (typeof monacoEnvironment.getWorker === 'function') { + return monacoEnvironment.getWorker('workerMain.js', label); } - if (typeof globals.MonacoEnvironment.getWorkerUrl === 'function') { - const workerUrl = globals.MonacoEnvironment.getWorkerUrl('workerMain.js', label); + if (typeof monacoEnvironment.getWorkerUrl === 'function') { + const workerUrl = monacoEnvironment.getWorkerUrl('workerMain.js', label); return new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label }); } } @@ -40,12 +44,12 @@ function getWorker(label: string): Worker | Promise { // ESM-comment-begin export function getWorkerBootstrapUrl(scriptPath: string, label: string): string { - if (/^((http:)|(https:)|(file:))/.test(scriptPath) && scriptPath.substring(0, self.origin.length) !== self.origin) { + if (/^((http:)|(https:)|(file:))/.test(scriptPath) && scriptPath.substring(0, globalThis.origin.length) !== globalThis.origin) { // this is the cross-origin case // i.e. the webpage is running at a different origin than where the scripts are loaded from const myPath = 'vs/base/worker/defaultWorkerFactory.js'; const workerBaseUrl = require.toUrl(myPath).slice(0, -myPath.length); // explicitly using require.toUrl(), see https://github.com/microsoft/vscode/issues/107440#issuecomment-698982321 - const js = `/*${label}*/self.MonacoEnvironment={baseUrl: '${workerBaseUrl}'};const ttPolicy = self.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });importScripts(ttPolicy?.createScriptURL('${scriptPath}') ?? '${scriptPath}');/*${label}*/`; + const js = `/*${label}*/globalThis.MonacoEnvironment={baseUrl: '${workerBaseUrl}'};const ttPolicy = globalThis.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });importScripts(ttPolicy?.createScriptURL('${scriptPath}') ?? '${scriptPath}');/*${label}*/`; const blob = new Blob([js], { type: 'application/javascript' }); return URL.createObjectURL(blob); } diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 4522b439a9a..e31eedaaabd 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -691,10 +691,11 @@ export function getActiveElement(): Element | null { return result; } -export function createStyleSheet(container: HTMLElement = document.getElementsByTagName('head')[0]): HTMLStyleElement { +export function createStyleSheet(container: HTMLElement = document.getElementsByTagName('head')[0], beforeAppend?: (style: HTMLStyleElement) => void): HTMLStyleElement { const style = document.createElement('style'); style.type = 'text/css'; style.media = 'screen'; + beforeAppend?.(style); container.appendChild(style); return style; } @@ -1040,6 +1041,14 @@ export function join(nodes: Node[], separator: Node | string): Node[] { return result; } +export function setVisibility(visible: boolean, ...elements: HTMLElement[]): void { + if (visible) { + show(...elements); + } else { + hide(...elements); + } +} + export function show(...elements: HTMLElement[]): void { for (const element of elements) { element.style.display = ''; @@ -1461,7 +1470,7 @@ export const basicMarkupHtmlTags = Object.freeze([ const defaultDomPurifyConfig = Object.freeze({ ALLOWED_TAGS: ['a', 'button', 'blockquote', 'code', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'input', 'label', 'li', 'p', 'pre', 'select', 'small', 'span', 'strong', 'textarea', 'ul', 'ol'], - ALLOWED_ATTR: ['href', 'data-href', 'data-command', 'target', 'title', 'name', 'src', 'alt', 'class', 'id', 'role', 'tabindex', 'style', 'data-code', 'width', 'height', 'align', 'x-dispatch', 'required', 'checked', 'placeholder', 'type'], + ALLOWED_ATTR: ['href', 'data-href', 'data-command', 'target', 'title', 'name', 'src', 'alt', 'class', 'id', 'role', 'tabindex', 'style', 'data-code', 'width', 'height', 'align', 'x-dispatch', 'required', 'checked', 'placeholder', 'type', 'start'], RETURN_DOM: false, RETURN_DOM_FRAGMENT: false, RETURN_TRUSTED_TYPE: true diff --git a/src/vs/base/browser/keyboardEvent.ts b/src/vs/base/browser/keyboardEvent.ts index 75943736534..9dd0862c003 100644 --- a/src/vs/base/browser/keyboardEvent.ts +++ b/src/vs/base/browser/keyboardEvent.ts @@ -23,19 +23,18 @@ function extractKeyCode(e: KeyboardEvent): KeyCode { if (keyCode === 3) { return KeyCode.PauseBreak; } else if (browser.isFirefox) { - if (keyCode === 59) { - return KeyCode.Semicolon; - } else if (keyCode === 107) { - return KeyCode.Equal; - } else if (keyCode === 109) { - return KeyCode.Minus; - } else if (platform.isMacintosh && keyCode === 224) { - return KeyCode.Meta; + switch (keyCode) { + case 59: return KeyCode.Semicolon; + + // based on: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#numpad_keys + case 107: return KeyCode.NumpadAdd; + case 109: return KeyCode.NumpadSubtract; + + case 224: + if (platform.isMacintosh) { return KeyCode.Meta; } } } else if (browser.isWebKit) { - if (keyCode === 91) { - return KeyCode.Meta; - } else if (platform.isMacintosh && keyCode === 93) { + if (platform.isMacintosh && keyCode === 93) { // the two meta keys in the Mac have different key codes (91 and 93) return KeyCode.Meta; } else if (!platform.isMacintosh && keyCode === 92) { diff --git a/src/vs/base/browser/markdownRenderer.ts b/src/vs/base/browser/markdownRenderer.ts index 097ededbe15..5726fa20666 100644 --- a/src/vs/base/browser/markdownRenderer.ts +++ b/src/vs/base/browser/markdownRenderer.ts @@ -32,7 +32,9 @@ export interface MarkedOptions extends marked.MarkedOptions { export interface MarkdownRenderOptions extends FormattedTextRenderOptions { readonly codeBlockRenderer?: (languageId: string, value: string) => Promise; + readonly codeBlockRendererSync?: (languageId: string, value: string) => HTMLElement; readonly asyncRenderCallback?: () => void; + readonly fillInIncompleteTokens?: boolean; } const defaultMarkedRenderers = Object.freeze({ @@ -149,8 +151,16 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende // Will collect [id, renderedElement] tuples const codeBlocks: Promise<[string, HTMLElement]>[] = []; + const syncCodeBlocks: [string, HTMLElement][] = []; - if (options.codeBlockRenderer) { + if (options.codeBlockRendererSync) { + renderer.code = (code, lang) => { + const id = defaultGenerator.nextId(); + const value = options.codeBlockRendererSync!(postProcessCodeBlockLanguageId(lang), code); + syncCodeBlocks.push([id, value]); + return `
${escape(code)}
`; + }; + } else if (options.codeBlockRenderer) { renderer.code = (code, lang) => { const id = defaultGenerator.nextId(); const value = options.codeBlockRenderer!(postProcessCodeBlockLanguageId(lang), code); @@ -228,7 +238,19 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende value = markdownEscapeEscapedIcons(value); } - let renderedMarkdown = marked.parse(value, markedOptions); + let renderedMarkdown: string; + if (options.fillInIncompleteTokens) { + // The defaults are applied by parse but not lexer()/parser(), and they need to be present + const opts = { + ...marked.defaults, + ...markedOptions + }; + const tokens = marked.lexer(value, opts); + const newTokens = fillInIncompleteTokens(tokens); + renderedMarkdown = marked.parser(newTokens, opts); + } else { + renderedMarkdown = marked.parse(value, markedOptions); + } // Rewrite theme icons if (markdown.supportThemeIcons) { @@ -292,6 +314,15 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende } options.asyncRenderCallback?.(); }); + } else if (syncCodeBlocks.length > 0) { + const renderedElements = new Map(syncCodeBlocks); + const placeholderElements = element.querySelectorAll(`div[data-code]`); + for (const placeholderElement of placeholderElements) { + const renderedElement = renderedElements.get(placeholderElement.dataset['code'] ?? ''); + if (renderedElement) { + DOM.reset(placeholderElement, renderedElement); + } + } } // signal size changes for image tags @@ -347,7 +378,7 @@ function sanitizeRenderedMarkdown( if (e.attrName === 'style' || e.attrName === 'class') { if (element.tagName === 'SPAN') { if (e.attrName === 'style') { - e.keepAttr = /^(color\:#[0-9a-fA-F]+;)?(background-color\:#[0-9a-fA-F]+;)?$/.test(e.attrValue); + e.keepAttr = /^(color\:(#[0-9a-fA-F]+|var\(--vscode(-[a-zA-Z]+)+\));)?(background-color\:(#[0-9a-fA-F]+|var\(--vscode(-[a-zA-Z]+)+\));)?$/.test(e.attrValue); return; } else if (e.attrName === 'class') { e.keepAttr = /^codicon codicon-[a-z\-]+( codicon-modifier-[a-z\-]+)?$/.test(e.attrValue); @@ -388,6 +419,7 @@ export const allowedMarkdownAttr = [ 'target', 'title', 'width', + 'start', ]; function getSanitizerOptions(options: { readonly isTrusted?: boolean | MarkdownStringTrustedOptions }): { config: dompurify.Config; allowedSchemes: string[] } { @@ -517,3 +549,85 @@ const plainTextRenderer = new Lazy(() => { }; return renderer; }); + +function mergeRawTokenText(tokens: marked.Token[]): string { + let mergedTokenText = ''; + tokens.forEach(token => { + mergedTokenText += token.raw; + }); + return mergedTokenText; +} + +export function fillInIncompleteTokens(tokens: marked.TokensList): marked.TokensList { + let i: number; + let newTokens: marked.Token[] | undefined; + for (i = 0; i < tokens.length; i++) { + const token = tokens[i]; + if (token.type === 'paragraph' && token.raw.match(/(\n|^)```/)) { + // If the code block was complete, it would be in a type='code' + newTokens = completeCodeBlock(tokens.slice(i)); + break; + } + + if (token.type === 'paragraph' && token.raw.match(/(\n|^)\|/)) { + newTokens = completeTable(tokens.slice(i)); + break; + } + } + + if (newTokens) { + const newTokensList = [ + ...tokens.slice(0, i), + ...newTokens, + ]; + (newTokensList as marked.TokensList).links = tokens.links; + return newTokensList as marked.TokensList; + } + + return tokens; +} + +function completeCodeBlock(tokens: marked.Token[]): marked.Token[] { + const mergedRawText = mergeRawTokenText(tokens); + return marked.lexer(mergedRawText + '\n```'); +} + +function completeTable(tokens: marked.Token[]): marked.Token[] { + const mergedRawText = mergeRawTokenText(tokens); + const lines = mergedRawText.split('\n'); + + let numCols: number | undefined; // The number of line1 col headers + let hasSeparatorRow = false; + for (let i = 0; i < lines.length; i++) { + const line = lines[i].trim(); + if (typeof numCols === 'undefined' && line.match(/^\s*\|/)) { + const line1Matches = line.match(/(\|[^\|]+)(?=\||$)/g); + if (line1Matches) { + numCols = line1Matches.length; + } + } else if (typeof numCols === 'number') { + if (line.match(/^\s*\|/)) { + if (i !== lines.length - 1) { + // We got the line1 header row, and the line2 separator row, but there are more lines, and it wasn't parsed as a table! + // That's strange and means that the table is probably malformed in the source, so I won't try to patch it up. + return tokens; + } + + // Got a line2 separator row- partial or complete, doesn't matter, we'll replace it with a correct one + hasSeparatorRow = true; + } else { + // The line after the header row isn't a valid separator row, so the table is malformed, don't fix it up + return tokens; + } + } + } + + if (typeof numCols === 'number' && numCols > 0) { + const prefixText = hasSeparatorRow ? lines.slice(0, -1).join('\n') : mergedRawText; + const line1EndsInPipe = !!prefixText.match(/\|\s*$/); + const newRawText = prefixText + (line1EndsInPipe ? '' : '|') + `\n|${' --- |'.repeat(numCols)}`; + return marked.lexer(newRawText); + } + + return tokens; +} diff --git a/src/vs/base/browser/mouseEvent.ts b/src/vs/base/browser/mouseEvent.ts index e6f5d3b5a4b..db8ba364a86 100644 --- a/src/vs/base/browser/mouseEvent.ts +++ b/src/vs/base/browser/mouseEvent.ts @@ -74,7 +74,7 @@ export class StandardMouseEvent implements IMouseEvent { } // Find the position of the iframe this code is executing in relative to the iframe where the event was captured. - const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(self, e.view); + const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(window, e.view); this.posx -= iframeOffsets.left; this.posy -= iframeOffsets.top; } diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts index 26d7bf26d65..182724b9474 100644 --- a/src/vs/base/browser/ui/button/button.ts +++ b/src/vs/base/browser/ui/button/button.ts @@ -5,20 +5,23 @@ import { IContextMenuProvider } from 'vs/base/browser/contextmenu'; import { addDisposableListener, EventHelper, EventType, IFocusTracker, reset, trackFocus } from 'vs/base/browser/dom'; +import { sanitize } from 'vs/base/browser/dompurify/dompurify'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { EventType as TouchEventType, Gesture } from 'vs/base/browser/touch'; +import { renderMarkdown, renderStringAsPlaintext } from 'vs/base/browser/markdownRenderer'; +import { Gesture, EventType as TouchEventType } from 'vs/base/browser/touch'; import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; import { Action, IAction, IActionRunner } from 'vs/base/common/actions'; import { Codicon } from 'vs/base/common/codicons'; -import { ThemeIcon } from 'vs/base/common/themables'; import { Color } from 'vs/base/common/color'; -import { Emitter, Event as BaseEvent } from 'vs/base/common/event'; +import { Event as BaseEvent, Emitter } from 'vs/base/common/event'; +import { IMarkdownString, isMarkdownString, markdownStringEqual } from 'vs/base/common/htmlContent'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; -import { localize } from 'vs/nls'; +import { ThemeIcon } from 'vs/base/common/themables'; import 'vs/css!./button'; +import { localize } from 'vs/nls'; -export interface IButtonOptions extends IButtonStyles { +export interface IButtonOptions extends Partial { readonly title?: boolean | string; readonly supportIcons?: boolean; readonly supportShortLabel?: boolean; @@ -50,9 +53,11 @@ export const unthemedButtonStyles: IButtonStyles = { export interface IButton extends IDisposable { readonly element: HTMLElement; readonly onDidClick: BaseEvent; - label: string; - icon: ThemeIcon; - enabled: boolean; + + set label(value: string | IMarkdownString); + set icon(value: ThemeIcon); + set enabled(value: boolean); + focus(): void; hasFocus(): boolean; } @@ -65,6 +70,7 @@ export class Button extends Disposable implements IButton { protected options: IButtonOptions; protected _element: HTMLElement; + protected _label: string | IMarkdownString = ''; protected _labelElement: HTMLElement | undefined; protected _labelShortElement: HTMLElement | undefined; @@ -187,21 +193,50 @@ export class Button extends Disposable implements IButton { return this._element; } - set label(value: string) { + set label(value: string | IMarkdownString) { + if (this._label === value) { + return; + } + + if (isMarkdownString(this._label) && isMarkdownString(value) && markdownStringEqual(this._label, value)) { + return; + } + this._element.classList.add('monaco-text-button'); const labelElement = this.options.supportShortLabel ? this._labelElement! : this._element; - if (this.options.supportIcons) { - reset(labelElement, ...this.getContentElements(value)); + if (isMarkdownString(value)) { + const rendered = renderMarkdown(value, { inline: true }); + rendered.dispose(); + + // Don't include outer `

` + const root = rendered.element.querySelector('p')?.innerHTML; + if (root) { + // Only allow a very limited set of inline html tags + const sanitized = sanitize(root, { ADD_TAGS: ['b', 'i', 'u', 'code', 'span'], ALLOWED_ATTR: ['class'], RETURN_TRUSTED_TYPE: true }); + labelElement.innerHTML = sanitized as unknown as string; + } else { + reset(labelElement); + } } else { - labelElement.textContent = value; + if (this.options.supportIcons) { + reset(labelElement, ...this.getContentElements(value)); + } else { + labelElement.textContent = value; + } } if (typeof this.options.title === 'string') { this._element.title = this.options.title; } else if (this.options.title) { - this._element.title = value; + this._element.title = renderStringAsPlaintext(value); } + + this._label = value; + } + + get label(): string | IMarkdownString { + return this._label; } set labelShort(value: string) { @@ -272,7 +307,7 @@ export class ButtonWithDropdown extends Disposable implements IButton { this.button = this._register(new Button(this.element, options)); this._register(this.button.onDidClick(e => this._onDidClick.fire(e))); - this.action = this._register(new Action('primaryAction', this.button.label, undefined, true, async () => this._onDidClick.fire(undefined))); + this.action = this._register(new Action('primaryAction', renderStringAsPlaintext(this.button.label), undefined, true, async () => this._onDidClick.fire(undefined))); this.separatorContainer = document.createElement('div'); this.separatorContainer.classList.add('monaco-button-dropdown-separator'); diff --git a/src/vs/base/browser/ui/centered/centeredViewLayout.ts b/src/vs/base/browser/ui/centered/centeredViewLayout.ts index b7530c058c0..1fef73f19da 100644 --- a/src/vs/base/browser/ui/centered/centeredViewLayout.ts +++ b/src/vs/base/browser/ui/centered/centeredViewLayout.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { $ } from 'vs/base/browser/dom'; +import { $, IDomNodePagePosition } from 'vs/base/browser/dom'; import { IView, IViewSize } from 'vs/base/browser/ui/grid/grid'; import { IBoundarySashes } from 'vs/base/browser/ui/sash/sash'; import { DistributeSizing, ISplitViewStyles, IView as ISplitViewView, Orientation, SplitView } from 'vs/base/browser/ui/splitview/splitview'; @@ -61,8 +61,7 @@ export interface ICenteredViewStyles extends ISplitViewStyles { export class CenteredViewLayout implements IDisposable { private splitView?: SplitView<{ top: number; left: number }>; - private width: number = 0; - private height: number = 0; + private lastLayoutPosition: IDomNodePagePosition = { width: 0, height: 0, left: 0, top: 0 }; private style!: ICenteredViewStyles; private didLayout = false; private emptyViews: ISplitViewView<{ top: number; left: number }>[] | undefined; @@ -99,10 +98,9 @@ export class CenteredViewLayout implements IDisposable { } layout(width: number, height: number, top: number, left: number): void { - this.width = width; - this.height = height; + this.lastLayoutPosition = { width, height, top, left }; if (this.splitView) { - this.splitView.layout(width); + this.splitView.layout(width, this.lastLayoutPosition); if (!this.didLayout || this.centeredLayoutFixedWidth) { this.resizeSplitViews(); } @@ -118,16 +116,15 @@ export class CenteredViewLayout implements IDisposable { return; } if (this.centeredLayoutFixedWidth) { - - const centerViewWidth = Math.min(this.width, this.state.targetWidth); - const marginWidthFloat = (this.width - centerViewWidth) / 2; + const centerViewWidth = Math.min(this.lastLayoutPosition.width, this.state.targetWidth); + const marginWidthFloat = (this.lastLayoutPosition.width - centerViewWidth) / 2; this.splitView.resizeView(0, Math.floor(marginWidthFloat)); this.splitView.resizeView(1, centerViewWidth); this.splitView.resizeView(2, Math.ceil(marginWidthFloat)); } else { - const leftMargin = this.state.leftMarginRatio * this.width; - const rightMargin = this.state.rightMarginRatio * this.width; - const center = this.width - leftMargin - rightMargin; + const leftMargin = this.state.leftMarginRatio * this.lastLayoutPosition.width; + const rightMargin = this.state.rightMarginRatio * this.lastLayoutPosition.width; + const center = this.lastLayoutPosition.width - leftMargin - rightMargin; this.splitView.resizeView(0, leftMargin); this.splitView.resizeView(1, center); this.splitView.resizeView(2, rightMargin); @@ -145,8 +142,8 @@ export class CenteredViewLayout implements IDisposable { private updateState() { if (!!this.splitView) { this.state.targetWidth = this.splitView.getViewSize(1); - this.state.leftMarginRatio = this.splitView.getViewSize(0) / this.width; - this.state.rightMarginRatio = this.splitView.getViewSize(2) / this.width; + this.state.leftMarginRatio = this.splitView.getViewSize(0) / this.lastLayoutPosition.width; + this.state.rightMarginRatio = this.splitView.getViewSize(2) / this.lastLayoutPosition.width; } } @@ -188,12 +185,12 @@ export class CenteredViewLayout implements IDisposable { this.resizeSplitViews(); })); - this.splitView.layout(this.width); + this.splitView.layout(this.lastLayoutPosition.width, this.lastLayoutPosition); const backgroundColor = this.style ? this.style.background : undefined; this.emptyViews = [createEmptyView(backgroundColor), createEmptyView(backgroundColor)]; this.splitView.addView(this.emptyViews[0], distributeSizing, 0); - this.splitView.addView(toSplitViewView(this.view, () => this.height), distributeSizing, 1); + this.splitView.addView(toSplitViewView(this.view, () => this.lastLayoutPosition.height), distributeSizing, 1); this.splitView.addView(this.emptyViews[1], distributeSizing, 2); this.resizeSplitViews(); @@ -206,7 +203,7 @@ export class CenteredViewLayout implements IDisposable { this.splitView = undefined; this.emptyViews = undefined; this.container.appendChild(this.view.element); - this.view.layout(this.width, this.height, 0, 0); + this.view.layout(this.lastLayoutPosition.width, this.lastLayoutPosition.height, this.lastLayoutPosition.top, this.lastLayoutPosition.left); } } diff --git a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf index cc4c7aeaa79..ea2309d11d3 100644 Binary files a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf and b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf differ diff --git a/src/vs/base/browser/ui/dialog/dialog.ts b/src/vs/base/browser/ui/dialog/dialog.ts index 6392ec535e7..d7fc96598f1 100644 --- a/src/vs/base/browser/ui/dialog/dialog.ts +++ b/src/vs/base/browser/ui/dialog/dialog.ts @@ -375,6 +375,8 @@ export class Dialog extends Disposable { this.iconElement.classList.add(...ThemeIcon.asClassNameArray(Codicon.loading), spinModifierClassName); break; case 'none': + this.iconElement.classList.add('no-codicon'); + break; case 'info': case 'question': default: diff --git a/src/vs/base/browser/ui/findinput/findInput.ts b/src/vs/base/browser/ui/findinput/findInput.ts index 39fd66a7251..d663c086cff 100644 --- a/src/vs/base/browser/ui/findinput/findInput.ts +++ b/src/vs/base/browser/ui/findinput/findInput.ts @@ -191,7 +191,7 @@ export class FindInput extends Widget { this.controls = document.createElement('div'); this.controls.className = 'controls'; - this.controls.style.display = this.showCommonFindToggles ? 'block' : 'none'; + this.controls.style.display = this.showCommonFindToggles ? '' : 'none'; if (this.caseSensitive) { this.controls.append(this.caseSensitive.domNode); } @@ -232,6 +232,11 @@ export class FindInput extends Widget { return this.inputBox.onDidChange; } + public layout(style: { collapsedFindWidget: boolean; narrowFindWidget: boolean; reducedFindWidget: boolean }) { + this.inputBox.layout(); + this.updateInputBoxPadding(style.collapsedFindWidget); + } + public enable(): void { this.domNode.classList.remove('disabled'); this.inputBox.enable(); @@ -291,12 +296,20 @@ export class FindInput extends Widget { } if (this.additionalToggles.length > 0) { - this.controls.style.display = 'block'; + this.controls.style.display = ''; } - this.inputBox.paddingRight = - ((this.caseSensitive?.width() ?? 0) + (this.wholeWords?.width() ?? 0) + (this.regex?.width() ?? 0)) - + this.additionalToggles.reduce((r, t) => r + t.width(), 0); + this.updateInputBoxPadding(); + } + + private updateInputBoxPadding(controlsHidden = false) { + if (controlsHidden) { + this.inputBox.paddingRight = 0; + } else { + this.inputBox.paddingRight = + ((this.caseSensitive?.width() ?? 0) + (this.wholeWords?.width() ?? 0) + (this.regex?.width() ?? 0)) + + this.additionalToggles.reduce((r, t) => r + t.width(), 0); + } } public clear(): void { diff --git a/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts b/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts index ef5cf2ce7a3..c2b41545d79 100644 --- a/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts +++ b/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts @@ -13,13 +13,13 @@ import * as objects from 'vs/base/common/objects'; export interface IHighlight { start: number; end: number; - extraClasses?: string[]; + readonly extraClasses?: readonly string[]; } -export interface IOptions { +export interface IHighlightedLabelOptions { /** - * Whether + * Whether the label supports rendering icons. */ readonly supportIcons?: boolean; } @@ -42,7 +42,7 @@ export class HighlightedLabel { * * @param container The parent container to append to. */ - constructor(container: HTMLElement, options?: IOptions) { + constructor(container: HTMLElement, options?: IHighlightedLabelOptions) { this.supportIcons = options?.supportIcons ?? false; this.domNode = dom.append(container, dom.$('span.monaco-highlighted-label')); } diff --git a/src/vs/base/browser/ui/hover/hover.css b/src/vs/base/browser/ui/hover/hover.css index 5cd824a3d76..f3058d6c107 100644 --- a/src/vs/base/browser/ui/hover/hover.css +++ b/src/vs/base/browser/ui/hover/hover.css @@ -114,6 +114,11 @@ line-height: 22px; } +.monaco-hover .hover-row.status-bar .info { + font-style: italic; + padding: 0px 8px; +} + .monaco-hover .hover-row.status-bar .actions { display: flex; padding: 0px 8px; diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 54ab048af47..916c073d977 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -16,6 +16,7 @@ import { Widget } from 'vs/base/browser/ui/widget'; import { IAction } from 'vs/base/common/actions'; import { Emitter, Event } from 'vs/base/common/event'; import { HistoryNavigator } from 'vs/base/common/history'; +import { equals } from 'vs/base/common/objects'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import 'vs/css!./inputBox'; import * as nls from 'vs/nls'; @@ -368,6 +369,11 @@ export class InputBox extends Widget { } public showMessage(message: IMessage, force?: boolean): void { + if (this.state === 'open' && equals(this.message, message)) { + // Already showing + return; + } + this.message = message; this.element.classList.remove('idle'); diff --git a/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts b/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts index b809c1ce478..431e33048cd 100644 --- a/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts +++ b/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts @@ -93,13 +93,13 @@ export class KeybindingLabel { this.clear(); if (this.keybinding) { - const [firstChord, secondChord] = this.keybinding.getChords();// TODO@chords - if (firstChord) { - this.renderChord(this.domNode, firstChord, this.matches ? this.matches.firstPart : null); + const chords = this.keybinding.getChords(); + if (chords[0]) { + this.renderChord(this.domNode, chords[0], this.matches ? this.matches.firstPart : null); } - if (secondChord) { + for (let i = 1; i < chords.length; i++) { dom.append(this.domNode, $('span.monaco-keybinding-key-chord-separator', undefined, ' ')); - this.renderChord(this.domNode, secondChord, this.matches ? this.matches.chordPart : null); + this.renderChord(this.domNode, chords[i], this.matches ? this.matches.chordPart : null); } const title = (this.options.disableTitle ?? false) ? undefined : this.keybinding.getAriaLabel() || undefined; if (title !== undefined) { diff --git a/src/vs/base/browser/ui/list/list.ts b/src/vs/base/browser/ui/list/list.ts index 29ebb8c14bc..c53f26f182b 100644 --- a/src/vs/base/browser/ui/list/list.ts +++ b/src/vs/base/browser/ui/list/list.ts @@ -24,40 +24,40 @@ export interface IListRenderer { } export interface IListEvent { - elements: T[]; - indexes: number[]; - browserEvent?: UIEvent; + readonly elements: readonly T[]; + readonly indexes: readonly number[]; + readonly browserEvent?: UIEvent; } export interface IListMouseEvent { - browserEvent: MouseEvent; - element: T | undefined; - index: number | undefined; + readonly browserEvent: MouseEvent; + readonly element: T | undefined; + readonly index: number | undefined; } export interface IListTouchEvent { - browserEvent: TouchEvent; - element: T | undefined; - index: number | undefined; + readonly browserEvent: TouchEvent; + readonly element: T | undefined; + readonly index: number | undefined; } export interface IListGestureEvent { - browserEvent: GestureEvent; - element: T | undefined; - index: number | undefined; + readonly browserEvent: GestureEvent; + readonly element: T | undefined; + readonly index: number | undefined; } export interface IListDragEvent { - browserEvent: DragEvent; - element: T | undefined; - index: number | undefined; + readonly browserEvent: DragEvent; + readonly element: T | undefined; + readonly index: number | undefined; } export interface IListContextMenuEvent { - browserEvent: UIEvent; - element: T | undefined; - index: number | undefined; - anchor: HTMLElement | { x: number; y: number }; + readonly browserEvent: UIEvent; + readonly element: T | undefined; + readonly index: number | undefined; + readonly anchor: HTMLElement | { readonly x: number; readonly y: number }; } export interface IIdentityProvider { diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 697a5102b7c..619e5c11f0b 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -1034,7 +1034,8 @@ ${formatRule(Codicon.menuSubmenu)} flex-direction: row-reverse; } -.monaco-menu .monaco-action-bar .action-item { +:host-context(.monaco-workbench:not(.reduce-motion)) .monaco-menu .monaco-action-bar .action-item, +.monaco-workbench:not(.reduce-motion) .monaco-menu .monaco-action-bar .action-item { cursor: pointer; display: inline-block; transition: transform 50ms ease; @@ -1309,7 +1310,7 @@ ${formatRule(Codicon.menuSubmenu)} font-size: 11px !important; } - .monaco-scrollable-element > .visible { + :host-context(.monaco-workbench:not(.reduce-motion)) .monaco-scrollable-element > .visible { opacity: 1; /* Background rule added for IE9 - to allow clicks on dom node */ @@ -1321,7 +1322,7 @@ ${formatRule(Codicon.menuSubmenu)} opacity: 0; pointer-events: none; } - .monaco-scrollable-element > .invisible.fade { + :host-context(.monaco-workbench:not(.reduce-motion)) .monaco-scrollable-element > .invisible.fade { transition: opacity 800ms linear; } diff --git a/src/vs/base/browser/ui/sash/sash.css b/src/vs/base/browser/ui/sash/sash.css index 0026c3c3b1c..fdcbc26609e 100644 --- a/src/vs/base/browser/ui/sash/sash.css +++ b/src/vs/base/browser/ui/sash/sash.css @@ -107,10 +107,13 @@ position: absolute; width: 100%; height: 100%; - transition: background-color 0.1s ease-out; background: transparent; } +.monaco-workbench:not(.reduce-motion) .monaco-sash:before { + transition: background-color 0.1s ease-out; +} + .monaco-sash.hover:before, .monaco-sash.active:before { background: var(--vscode-sash-hoverBorder); diff --git a/src/vs/base/browser/ui/splitview/splitview.css b/src/vs/base/browser/ui/splitview/splitview.css index 6f6b302e5b3..3af3e9062d2 100644 --- a/src/vs/base/browser/ui/splitview/splitview.css +++ b/src/vs/base/browser/ui/splitview/splitview.css @@ -54,7 +54,7 @@ position: absolute; top: 0; left: 0; - z-index: 20; + z-index: 5; pointer-events: none; background-color: var(--separator-border); } diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 9b00db6e0f2..531d030f6eb 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -1383,12 +1383,14 @@ export class SplitView extends Disposable { } override dispose(): void { - super.dispose(); + this.sashDragState?.disposable.dispose(); dispose(this.viewItems); this.viewItems = []; this.sashItems.forEach(i => i.disposable.dispose()); this.sashItems = []; + + super.dispose(); } } diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index 7c2564c5056..e996ae8bc21 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -11,7 +11,7 @@ import { ComposedTreeDelegate, TreeFindMode as TreeFindMode, IAbstractTreeOption import { ICompressedTreeElement, ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel'; import { getVisibleState, isFilterResult } from 'vs/base/browser/ui/tree/indexTreeModel'; import { CompressibleObjectTree, ICompressibleKeyboardNavigationLabelProvider, ICompressibleObjectTreeOptions, ICompressibleTreeRenderer, IObjectTreeOptions, IObjectTreeSetChildrenOptions, ObjectTree } from 'vs/base/browser/ui/tree/objectTree'; -import { IAsyncDataSource, ICollapseStateChangeEvent, ITreeContextMenuEvent, ITreeDragAndDrop, ITreeElement, ITreeEvent, ITreeFilter, ITreeMouseEvent, ITreeNode, ITreeRenderer, ITreeSorter, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from 'vs/base/browser/ui/tree/tree'; +import { IAsyncDataSource, ICollapseStateChangeEvent, IObjectTreeElement, ITreeContextMenuEvent, ITreeDragAndDrop, ITreeEvent, ITreeFilter, ITreeMouseEvent, ITreeNode, ITreeRenderer, ITreeSorter, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from 'vs/base/browser/ui/tree/tree'; import { CancelablePromise, createCancelablePromise, Promises, timeout } from 'vs/base/common/async'; import { Codicon } from 'vs/base/common/codicons'; import { ThemeIcon } from 'vs/base/common/themables'; @@ -988,7 +988,7 @@ export class AsyncDataTree implements IDisposable this._onDidRender.fire(); } - protected asTreeElement(node: IAsyncDataTreeNode, viewStateContext?: IAsyncDataTreeViewStateContext): ITreeElement> { + protected asTreeElement(node: IAsyncDataTreeNode, viewStateContext?: IAsyncDataTreeViewStateContext): IObjectTreeElement> { if (node.stale) { return { element: node, diff --git a/src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts b/src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts index 8ea45f5e3e5..241c26daf23 100644 --- a/src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts +++ b/src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts @@ -6,12 +6,12 @@ import { IIdentityProvider } from 'vs/base/browser/ui/list/list'; import { IIndexTreeModelSpliceOptions, IList } from 'vs/base/browser/ui/tree/indexTreeModel'; import { IObjectTreeModel, IObjectTreeModelOptions, IObjectTreeModelSetChildrenOptions, ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel'; -import { ICollapseStateChangeEvent, ITreeElement, ITreeModel, ITreeModelSpliceEvent, ITreeNode, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from 'vs/base/browser/ui/tree/tree'; +import { ICollapseStateChangeEvent, IObjectTreeElement, ITreeModel, ITreeModelSpliceEvent, ITreeNode, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from 'vs/base/browser/ui/tree/tree'; import { Event } from 'vs/base/common/event'; import { Iterable } from 'vs/base/common/iterator'; // Exported only for test reasons, do not use directly -export interface ICompressedTreeElement extends ITreeElement { +export interface ICompressedTreeElement extends IObjectTreeElement { readonly children?: Iterable>; readonly incompressible?: boolean; } @@ -22,7 +22,7 @@ export interface ICompressedTreeNode { readonly incompressible: boolean; } -function noCompress(element: ICompressedTreeElement): ITreeElement> { +function noCompress(element: ICompressedTreeElement): ICompressedTreeElement> { const elements = [element.element]; const incompressible = element.incompressible || false; @@ -35,7 +35,7 @@ function noCompress(element: ICompressedTreeElement): ITreeElement(element: ICompressedTreeElement): ITreeElement> { +export function compress(element: ICompressedTreeElement): ICompressedTreeElement> { const elements = [element.element]; const incompressible = element.incompressible || false; @@ -65,7 +65,7 @@ export function compress(element: ICompressedTreeElement): ITreeElement(element: ITreeElement>, index = 0): ICompressedTreeElement { +function _decompress(element: ICompressedTreeElement>, index = 0): ICompressedTreeElement { let children: Iterable>; if (index < element.element.elements.length - 1) { @@ -93,7 +93,7 @@ function _decompress(element: ITreeElement>, index = 0 } // Exported only for test reasons, do not use directly -export function decompress(element: ITreeElement>): ICompressedTreeElement { +export function decompress(element: ICompressedTreeElement>): ICompressedTreeElement { return _decompress(element, 0); } @@ -205,7 +205,7 @@ export class CompressedObjectTreeModel, TFilterData e private _setChildren( node: ICompressedTreeNode | null, - children: Iterable>>, + children: Iterable>>, options: IIndexTreeModelSpliceOptions, TFilterData>, ): void { const insertedElements = new Set(); diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 9256e1e8077..a83a0a84e31 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -32,7 +32,7 @@ border-left: 1px solid transparent; } -.monaco-tl-indent > .indent-guide { +.monaco-workbench:not(.reduce-motion) .monaco-tl-indent > .indent-guide { transition: border-color 0.1s linear; } @@ -76,10 +76,16 @@ top: 0; display: flex; padding: 3px; - transition: top 0.3s; max-width: 200px; z-index: 100; margin: 0 6px; + border: 1px solid var(--vscode-widget-border); + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} + +.monaco-workbench:not(.reduce-motion) .monaco-tree-type-filter { + transition: top 0.3s; } .monaco-tree-type-filter.disabled { diff --git a/src/vs/base/browser/ui/tree/objectTree.ts b/src/vs/base/browser/ui/tree/objectTree.ts index 86aca57ac40..5880b0bb25d 100644 --- a/src/vs/base/browser/ui/tree/objectTree.ts +++ b/src/vs/base/browser/ui/tree/objectTree.ts @@ -8,7 +8,7 @@ import { AbstractTree, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from ' import { CompressibleObjectTreeModel, ElementMapper, ICompressedTreeElement, ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel'; import { IList } from 'vs/base/browser/ui/tree/indexTreeModel'; import { IObjectTreeModel, ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel'; -import { ICollapseStateChangeEvent, ITreeElement, ITreeModel, ITreeNode, ITreeRenderer, ITreeSorter } from 'vs/base/browser/ui/tree/tree'; +import { ICollapseStateChangeEvent, IObjectTreeElement, ITreeModel, ITreeNode, ITreeRenderer, ITreeSorter } from 'vs/base/browser/ui/tree/tree'; import { memoize } from 'vs/base/common/decorators'; import { Event } from 'vs/base/common/event'; import { Iterable } from 'vs/base/common/iterator'; @@ -52,7 +52,7 @@ export class ObjectTree, TFilterData = void> extends super(user, container, delegate, renderers, options as IObjectTreeOptions); } - setChildren(element: T | null, children: Iterable> = Iterable.empty(), options?: IObjectTreeSetChildrenOptions): void { + setChildren(element: T | null, children: Iterable> = Iterable.empty(), options?: IObjectTreeSetChildrenOptions): void { this.model.setChildren(element, children, options); } diff --git a/src/vs/base/browser/ui/tree/objectTreeModel.ts b/src/vs/base/browser/ui/tree/objectTreeModel.ts index fe44f7e91c7..919f14b2b3a 100644 --- a/src/vs/base/browser/ui/tree/objectTreeModel.ts +++ b/src/vs/base/browser/ui/tree/objectTreeModel.ts @@ -5,14 +5,14 @@ import { IIdentityProvider } from 'vs/base/browser/ui/list/list'; import { IIndexTreeModelOptions, IIndexTreeModelSpliceOptions, IList, IndexTreeModel } from 'vs/base/browser/ui/tree/indexTreeModel'; -import { ICollapseStateChangeEvent, ITreeElement, ITreeModel, ITreeModelSpliceEvent, ITreeNode, ITreeSorter, TreeError } from 'vs/base/browser/ui/tree/tree'; +import { ICollapseStateChangeEvent, IObjectTreeElement, ITreeElement, ITreeModel, ITreeModelSpliceEvent, ITreeNode, ITreeSorter, ObjectTreeElementCollapseState, TreeError } from 'vs/base/browser/ui/tree/tree'; import { Event } from 'vs/base/common/event'; import { Iterable } from 'vs/base/common/iterator'; export type ITreeNodeCallback = (node: ITreeNode) => void; export interface IObjectTreeModel, TFilterData extends NonNullable = void> extends ITreeModel { - setChildren(element: T | null, children: Iterable> | undefined, options?: IObjectTreeModelSetChildrenOptions): void; + setChildren(element: T | null, children: Iterable> | undefined, options?: IObjectTreeModelSetChildrenOptions): void; resort(element?: T | null, recursive?: boolean): void; updateElementHeight(element: T, height: number | undefined): void; } @@ -64,7 +64,7 @@ export class ObjectTreeModel, TFilterData extends Non setChildren( element: T | null, - children: Iterable> = Iterable.empty(), + children: Iterable> = Iterable.empty(), options: IObjectTreeModelSetChildrenOptions = {}, ): void { const location = this.getElementLocation(element); @@ -127,7 +127,7 @@ export class ObjectTreeModel, TFilterData extends Non ); } - private preserveCollapseState(elements: Iterable> = Iterable.empty()): Iterable> { + private preserveCollapseState(elements: Iterable> = Iterable.empty()): Iterable> { if (this.sorter) { elements = [...elements].sort(this.sorter.compare.bind(this.sorter)); } @@ -141,14 +141,37 @@ export class ObjectTreeModel, TFilterData extends Non } if (!node) { + let collapsed: boolean | undefined; + + if (typeof treeElement.collapsed === 'undefined') { + collapsed = undefined; + } else if (treeElement.collapsed === ObjectTreeElementCollapseState.Collapsed || treeElement.collapsed === ObjectTreeElementCollapseState.PreserveOrCollapsed) { + collapsed = true; + } else if (treeElement.collapsed === ObjectTreeElementCollapseState.Expanded || treeElement.collapsed === ObjectTreeElementCollapseState.PreserveOrExpanded) { + collapsed = false; + } else { + collapsed = Boolean(treeElement.collapsed); + } + return { ...treeElement, - children: this.preserveCollapseState(treeElement.children) + children: this.preserveCollapseState(treeElement.children), + collapsed }; } const collapsible = typeof treeElement.collapsible === 'boolean' ? treeElement.collapsible : node.collapsible; - const collapsed = typeof treeElement.collapsed !== 'undefined' ? treeElement.collapsed : node.collapsed; + let collapsed: boolean | undefined; + + if (typeof treeElement.collapsed === 'undefined' || treeElement.collapsed === ObjectTreeElementCollapseState.PreserveOrCollapsed || treeElement.collapsed === ObjectTreeElementCollapseState.PreserveOrExpanded) { + collapsed = node.collapsed; + } else if (treeElement.collapsed === ObjectTreeElementCollapseState.Collapsed) { + collapsed = true; + } else if (treeElement.collapsed === ObjectTreeElementCollapseState.Expanded) { + collapsed = false; + } else { + collapsed = Boolean(treeElement.collapsed); + } return { ...treeElement, diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index f29091c104a..94e8650f2de 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -78,6 +78,28 @@ export interface ITreeElement { readonly collapsed?: boolean; } +export enum ObjectTreeElementCollapseState { + Expanded, + Collapsed, + + /** + * If the element is already in the tree, preserve its current state. Else, expand it. + */ + PreserveOrExpanded, + + /** + * If the element is already in the tree, preserve its current state. Else, collapse it. + */ + PreserveOrCollapsed, +} + +export interface IObjectTreeElement { + readonly element: T; + readonly children?: Iterable>; + readonly collapsible?: boolean; + readonly collapsed?: boolean | ObjectTreeElementCollapseState; +} + export interface ITreeNode { readonly element: T; readonly children: ITreeNode[]; @@ -134,8 +156,8 @@ export interface ITreeRenderer exte } export interface ITreeEvent { - elements: T[]; - browserEvent?: UIEvent; + readonly elements: readonly T[]; + readonly browserEvent?: UIEvent; } export enum TreeMouseEventTarget { @@ -146,15 +168,15 @@ export enum TreeMouseEventTarget { } export interface ITreeMouseEvent { - browserEvent: MouseEvent; - element: T | null; - target: TreeMouseEventTarget; + readonly browserEvent: MouseEvent; + readonly element: T | null; + readonly target: TreeMouseEventTarget; } export interface ITreeContextMenuEvent { - browserEvent: UIEvent; - element: T | null; - anchor: HTMLElement | { x: number; y: number }; + readonly browserEvent: UIEvent; + readonly element: T | null; + readonly anchor: HTMLElement | { readonly x: number; readonly y: number }; } export interface ITreeNavigator { diff --git a/src/vs/base/common/actions.ts b/src/vs/base/common/actions.ts index b1d13e8210d..1780b30b4ff 100644 --- a/src/vs/base/common/actions.ts +++ b/src/vs/base/common/actions.ts @@ -16,6 +16,7 @@ export interface ITelemetryData { export type WorkbenchActionExecutedClassification = { id: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The identifier of the action that was run.' }; from: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The name of the component the action was run from.' }; + detail?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Optional details about how the action was run, e.g which keybinding was used.' }; owner: 'bpasero'; comment: 'Provides insight into actions that are executed within the workbench.'; }; @@ -23,6 +24,7 @@ export type WorkbenchActionExecutedClassification = { export type WorkbenchActionExecutedEvent = { id: string; from: string; + detail?: string; }; export interface IAction { @@ -32,7 +34,7 @@ export interface IAction { class: string | undefined; enabled: boolean; checked?: boolean; - run(event?: unknown): unknown; + run(...args: unknown[]): unknown; } export interface IActionRunner extends IDisposable { diff --git a/src/vs/base/common/charCode.ts b/src/vs/base/common/charCode.ts index 9799712d031..de0a25badec 100644 --- a/src/vs/base/common/charCode.ts +++ b/src/vs/base/common/charCode.ts @@ -225,6 +225,12 @@ export const enum CharCode { */ Tilde = 126, + /** + * The   (no-break space) character. + * Unicode Character 'NO-BREAK SPACE' (U+00A0) + */ + NoBreakSpace = 160, + U_Combining_Grave_Accent = 0x0300, // U+0300 Combining Grave Accent U_Combining_Acute_Accent = 0x0301, // U+0301 Combining Acute Accent U_Combining_Circumflex_Accent = 0x0302, // U+0302 Combining Circumflex Accent diff --git a/src/vs/base/common/codicons.ts b/src/vs/base/common/codicons.ts index 1580521e4b2..f205af33b4c 100644 --- a/src/vs/base/common/codicons.ts +++ b/src/vs/base/common/codicons.ts @@ -560,6 +560,9 @@ export const Codicon = { gitPullRequestNewChanges: register('git-pull-request-new-changes', 0xec0c), searchFuzzy: register('search-fuzzy', 0xec0d), commentDraft: register('comment-draft', 0xec0e), + send: register('send', 0xec0f), + sparkle: register('sparkle', 0xec10), + insert: register('insert', 0xec11), // derived icons, that could become separate icons diff --git a/src/vs/base/common/date.ts b/src/vs/base/common/date.ts index 033d3287373..0865e813249 100644 --- a/src/vs/base/common/date.ts +++ b/src/vs/base/common/date.ts @@ -13,7 +13,7 @@ const month = day * 30; const year = day * 365; /** - * Create a localized of the time between now and the specified date. + * Create a localized difference of the time between now and the specified date. * @param date The date to generate the difference from. * @param appendAgoLabel Whether to append the " ago" to the end. * @param useFullTimeWords Whether to use full words (eg. seconds) instead of diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index f9623407a02..172eeedf22a 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -119,18 +119,31 @@ export namespace Event { } /** + * Wraps an event in another event that performs some function on the event object before firing. + * * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the * returned event causes this utility to leak a listener on the original event. + * + * @param event The event source for the new event. + * @param each The function to perform on the event object. + * @param disposable A disposable store to add the new EventEmitter to. */ export function forEach(event: Event, each: (i: I) => void, disposable?: DisposableStore): Event { return snapshot((listener, thisArgs = null, disposables?) => event(i => { each(i); listener.call(thisArgs, i); }, null, disposables), disposable); } /** + * Wraps an event in another event that fires only when some condition is met. + * * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the * returned event causes this utility to leak a listener on the original event. + * + * @param event The event source for the new event. + * @param filter The filter function that defines the condition. The event will fire for the object if this function + * returns true. + * @param disposable A disposable store to add the new EventEmitter to. */ export function filter(event: Event, filter: (e: T | U) => e is T, disposable?: DisposableStore): Event; export function filter(event: Event, filter: (e: T) => boolean, disposable?: DisposableStore): Event; @@ -147,8 +160,7 @@ export namespace Event { } /** - * Given a collection of events, returns a single event which emits - * whenever any of the provided events emit. + * Given a collection of events, returns a single event which emits whenever any of the provided events emit. */ export function any(...events: Event[]): Event; export function any(...events: Event[]): Event; @@ -293,9 +305,22 @@ export namespace Event { } /** + * Filters an event such that some condition is _not_ met more than once in a row, effectively ensuring duplicate + * event objects from different sources do not fire the same event object. + * * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the * returned event causes this utility to leak a listener on the original event. + * + * @param event The event source for the new event. + * @param equals The equality condition. + * @param disposable A disposable store to add the new EventEmitter to. + * + * @example + * ``` + * // Fire only one time when a single window is opened or focused + * Event.latch(Event.any(onDidOpenWindow, onDidFocusWindow)) + * ``` */ export function latch(event: Event, equals: (a: T, b: T) => boolean = (a, b) => a === b, disposable?: DisposableStore): Event { let firstCall = true; @@ -334,9 +359,24 @@ export namespace Event { } /** + * Buffers an event until it has a listener attached. + * * *NOTE* that this function returns an `Event` and it MUST be called with a `DisposableStore` whenever the returned * event is accessible to "third parties", e.g the event is a public property. Otherwise a leaked listener on the * returned event causes this utility to leak a listener on the original event. + * + * @param event The event source for the new event. + * @param flushAfterTimeout Determines whether to flush the buffer after a timeout immediately or after a + * `setTimeout` when the first event listener is added. + * @param _buffer Internal: A source event array used for tests. + * + * @example + * ``` + * // Start accumulating events, when the first listener is attached, flush + * // the event after a timeout such that multiple listeners attached before + * // the timeout would receive the event + * this.onInstallExtension = Event.buffer(service.onInstallExtension, true); + * ``` */ export function buffer(event: Event, flushAfterTimeout = false, _buffer: T[] = []): Event { let buffer: T[] | null = _buffer.slice(); @@ -403,38 +443,48 @@ export namespace Event { constructor(readonly event: Event) { } + /** @see {@link Event.map} */ map(fn: (i: T) => O): IChainableEvent { return new ChainableEvent(map(this.event, fn, this.disposables)); } + /** @see {@link Event.forEach} */ forEach(fn: (i: T) => void): IChainableEvent { return new ChainableEvent(forEach(this.event, fn, this.disposables)); } + /** @see {@link Event.filter} */ filter(fn: (e: T) => boolean): IChainableEvent; filter(fn: (e: T | R) => e is R): IChainableEvent; filter(fn: (e: T) => boolean): IChainableEvent { return new ChainableEvent(filter(this.event, fn, this.disposables)); } + /** @see {@link Event.reduce} */ reduce(merge: (last: R | undefined, event: T) => R, initial?: R): IChainableEvent { return new ChainableEvent(reduce(this.event, merge, initial, this.disposables)); } + /** @see {@link Event.reduce} */ latch(): IChainableEvent { return new ChainableEvent(latch(this.event, undefined, this.disposables)); } + /** @see {@link Event.debounce} */ debounce(merge: (last: T | undefined, event: T) => T, delay?: number, leading?: boolean, flushOnListenerRemove?: boolean, leakWarningThreshold?: number): IChainableEvent; debounce(merge: (last: R | undefined, event: T) => R, delay?: number, leading?: boolean, flushOnListenerRemove?: boolean, leakWarningThreshold?: number): IChainableEvent; debounce(merge: (last: R | undefined, event: T) => R, delay: number = 100, leading = false, flushOnListenerRemove = false, leakWarningThreshold?: number): IChainableEvent { return new ChainableEvent(debounce(this.event, merge, delay, leading, flushOnListenerRemove, leakWarningThreshold, this.disposables)); } + /** + * Attach a listener to the event. + */ on(listener: (e: T) => any, thisArgs: any, disposables: IDisposable[] | DisposableStore) { return this.event(listener, thisArgs, disposables); } + /** @see {@link Event.once} */ once(listener: (e: T) => any, thisArgs: any, disposables: IDisposable[]) { return once(this.event)(listener, thisArgs, disposables); } @@ -444,6 +494,24 @@ export namespace Event { } } + /** + * Wraps the event in an {@link IChainableEvent}, allowing a more functional programming style. + * + * @example + * ``` + * // Normal + * const onEnterPressNormal = Event.filter( + * Event.map(onKeyPress.event, e => new StandardKeyboardEvent(e)), + * e.keyCode === KeyCode.Enter + * ).event; + * + * // Using chain + * const onEnterPressChain = Event.chain(onKeyPress.event) + * .map(e => new StandardKeyboardEvent(e)) + * .filter(e => e.keyCode === KeyCode.Enter) + * .event; + * ``` + */ export function chain(event: Event): IChainableEvent { return new ChainableEvent(event); } @@ -453,6 +521,9 @@ export namespace Event { removeListener(event: string | symbol, listener: Function): unknown; } + /** + * Creates an {@link Event} from a node event emitter. + */ export function fromNodeEventEmitter(emitter: NodeEventEmitter, eventName: string, map: (...args: any[]) => T = id => id): Event { const fn = (...args: any[]) => result.fire(map(...args)); const onFirstListenerAdd = () => emitter.on(eventName, fn); @@ -467,6 +538,9 @@ export namespace Event { removeEventListener(event: string | symbol, listener: Function): void; } + /** + * Creates an {@link Event} from a DOM event emitter. + */ export function fromDOMEventEmitter(emitter: DOMEventEmitter, eventName: string, map: (...args: any[]) => T = id => id): Event { const fn = (...args: any[]) => result.fire(map(...args)); const onFirstListenerAdd = () => emitter.addEventListener(eventName, fn); @@ -476,15 +550,31 @@ export namespace Event { return result.event; } + /** + * Creates a promise out of an event, using the {@link Event.once} helper. + */ export function toPromise(event: Event): Promise { return new Promise(resolve => once(event)(resolve)); } + /** + * Adds a listener to an event and calls the listener immediately with undefined as the event object. + * + * @example + * ``` + * // Initialize the UI and update it when dataChangeEvent fires + * runAndSubscribe(dataChangeEvent, () => this._updateUI()); + * ``` + */ export function runAndSubscribe(event: Event, handler: (e: T | undefined) => any): IDisposable { handler(undefined); return event(e => handler(e)); } + /** + * Adds a listener to an event and calls the listener immediately with undefined as the event object. A new + * {@link DisposableStore} is passed to the listener which is disposed when the returned disposable is disposed. + */ export function runAndSubscribeWithStore(event: Event, handler: (e: T | undefined, disposableStore: DisposableStore) => any): IDisposable { let store: DisposableStore | null = null; @@ -573,6 +663,11 @@ export interface EmitterOptions { * Optional function that's called *before* a listener is removed */ onWillRemoveListener?: Function; + /** + * Optional function that's called when a listener throws an error. Defaults to + * {@link onUnexpectedError} + */ + onListenerError?: (e: any) => void; /** * Number of listeners that are allowed before assuming a leak. Default to * a globally configured value @@ -874,7 +969,7 @@ export class Emitter { // the driver of this if (!this._deliveryQueue) { - this._deliveryQueue = new PrivateEventDeliveryQueue(); + this._deliveryQueue = new PrivateEventDeliveryQueue(this._options?.onListenerError); } for (const listener of this._listeners) { @@ -899,8 +994,13 @@ export class Emitter { } export class EventDeliveryQueue { + protected _queue = new LinkedList(); + constructor( + private readonly _onListenerError: (e: any) => void = onUnexpectedError + ) { } + get size(): number { return this._queue.size; } @@ -925,7 +1025,7 @@ export class EventDeliveryQueue { try { element.listener.invoke(element.event); } catch (e) { - onUnexpectedError(e); + this._onListenerError(e); } } } diff --git a/src/vs/base/common/extpath.ts b/src/vs/base/common/extpath.ts index a0fe8ad76a8..e4f64431608 100644 --- a/src/vs/base/common/extpath.ts +++ b/src/vs/base/common/extpath.ts @@ -382,11 +382,26 @@ export function parseLineAndColumnAware(rawPath: string): IPathWithLineAndColumn } const pathChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; +const windowsSafePathFirstChars = 'BDEFGHIJKMOQRSTUVWXYZbdefghijkmoqrstuvwxyz0123456789'; export function randomPath(parent?: string, prefix?: string, randomLength = 8): string { let suffix = ''; for (let i = 0; i < randomLength; i++) { - suffix += pathChars.charAt(Math.floor(Math.random() * pathChars.length)); + let pathCharsTouse: string; + if (i === 0 && isWindows && !prefix && (randomLength === 3 || randomLength === 4)) { + + // Windows has certain reserved file names that cannot be used, such + // as AUX, CON, PRN, etc. We want to avoid generating a random name + // that matches that pattern, so we use a different set of characters + // for the first character of the name that does not include any of + // the reserved names first characters. + + pathCharsTouse = windowsSafePathFirstChars; + } else { + pathCharsTouse = pathChars; + } + + suffix += pathCharsTouse.charAt(Math.floor(Math.random() * pathCharsTouse.length)); } let randomFileName: string; diff --git a/src/vs/base/common/keyCodes.ts b/src/vs/base/common/keyCodes.ts index 44488dbb299..4f204f40435 100644 --- a/src/vs/base/common/keyCodes.ts +++ b/src/vs/base/common/keyCodes.ts @@ -648,7 +648,7 @@ for (let i = 0; i <= KeyCode.MAX_VALUE; i++) { [5, 1, ScanCode.None, empty, KeyCode.Ctrl, 'Ctrl', 17, 'VK_CONTROL', empty, empty], [4, 1, ScanCode.None, empty, KeyCode.Shift, 'Shift', 16, 'VK_SHIFT', empty, empty], [6, 1, ScanCode.None, empty, KeyCode.Alt, 'Alt', 18, 'VK_MENU', empty, empty], - [57, 1, ScanCode.None, empty, KeyCode.Meta, 'Meta', 0, 'VK_COMMAND', empty, empty], + [57, 1, ScanCode.None, empty, KeyCode.Meta, 'Meta', 91, 'VK_COMMAND', empty, empty], [5, 1, ScanCode.ControlLeft, 'ControlLeft', KeyCode.Ctrl, empty, 0, 'VK_LCONTROL', empty, empty], [4, 1, ScanCode.ShiftLeft, 'ShiftLeft', KeyCode.Shift, empty, 0, 'VK_LSHIFT', empty, empty], [6, 1, ScanCode.AltLeft, 'AltLeft', KeyCode.Alt, empty, 0, 'VK_LMENU', empty, empty], diff --git a/src/vs/base/common/keybindings.ts b/src/vs/base/common/keybindings.ts index f3523709f9f..375256237a6 100644 --- a/src/vs/base/common/keybindings.ts +++ b/src/vs/base/common/keybindings.ts @@ -28,19 +28,27 @@ const enum BinaryKeybindingsMask { KeyCode = 0x000000FF } -export function decodeKeybinding(keybinding: number, OS: OperatingSystem): Keybinding | null { - if (keybinding === 0) { - return null; +export function decodeKeybinding(keybinding: number | number[], OS: OperatingSystem): Keybinding | null { + if (typeof keybinding === 'number') { + if (keybinding === 0) { + return null; + } + const firstChord = (keybinding & 0x0000FFFF) >>> 0; + const secondChord = (keybinding & 0xFFFF0000) >>> 16; + if (secondChord !== 0) { + return new Keybinding([ + createSimpleKeybinding(firstChord, OS), + createSimpleKeybinding(secondChord, OS) + ]); + } + return new Keybinding([createSimpleKeybinding(firstChord, OS)]); + } else { + const chords = []; + for (let i = 0; i < keybinding.length; i++) { + chords.push(createSimpleKeybinding(keybinding[i], OS)); + } + return new Keybinding(chords); } - const firstChord = (keybinding & 0x0000FFFF) >>> 0; - const secondChord = (keybinding & 0xFFFF0000) >>> 16; - if (secondChord !== 0) { - return new Keybinding([ - createSimpleKeybinding(firstChord, OS), - createSimpleKeybinding(secondChord, OS) - ]); - } - return new Keybinding([createSimpleKeybinding(firstChord, OS)]); } export function createSimpleKeybinding(keybinding: number, OS: OperatingSystem): KeyCodeChord { diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index e8b505142b0..e8dc62329e3 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -632,3 +632,35 @@ export class LRUCache extends LinkedMap { } } } + +export class CounterSet { + + private map = new Map(); + + add(value: T): CounterSet { + this.map.set(value, (this.map.get(value) || 0) + 1); + return this; + } + + delete(value: T): boolean { + let counter = this.map.get(value) || 0; + + if (counter === 0) { + return false; + } + + counter--; + + if (counter === 0) { + this.map.delete(value); + } else { + this.map.set(value, counter); + } + + return true; + } + + has(value: T): boolean { + return this.map.has(value); + } +} diff --git a/src/vs/base/common/marked/marked.js b/src/vs/base/common/marked/marked.js index f8ffa170fbb..eb8cde82ab4 100644 --- a/src/vs/base/common/marked/marked.js +++ b/src/vs/base/common/marked/marked.js @@ -19,8 +19,8 @@ // ESM-uncomment-end (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.marked = {})); })(this, (function (exports) { 'use strict'; diff --git a/src/vs/base/common/observableImpl/utils.ts b/src/vs/base/common/observableImpl/utils.ts index b021df0fc11..de5e6c73f14 100644 --- a/src/vs/base/common/observableImpl/utils.ts +++ b/src/vs/base/common/observableImpl/utils.ts @@ -276,8 +276,12 @@ export function wasEventTriggeredRecently(event: Event, timeoutMs: number, } /** - * This ensures the observable is kept up-to-date. - * This is useful when the observables `get` method is used. + * This ensures the observable cache is kept up-to-date, even if there are no subscribers. + * This is useful when the observables `get` method is used, but not its `read` method. + * + * (Usually, when no one is actually observing the observable, getting its value will + * compute it from scratch, as the cache cannot be trusted: + * Because no one is actually observing its value, keeping the cache up-to-date would be too expensive) */ export function keepAlive(observable: IObservable): IDisposable { const o = new KeepAliveObserver(); diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index d267b8a39a3..c752f32550f 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -18,11 +18,13 @@ let _isCI = false; let _isMobile = false; let _locale: string | undefined = undefined; let _language: string = LANGUAGE_DEFAULT; +let _platformLocale: string = LANGUAGE_DEFAULT; let _translationsConfigFile: string | undefined = undefined; let _userAgent: string | undefined = undefined; interface NLSConfig { locale: string; + osLocale: string; availableLanguages: { [key: string]: string }; _translationsConfigFile: string; } @@ -44,6 +46,7 @@ export interface INodeProcess { env: IProcessEnvironment; versions?: { electron?: string; + chrome?: string; }; type?: string; cwd: () => string; @@ -73,6 +76,7 @@ const isElectronRenderer = isElectronProcess && nodeProcess?.type === 'renderer' interface INavigator { userAgent: string; maxTouchPoints?: number; + language: string; } declare const navigator: INavigator; @@ -95,8 +99,8 @@ if (typeof navigator === 'object' && !isElectronRenderer) { ); _locale = configuredLocale || LANGUAGE_DEFAULT; - _language = _locale; + _platformLocale = navigator.language; } // Native environment @@ -115,6 +119,7 @@ else if (typeof nodeProcess === 'object') { const nlsConfig: NLSConfig = JSON.parse(rawNlsConfig); const resolved = nlsConfig.availableLanguages['*']; _locale = nlsConfig.locale; + _platformLocale = nlsConfig.osLocale; // VSCode's default language is 'en' _language = resolved ? resolved : LANGUAGE_DEFAULT; _translationsConfigFile = nlsConfig._translationsConfigFile; @@ -135,7 +140,9 @@ export const enum Platform { Linux, Windows } -export function PlatformToString(platform: Platform) { +export type PlatformName = 'Web' | 'Windows' | 'Mac' | 'Linux'; + +export function PlatformToString(platform: Platform): PlatformName { switch (platform) { case Platform.Web: return 'Web'; case Platform.Mac: return 'Mac'; @@ -206,6 +213,14 @@ export namespace Language { */ export const locale = _locale; +/** + * This will always be set to the OS/browser's locale regardless of + * what was specified by --locale. The format of the string is all + * lower case (e.g. zh-tw for Traditional Chinese). The UI is not + * necessarily shown in the provided locale. + */ +export const platformLocale = _platformLocale; + /** * The translations that are available through language packs. */ diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index e6be203b984..b8114824ee5 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IStringDictionary } from 'vs/base/common/collections'; +import { PlatformName } from 'vs/base/common/platform'; export interface IBuiltInExtension { readonly name: string; @@ -12,6 +13,29 @@ export interface IBuiltInExtension { readonly metadata: any; } +export interface IProductWalkthrough { + id: string; + steps: IProductWalkthroughStep[]; +} + +export interface IProductWalkthroughStep { + id: string; + title: string; + when: string; + description: string; + media: + | { type: 'image'; path: string | { hc: string; hcLight?: string; light: string; dark: string }; altText: string } + | { type: 'svg'; path: string; altText: string } + | { type: 'markdown'; path: string }; +} + +export interface IFeaturedExtension { + readonly id: string; + readonly title: string; + readonly description: string; + readonly imagePath: string; +} + export type ConfigurationSyncStore = { url: string; insidersUrl: string; @@ -49,6 +73,8 @@ export interface IProductConfiguration { readonly dataFolderName: string; // location for extensions (e.g. ~/.vscode-insiders) readonly builtInExtensions?: IBuiltInExtension[]; + readonly walkthroughMetadata?: IProductWalkthrough[]; + readonly featuredExtensions?: IFeaturedExtension[]; readonly downloadUrl?: string; readonly updateUrl?: string; @@ -80,17 +106,16 @@ export interface IProductConfiguration { readonly nlsBaseUrl: string; }; - readonly extensionTips?: { [id: string]: string }; - readonly extensionImportantTips?: IStringDictionary; - readonly configBasedExtensionTips?: { [id: string]: IConfigBasedExtensionTip }; - readonly exeBasedExtensionTips?: { [id: string]: IExeBasedExtensionTip }; - readonly remoteExtensionTips?: { [remoteName: string]: IRemoteExtensionTip }; - readonly virtualWorkspaceExtensionTips?: { [virtualWorkspaceName: string]: IVirtualWorkspaceExtensionTip }; - readonly extensionKeywords?: { [extension: string]: readonly string[] }; + readonly extensionRecommendations?: IStringDictionary; + readonly configBasedExtensionTips?: IStringDictionary; + readonly exeBasedExtensionTips?: IStringDictionary; + readonly remoteExtensionTips?: IStringDictionary; + readonly virtualWorkspaceExtensionTips?: IStringDictionary; + readonly extensionKeywords?: IStringDictionary; readonly keymapExtensionTips?: readonly string[]; readonly webExtensionTips?: readonly string[]; readonly languageExtensionTips?: readonly string[]; - readonly trustedExtensionUrlPublicKeys?: { [id: string]: string[] }; + readonly trustedExtensionUrlPublicKeys?: IStringDictionary; readonly trustedExtensionAuthAccess?: readonly string[]; readonly commandPaletteSuggestedCommandIds?: string[]; @@ -172,7 +197,27 @@ export interface ITunnelApplicationConfig { extension: IRemoteExtensionTip; } -export type ImportantExtensionTip = { name: string; languages?: string[]; pattern?: string; isExtensionPack?: boolean; whenNotInstalled?: string[] }; +export interface IExtensionRecommendations { + readonly onFileOpen: IFileOpenCondition[]; +} + +export interface IExtensionRecommendationCondition { + readonly important?: boolean; + readonly whenInstalled?: string[]; + readonly whenNotInstalled?: string[]; +} + +export type IFileOpenCondition = IFileLanguageCondition | IFilePathCondition | IFileContentCondition; + +export interface IFileLanguageCondition extends IExtensionRecommendationCondition { + readonly languages: string[]; +} + +export interface IFilePathCondition extends IExtensionRecommendationCondition { + readonly pathGlob: string; +} + +export type IFileContentCondition = (IFileLanguageCondition | IFilePathCondition) & { readonly contentPattern: string }; export interface IAppCenterConfiguration { readonly 'win32-ia32': string; @@ -185,7 +230,13 @@ export interface IConfigBasedExtensionTip { configPath: string; configName: string; configScheme?: string; - recommendations: IStringDictionary<{ name: string; remotes?: string[]; important?: boolean; isExtensionPack?: boolean; whenNotInstalled?: string[] }>; + recommendations: IStringDictionary<{ + name: string; + contentPattern?: string; + important?: boolean; + isExtensionPack?: boolean; + whenNotInstalled?: string[]; + }>; } export interface IExeBasedExtensionTip { @@ -198,11 +249,15 @@ export interface IExeBasedExtensionTip { export interface IRemoteExtensionTip { friendlyName: string; extensionId: string; + supportedPlatforms?: PlatformName[]; + showInStartEntry?: boolean; } export interface IVirtualWorkspaceExtensionTip { friendlyName: string; extensionId: string; + supportedPlatforms?: PlatformName[]; + showInStartEntry?: boolean; } export interface ISurveyData { diff --git a/src/vs/base/common/strings.ts b/src/vs/base/common/strings.ts index 99304974d17..6e1d31bd91d 100644 --- a/src/vs/base/common/strings.ts +++ b/src/vs/base/common/strings.ts @@ -1086,7 +1086,7 @@ export class AmbiguousCharacters { // Generated using https://github.com/hediet/vscode-unicode-data // Stored as key1, value1, key2, value2, ... return JSON.parse( - '{\"_common\":[8232,32,8233,32,5760,32,8192,32,8193,32,8194,32,8195,32,8196,32,8197,32,8198,32,8200,32,8201,32,8202,32,8287,32,8199,32,8239,32,2042,95,65101,95,65102,95,65103,95,8208,45,8209,45,8210,45,65112,45,1748,45,8259,45,727,45,8722,45,10134,45,11450,45,1549,44,1643,44,8218,44,184,44,42233,44,894,59,2307,58,2691,58,1417,58,1795,58,1796,58,5868,58,65072,58,6147,58,6153,58,8282,58,1475,58,760,58,42889,58,8758,58,720,58,42237,58,451,33,11601,33,660,63,577,63,2429,63,5038,63,42731,63,119149,46,8228,46,1793,46,1794,46,42510,46,68176,46,1632,46,1776,46,42232,46,1373,96,65287,96,8219,96,8242,96,1370,96,1523,96,8175,96,65344,96,900,96,8189,96,8125,96,8127,96,8190,96,697,96,884,96,712,96,714,96,715,96,756,96,699,96,701,96,700,96,702,96,42892,96,1497,96,2036,96,2037,96,5194,96,5836,96,94033,96,94034,96,65339,91,10088,40,10098,40,12308,40,64830,40,65341,93,10089,41,10099,41,12309,41,64831,41,10100,123,119060,123,10101,125,65342,94,8270,42,1645,42,8727,42,66335,42,5941,47,8257,47,8725,47,8260,47,9585,47,10187,47,10744,47,119354,47,12755,47,12339,47,11462,47,20031,47,12035,47,65340,92,65128,92,8726,92,10189,92,10741,92,10745,92,119311,92,119355,92,12756,92,20022,92,12034,92,42872,38,708,94,710,94,5869,43,10133,43,66203,43,8249,60,10094,60,706,60,119350,60,5176,60,5810,60,5120,61,11840,61,12448,61,42239,61,8250,62,10095,62,707,62,119351,62,5171,62,94015,62,8275,126,732,126,8128,126,8764,126,65372,124,65293,45,120784,50,120794,50,120804,50,120814,50,120824,50,130034,50,42842,50,423,50,1000,50,42564,50,5311,50,42735,50,119302,51,120785,51,120795,51,120805,51,120815,51,120825,51,130035,51,42923,51,540,51,439,51,42858,51,11468,51,1248,51,94011,51,71882,51,120786,52,120796,52,120806,52,120816,52,120826,52,130036,52,5070,52,71855,52,120787,53,120797,53,120807,53,120817,53,120827,53,130037,53,444,53,71867,53,120788,54,120798,54,120808,54,120818,54,120828,54,130038,54,11474,54,5102,54,71893,54,119314,55,120789,55,120799,55,120809,55,120819,55,120829,55,130039,55,66770,55,71878,55,2819,56,2538,56,2666,56,125131,56,120790,56,120800,56,120810,56,120820,56,120830,56,130040,56,547,56,546,56,66330,56,2663,57,2920,57,2541,57,3437,57,120791,57,120801,57,120811,57,120821,57,120831,57,130041,57,42862,57,11466,57,71884,57,71852,57,71894,57,9082,97,65345,97,119834,97,119886,97,119938,97,119990,97,120042,97,120094,97,120146,97,120198,97,120250,97,120302,97,120354,97,120406,97,120458,97,593,97,945,97,120514,97,120572,97,120630,97,120688,97,120746,97,65313,65,119808,65,119860,65,119912,65,119964,65,120016,65,120068,65,120120,65,120172,65,120224,65,120276,65,120328,65,120380,65,120432,65,913,65,120488,65,120546,65,120604,65,120662,65,120720,65,5034,65,5573,65,42222,65,94016,65,66208,65,119835,98,119887,98,119939,98,119991,98,120043,98,120095,98,120147,98,120199,98,120251,98,120303,98,120355,98,120407,98,120459,98,388,98,5071,98,5234,98,5551,98,65314,66,8492,66,119809,66,119861,66,119913,66,120017,66,120069,66,120121,66,120173,66,120225,66,120277,66,120329,66,120381,66,120433,66,42932,66,914,66,120489,66,120547,66,120605,66,120663,66,120721,66,5108,66,5623,66,42192,66,66178,66,66209,66,66305,66,65347,99,8573,99,119836,99,119888,99,119940,99,119992,99,120044,99,120096,99,120148,99,120200,99,120252,99,120304,99,120356,99,120408,99,120460,99,7428,99,1010,99,11429,99,43951,99,66621,99,128844,67,71922,67,71913,67,65315,67,8557,67,8450,67,8493,67,119810,67,119862,67,119914,67,119966,67,120018,67,120174,67,120226,67,120278,67,120330,67,120382,67,120434,67,1017,67,11428,67,5087,67,42202,67,66210,67,66306,67,66581,67,66844,67,8574,100,8518,100,119837,100,119889,100,119941,100,119993,100,120045,100,120097,100,120149,100,120201,100,120253,100,120305,100,120357,100,120409,100,120461,100,1281,100,5095,100,5231,100,42194,100,8558,68,8517,68,119811,68,119863,68,119915,68,119967,68,120019,68,120071,68,120123,68,120175,68,120227,68,120279,68,120331,68,120383,68,120435,68,5024,68,5598,68,5610,68,42195,68,8494,101,65349,101,8495,101,8519,101,119838,101,119890,101,119942,101,120046,101,120098,101,120150,101,120202,101,120254,101,120306,101,120358,101,120410,101,120462,101,43826,101,1213,101,8959,69,65317,69,8496,69,119812,69,119864,69,119916,69,120020,69,120072,69,120124,69,120176,69,120228,69,120280,69,120332,69,120384,69,120436,69,917,69,120492,69,120550,69,120608,69,120666,69,120724,69,11577,69,5036,69,42224,69,71846,69,71854,69,66182,69,119839,102,119891,102,119943,102,119995,102,120047,102,120099,102,120151,102,120203,102,120255,102,120307,102,120359,102,120411,102,120463,102,43829,102,42905,102,383,102,7837,102,1412,102,119315,70,8497,70,119813,70,119865,70,119917,70,120021,70,120073,70,120125,70,120177,70,120229,70,120281,70,120333,70,120385,70,120437,70,42904,70,988,70,120778,70,5556,70,42205,70,71874,70,71842,70,66183,70,66213,70,66853,70,65351,103,8458,103,119840,103,119892,103,119944,103,120048,103,120100,103,120152,103,120204,103,120256,103,120308,103,120360,103,120412,103,120464,103,609,103,7555,103,397,103,1409,103,119814,71,119866,71,119918,71,119970,71,120022,71,120074,71,120126,71,120178,71,120230,71,120282,71,120334,71,120386,71,120438,71,1292,71,5056,71,5107,71,42198,71,65352,104,8462,104,119841,104,119945,104,119997,104,120049,104,120101,104,120153,104,120205,104,120257,104,120309,104,120361,104,120413,104,120465,104,1211,104,1392,104,5058,104,65320,72,8459,72,8460,72,8461,72,119815,72,119867,72,119919,72,120023,72,120179,72,120231,72,120283,72,120335,72,120387,72,120439,72,919,72,120494,72,120552,72,120610,72,120668,72,120726,72,11406,72,5051,72,5500,72,42215,72,66255,72,731,105,9075,105,65353,105,8560,105,8505,105,8520,105,119842,105,119894,105,119946,105,119998,105,120050,105,120102,105,120154,105,120206,105,120258,105,120310,105,120362,105,120414,105,120466,105,120484,105,618,105,617,105,953,105,8126,105,890,105,120522,105,120580,105,120638,105,120696,105,120754,105,1110,105,42567,105,1231,105,43893,105,5029,105,71875,105,65354,106,8521,106,119843,106,119895,106,119947,106,119999,106,120051,106,120103,106,120155,106,120207,106,120259,106,120311,106,120363,106,120415,106,120467,106,1011,106,1112,106,65322,74,119817,74,119869,74,119921,74,119973,74,120025,74,120077,74,120129,74,120181,74,120233,74,120285,74,120337,74,120389,74,120441,74,42930,74,895,74,1032,74,5035,74,5261,74,42201,74,119844,107,119896,107,119948,107,120000,107,120052,107,120104,107,120156,107,120208,107,120260,107,120312,107,120364,107,120416,107,120468,107,8490,75,65323,75,119818,75,119870,75,119922,75,119974,75,120026,75,120078,75,120130,75,120182,75,120234,75,120286,75,120338,75,120390,75,120442,75,922,75,120497,75,120555,75,120613,75,120671,75,120729,75,11412,75,5094,75,5845,75,42199,75,66840,75,1472,108,8739,73,9213,73,65512,73,1633,108,1777,73,66336,108,125127,108,120783,73,120793,73,120803,73,120813,73,120823,73,130033,73,65321,73,8544,73,8464,73,8465,73,119816,73,119868,73,119920,73,120024,73,120128,73,120180,73,120232,73,120284,73,120336,73,120388,73,120440,73,65356,108,8572,73,8467,108,119845,108,119897,108,119949,108,120001,108,120053,108,120105,73,120157,73,120209,73,120261,73,120313,73,120365,73,120417,73,120469,73,448,73,120496,73,120554,73,120612,73,120670,73,120728,73,11410,73,1030,73,1216,73,1493,108,1503,108,1575,108,126464,108,126592,108,65166,108,65165,108,1994,108,11599,73,5825,73,42226,73,93992,73,66186,124,66313,124,119338,76,8556,76,8466,76,119819,76,119871,76,119923,76,120027,76,120079,76,120131,76,120183,76,120235,76,120287,76,120339,76,120391,76,120443,76,11472,76,5086,76,5290,76,42209,76,93974,76,71843,76,71858,76,66587,76,66854,76,65325,77,8559,77,8499,77,119820,77,119872,77,119924,77,120028,77,120080,77,120132,77,120184,77,120236,77,120288,77,120340,77,120392,77,120444,77,924,77,120499,77,120557,77,120615,77,120673,77,120731,77,1018,77,11416,77,5047,77,5616,77,5846,77,42207,77,66224,77,66321,77,119847,110,119899,110,119951,110,120003,110,120055,110,120107,110,120159,110,120211,110,120263,110,120315,110,120367,110,120419,110,120471,110,1400,110,1404,110,65326,78,8469,78,119821,78,119873,78,119925,78,119977,78,120029,78,120081,78,120185,78,120237,78,120289,78,120341,78,120393,78,120445,78,925,78,120500,78,120558,78,120616,78,120674,78,120732,78,11418,78,42208,78,66835,78,3074,111,3202,111,3330,111,3458,111,2406,111,2662,111,2790,111,3046,111,3174,111,3302,111,3430,111,3664,111,3792,111,4160,111,1637,111,1781,111,65359,111,8500,111,119848,111,119900,111,119952,111,120056,111,120108,111,120160,111,120212,111,120264,111,120316,111,120368,111,120420,111,120472,111,7439,111,7441,111,43837,111,959,111,120528,111,120586,111,120644,111,120702,111,120760,111,963,111,120532,111,120590,111,120648,111,120706,111,120764,111,11423,111,4351,111,1413,111,1505,111,1607,111,126500,111,126564,111,126596,111,65259,111,65260,111,65258,111,65257,111,1726,111,64428,111,64429,111,64427,111,64426,111,1729,111,64424,111,64425,111,64423,111,64422,111,1749,111,3360,111,4125,111,66794,111,71880,111,71895,111,66604,111,1984,79,2534,79,2918,79,12295,79,70864,79,71904,79,120782,79,120792,79,120802,79,120812,79,120822,79,130032,79,65327,79,119822,79,119874,79,119926,79,119978,79,120030,79,120082,79,120134,79,120186,79,120238,79,120290,79,120342,79,120394,79,120446,79,927,79,120502,79,120560,79,120618,79,120676,79,120734,79,11422,79,1365,79,11604,79,4816,79,2848,79,66754,79,42227,79,71861,79,66194,79,66219,79,66564,79,66838,79,9076,112,65360,112,119849,112,119901,112,119953,112,120005,112,120057,112,120109,112,120161,112,120213,112,120265,112,120317,112,120369,112,120421,112,120473,112,961,112,120530,112,120544,112,120588,112,120602,112,120646,112,120660,112,120704,112,120718,112,120762,112,120776,112,11427,112,65328,80,8473,80,119823,80,119875,80,119927,80,119979,80,120031,80,120083,80,120187,80,120239,80,120291,80,120343,80,120395,80,120447,80,929,80,120504,80,120562,80,120620,80,120678,80,120736,80,11426,80,5090,80,5229,80,42193,80,66197,80,119850,113,119902,113,119954,113,120006,113,120058,113,120110,113,120162,113,120214,113,120266,113,120318,113,120370,113,120422,113,120474,113,1307,113,1379,113,1382,113,8474,81,119824,81,119876,81,119928,81,119980,81,120032,81,120084,81,120188,81,120240,81,120292,81,120344,81,120396,81,120448,81,11605,81,119851,114,119903,114,119955,114,120007,114,120059,114,120111,114,120163,114,120215,114,120267,114,120319,114,120371,114,120423,114,120475,114,43847,114,43848,114,7462,114,11397,114,43905,114,119318,82,8475,82,8476,82,8477,82,119825,82,119877,82,119929,82,120033,82,120189,82,120241,82,120293,82,120345,82,120397,82,120449,82,422,82,5025,82,5074,82,66740,82,5511,82,42211,82,94005,82,65363,115,119852,115,119904,115,119956,115,120008,115,120060,115,120112,115,120164,115,120216,115,120268,115,120320,115,120372,115,120424,115,120476,115,42801,115,445,115,1109,115,43946,115,71873,115,66632,115,65331,83,119826,83,119878,83,119930,83,119982,83,120034,83,120086,83,120138,83,120190,83,120242,83,120294,83,120346,83,120398,83,120450,83,1029,83,1359,83,5077,83,5082,83,42210,83,94010,83,66198,83,66592,83,119853,116,119905,116,119957,116,120009,116,120061,116,120113,116,120165,116,120217,116,120269,116,120321,116,120373,116,120425,116,120477,116,8868,84,10201,84,128872,84,65332,84,119827,84,119879,84,119931,84,119983,84,120035,84,120087,84,120139,84,120191,84,120243,84,120295,84,120347,84,120399,84,120451,84,932,84,120507,84,120565,84,120623,84,120681,84,120739,84,11430,84,5026,84,42196,84,93962,84,71868,84,66199,84,66225,84,66325,84,119854,117,119906,117,119958,117,120010,117,120062,117,120114,117,120166,117,120218,117,120270,117,120322,117,120374,117,120426,117,120478,117,42911,117,7452,117,43854,117,43858,117,651,117,965,117,120534,117,120592,117,120650,117,120708,117,120766,117,1405,117,66806,117,71896,117,8746,85,8899,85,119828,85,119880,85,119932,85,119984,85,120036,85,120088,85,120140,85,120192,85,120244,85,120296,85,120348,85,120400,85,120452,85,1357,85,4608,85,66766,85,5196,85,42228,85,94018,85,71864,85,8744,118,8897,118,65366,118,8564,118,119855,118,119907,118,119959,118,120011,118,120063,118,120115,118,120167,118,120219,118,120271,118,120323,118,120375,118,120427,118,120479,118,7456,118,957,118,120526,118,120584,118,120642,118,120700,118,120758,118,1141,118,1496,118,71430,118,43945,118,71872,118,119309,86,1639,86,1783,86,8548,86,119829,86,119881,86,119933,86,119985,86,120037,86,120089,86,120141,86,120193,86,120245,86,120297,86,120349,86,120401,86,120453,86,1140,86,11576,86,5081,86,5167,86,42719,86,42214,86,93960,86,71840,86,66845,86,623,119,119856,119,119908,119,119960,119,120012,119,120064,119,120116,119,120168,119,120220,119,120272,119,120324,119,120376,119,120428,119,120480,119,7457,119,1121,119,1309,119,1377,119,71434,119,71438,119,71439,119,43907,119,71919,87,71910,87,119830,87,119882,87,119934,87,119986,87,120038,87,120090,87,120142,87,120194,87,120246,87,120298,87,120350,87,120402,87,120454,87,1308,87,5043,87,5076,87,42218,87,5742,120,10539,120,10540,120,10799,120,65368,120,8569,120,119857,120,119909,120,119961,120,120013,120,120065,120,120117,120,120169,120,120221,120,120273,120,120325,120,120377,120,120429,120,120481,120,5441,120,5501,120,5741,88,9587,88,66338,88,71916,88,65336,88,8553,88,119831,88,119883,88,119935,88,119987,88,120039,88,120091,88,120143,88,120195,88,120247,88,120299,88,120351,88,120403,88,120455,88,42931,88,935,88,120510,88,120568,88,120626,88,120684,88,120742,88,11436,88,11613,88,5815,88,42219,88,66192,88,66228,88,66327,88,66855,88,611,121,7564,121,65369,121,119858,121,119910,121,119962,121,120014,121,120066,121,120118,121,120170,121,120222,121,120274,121,120326,121,120378,121,120430,121,120482,121,655,121,7935,121,43866,121,947,121,8509,121,120516,121,120574,121,120632,121,120690,121,120748,121,1199,121,4327,121,71900,121,65337,89,119832,89,119884,89,119936,89,119988,89,120040,89,120092,89,120144,89,120196,89,120248,89,120300,89,120352,89,120404,89,120456,89,933,89,978,89,120508,89,120566,89,120624,89,120682,89,120740,89,11432,89,1198,89,5033,89,5053,89,42220,89,94019,89,71844,89,66226,89,119859,122,119911,122,119963,122,120015,122,120067,122,120119,122,120171,122,120223,122,120275,122,120327,122,120379,122,120431,122,120483,122,7458,122,43923,122,71876,122,66293,90,71909,90,65338,90,8484,90,8488,90,119833,90,119885,90,119937,90,119989,90,120041,90,120197,90,120249,90,120301,90,120353,90,120405,90,120457,90,918,90,120493,90,120551,90,120609,90,120667,90,120725,90,5059,90,42204,90,71849,90,65282,34,65284,36,65285,37,65286,38,65290,42,65291,43,65294,46,65295,47,65296,48,65297,49,65298,50,65299,51,65300,52,65301,53,65302,54,65303,55,65304,56,65305,57,65308,60,65309,61,65310,62,65312,64,65316,68,65318,70,65319,71,65324,76,65329,81,65330,82,65333,85,65334,86,65335,87,65343,95,65346,98,65348,100,65350,102,65355,107,65357,109,65358,110,65361,113,65362,114,65364,116,65365,117,65367,119,65370,122,65371,123,65373,125],\"_default\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"cs\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"de\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"es\":[8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"fr\":[65374,126,65306,58,65281,33,8216,96,8245,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"it\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"ja\":[8211,45,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65292,44,65307,59],\"ko\":[8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"pl\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"pt-BR\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"qps-ploc\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"ru\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,305,105,921,73,1009,112,215,120,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"tr\":[160,32,8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"zh-hans\":[65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65288,40,65289,41],\"zh-hant\":[8211,45,65374,126,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65307,59]}' + '{\"_common\":[8232,32,8233,32,5760,32,8192,32,8193,32,8194,32,8195,32,8196,32,8197,32,8198,32,8200,32,8201,32,8202,32,8287,32,8199,32,8239,32,2042,95,65101,95,65102,95,65103,95,8208,45,8209,45,8210,45,65112,45,1748,45,8259,45,727,45,8722,45,10134,45,11450,45,1549,44,1643,44,8218,44,184,44,42233,44,894,59,2307,58,2691,58,1417,58,1795,58,1796,58,5868,58,65072,58,6147,58,6153,58,8282,58,1475,58,760,58,42889,58,8758,58,720,58,42237,58,451,33,11601,33,660,63,577,63,2429,63,5038,63,42731,63,119149,46,8228,46,1793,46,1794,46,42510,46,68176,46,1632,46,1776,46,42232,46,1373,96,65287,96,8219,96,8242,96,1370,96,1523,96,8175,96,65344,96,900,96,8189,96,8125,96,8127,96,8190,96,697,96,884,96,712,96,714,96,715,96,756,96,699,96,701,96,700,96,702,96,42892,96,1497,96,2036,96,2037,96,5194,96,5836,96,94033,96,94034,96,65339,91,10088,40,10098,40,12308,40,64830,40,65341,93,10089,41,10099,41,12309,41,64831,41,10100,123,119060,123,10101,125,65342,94,8270,42,1645,42,8727,42,66335,42,5941,47,8257,47,8725,47,8260,47,9585,47,10187,47,10744,47,119354,47,12755,47,12339,47,11462,47,20031,47,12035,47,65340,92,65128,92,8726,92,10189,92,10741,92,10745,92,119311,92,119355,92,12756,92,20022,92,12034,92,42872,38,708,94,710,94,5869,43,10133,43,66203,43,8249,60,10094,60,706,60,119350,60,5176,60,5810,60,5120,61,11840,61,12448,61,42239,61,8250,62,10095,62,707,62,119351,62,5171,62,94015,62,8275,126,732,126,8128,126,8764,126,65372,124,65293,45,120784,50,120794,50,120804,50,120814,50,120824,50,130034,50,42842,50,423,50,1000,50,42564,50,5311,50,42735,50,119302,51,120785,51,120795,51,120805,51,120815,51,120825,51,130035,51,42923,51,540,51,439,51,42858,51,11468,51,1248,51,94011,51,71882,51,120786,52,120796,52,120806,52,120816,52,120826,52,130036,52,5070,52,71855,52,120787,53,120797,53,120807,53,120817,53,120827,53,130037,53,444,53,71867,53,120788,54,120798,54,120808,54,120818,54,120828,54,130038,54,11474,54,5102,54,71893,54,119314,55,120789,55,120799,55,120809,55,120819,55,120829,55,130039,55,66770,55,71878,55,2819,56,2538,56,2666,56,125131,56,120790,56,120800,56,120810,56,120820,56,120830,56,130040,56,547,56,546,56,66330,56,2663,57,2920,57,2541,57,3437,57,120791,57,120801,57,120811,57,120821,57,120831,57,130041,57,42862,57,11466,57,71884,57,71852,57,71894,57,9082,97,65345,97,119834,97,119886,97,119938,97,119990,97,120042,97,120094,97,120146,97,120198,97,120250,97,120302,97,120354,97,120406,97,120458,97,593,97,945,97,120514,97,120572,97,120630,97,120688,97,120746,97,65313,65,119808,65,119860,65,119912,65,119964,65,120016,65,120068,65,120120,65,120172,65,120224,65,120276,65,120328,65,120380,65,120432,65,913,65,120488,65,120546,65,120604,65,120662,65,120720,65,5034,65,5573,65,42222,65,94016,65,66208,65,119835,98,119887,98,119939,98,119991,98,120043,98,120095,98,120147,98,120199,98,120251,98,120303,98,120355,98,120407,98,120459,98,388,98,5071,98,5234,98,5551,98,65314,66,8492,66,119809,66,119861,66,119913,66,120017,66,120069,66,120121,66,120173,66,120225,66,120277,66,120329,66,120381,66,120433,66,42932,66,914,66,120489,66,120547,66,120605,66,120663,66,120721,66,5108,66,5623,66,42192,66,66178,66,66209,66,66305,66,65347,99,8573,99,119836,99,119888,99,119940,99,119992,99,120044,99,120096,99,120148,99,120200,99,120252,99,120304,99,120356,99,120408,99,120460,99,7428,99,1010,99,11429,99,43951,99,66621,99,128844,67,71922,67,71913,67,65315,67,8557,67,8450,67,8493,67,119810,67,119862,67,119914,67,119966,67,120018,67,120174,67,120226,67,120278,67,120330,67,120382,67,120434,67,1017,67,11428,67,5087,67,42202,67,66210,67,66306,67,66581,67,66844,67,8574,100,8518,100,119837,100,119889,100,119941,100,119993,100,120045,100,120097,100,120149,100,120201,100,120253,100,120305,100,120357,100,120409,100,120461,100,1281,100,5095,100,5231,100,42194,100,8558,68,8517,68,119811,68,119863,68,119915,68,119967,68,120019,68,120071,68,120123,68,120175,68,120227,68,120279,68,120331,68,120383,68,120435,68,5024,68,5598,68,5610,68,42195,68,8494,101,65349,101,8495,101,8519,101,119838,101,119890,101,119942,101,120046,101,120098,101,120150,101,120202,101,120254,101,120306,101,120358,101,120410,101,120462,101,43826,101,1213,101,8959,69,65317,69,8496,69,119812,69,119864,69,119916,69,120020,69,120072,69,120124,69,120176,69,120228,69,120280,69,120332,69,120384,69,120436,69,917,69,120492,69,120550,69,120608,69,120666,69,120724,69,11577,69,5036,69,42224,69,71846,69,71854,69,66182,69,119839,102,119891,102,119943,102,119995,102,120047,102,120099,102,120151,102,120203,102,120255,102,120307,102,120359,102,120411,102,120463,102,43829,102,42905,102,383,102,7837,102,1412,102,119315,70,8497,70,119813,70,119865,70,119917,70,120021,70,120073,70,120125,70,120177,70,120229,70,120281,70,120333,70,120385,70,120437,70,42904,70,988,70,120778,70,5556,70,42205,70,71874,70,71842,70,66183,70,66213,70,66853,70,65351,103,8458,103,119840,103,119892,103,119944,103,120048,103,120100,103,120152,103,120204,103,120256,103,120308,103,120360,103,120412,103,120464,103,609,103,7555,103,397,103,1409,103,119814,71,119866,71,119918,71,119970,71,120022,71,120074,71,120126,71,120178,71,120230,71,120282,71,120334,71,120386,71,120438,71,1292,71,5056,71,5107,71,42198,71,65352,104,8462,104,119841,104,119945,104,119997,104,120049,104,120101,104,120153,104,120205,104,120257,104,120309,104,120361,104,120413,104,120465,104,1211,104,1392,104,5058,104,65320,72,8459,72,8460,72,8461,72,119815,72,119867,72,119919,72,120023,72,120179,72,120231,72,120283,72,120335,72,120387,72,120439,72,919,72,120494,72,120552,72,120610,72,120668,72,120726,72,11406,72,5051,72,5500,72,42215,72,66255,72,731,105,9075,105,65353,105,8560,105,8505,105,8520,105,119842,105,119894,105,119946,105,119998,105,120050,105,120102,105,120154,105,120206,105,120258,105,120310,105,120362,105,120414,105,120466,105,120484,105,618,105,617,105,953,105,8126,105,890,105,120522,105,120580,105,120638,105,120696,105,120754,105,1110,105,42567,105,1231,105,43893,105,5029,105,71875,105,65354,106,8521,106,119843,106,119895,106,119947,106,119999,106,120051,106,120103,106,120155,106,120207,106,120259,106,120311,106,120363,106,120415,106,120467,106,1011,106,1112,106,65322,74,119817,74,119869,74,119921,74,119973,74,120025,74,120077,74,120129,74,120181,74,120233,74,120285,74,120337,74,120389,74,120441,74,42930,74,895,74,1032,74,5035,74,5261,74,42201,74,119844,107,119896,107,119948,107,120000,107,120052,107,120104,107,120156,107,120208,107,120260,107,120312,107,120364,107,120416,107,120468,107,8490,75,65323,75,119818,75,119870,75,119922,75,119974,75,120026,75,120078,75,120130,75,120182,75,120234,75,120286,75,120338,75,120390,75,120442,75,922,75,120497,75,120555,75,120613,75,120671,75,120729,75,11412,75,5094,75,5845,75,42199,75,66840,75,1472,108,8739,73,9213,73,65512,73,1633,108,1777,73,66336,108,125127,108,120783,73,120793,73,120803,73,120813,73,120823,73,130033,73,65321,73,8544,73,8464,73,8465,73,119816,73,119868,73,119920,73,120024,73,120128,73,120180,73,120232,73,120284,73,120336,73,120388,73,120440,73,65356,108,8572,73,8467,108,119845,108,119897,108,119949,108,120001,108,120053,108,120105,73,120157,73,120209,73,120261,73,120313,73,120365,73,120417,73,120469,73,448,73,120496,73,120554,73,120612,73,120670,73,120728,73,11410,73,1030,73,1216,73,1493,108,1503,108,1575,108,126464,108,126592,108,65166,108,65165,108,1994,108,11599,73,5825,73,42226,73,93992,73,66186,124,66313,124,119338,76,8556,76,8466,76,119819,76,119871,76,119923,76,120027,76,120079,76,120131,76,120183,76,120235,76,120287,76,120339,76,120391,76,120443,76,11472,76,5086,76,5290,76,42209,76,93974,76,71843,76,71858,76,66587,76,66854,76,65325,77,8559,77,8499,77,119820,77,119872,77,119924,77,120028,77,120080,77,120132,77,120184,77,120236,77,120288,77,120340,77,120392,77,120444,77,924,77,120499,77,120557,77,120615,77,120673,77,120731,77,1018,77,11416,77,5047,77,5616,77,5846,77,42207,77,66224,77,66321,77,119847,110,119899,110,119951,110,120003,110,120055,110,120107,110,120159,110,120211,110,120263,110,120315,110,120367,110,120419,110,120471,110,1400,110,1404,110,65326,78,8469,78,119821,78,119873,78,119925,78,119977,78,120029,78,120081,78,120185,78,120237,78,120289,78,120341,78,120393,78,120445,78,925,78,120500,78,120558,78,120616,78,120674,78,120732,78,11418,78,42208,78,66835,78,3074,111,3202,111,3330,111,3458,111,2406,111,2662,111,2790,111,3046,111,3174,111,3302,111,3430,111,3664,111,3792,111,4160,111,1637,111,1781,111,65359,111,8500,111,119848,111,119900,111,119952,111,120056,111,120108,111,120160,111,120212,111,120264,111,120316,111,120368,111,120420,111,120472,111,7439,111,7441,111,43837,111,959,111,120528,111,120586,111,120644,111,120702,111,120760,111,963,111,120532,111,120590,111,120648,111,120706,111,120764,111,11423,111,4351,111,1413,111,1505,111,1607,111,126500,111,126564,111,126596,111,65259,111,65260,111,65258,111,65257,111,1726,111,64428,111,64429,111,64427,111,64426,111,1729,111,64424,111,64425,111,64423,111,64422,111,1749,111,3360,111,4125,111,66794,111,71880,111,71895,111,66604,111,1984,79,2534,79,2918,79,12295,79,70864,79,71904,79,120782,79,120792,79,120802,79,120812,79,120822,79,130032,79,65327,79,119822,79,119874,79,119926,79,119978,79,120030,79,120082,79,120134,79,120186,79,120238,79,120290,79,120342,79,120394,79,120446,79,927,79,120502,79,120560,79,120618,79,120676,79,120734,79,11422,79,1365,79,11604,79,4816,79,2848,79,66754,79,42227,79,71861,79,66194,79,66219,79,66564,79,66838,79,9076,112,65360,112,119849,112,119901,112,119953,112,120005,112,120057,112,120109,112,120161,112,120213,112,120265,112,120317,112,120369,112,120421,112,120473,112,961,112,120530,112,120544,112,120588,112,120602,112,120646,112,120660,112,120704,112,120718,112,120762,112,120776,112,11427,112,65328,80,8473,80,119823,80,119875,80,119927,80,119979,80,120031,80,120083,80,120187,80,120239,80,120291,80,120343,80,120395,80,120447,80,929,80,120504,80,120562,80,120620,80,120678,80,120736,80,11426,80,5090,80,5229,80,42193,80,66197,80,119850,113,119902,113,119954,113,120006,113,120058,113,120110,113,120162,113,120214,113,120266,113,120318,113,120370,113,120422,113,120474,113,1307,113,1379,113,1382,113,8474,81,119824,81,119876,81,119928,81,119980,81,120032,81,120084,81,120188,81,120240,81,120292,81,120344,81,120396,81,120448,81,11605,81,119851,114,119903,114,119955,114,120007,114,120059,114,120111,114,120163,114,120215,114,120267,114,120319,114,120371,114,120423,114,120475,114,43847,114,43848,114,7462,114,11397,114,43905,114,119318,82,8475,82,8476,82,8477,82,119825,82,119877,82,119929,82,120033,82,120189,82,120241,82,120293,82,120345,82,120397,82,120449,82,422,82,5025,82,5074,82,66740,82,5511,82,42211,82,94005,82,65363,115,119852,115,119904,115,119956,115,120008,115,120060,115,120112,115,120164,115,120216,115,120268,115,120320,115,120372,115,120424,115,120476,115,42801,115,445,115,1109,115,43946,115,71873,115,66632,115,65331,83,119826,83,119878,83,119930,83,119982,83,120034,83,120086,83,120138,83,120190,83,120242,83,120294,83,120346,83,120398,83,120450,83,1029,83,1359,83,5077,83,5082,83,42210,83,94010,83,66198,83,66592,83,119853,116,119905,116,119957,116,120009,116,120061,116,120113,116,120165,116,120217,116,120269,116,120321,116,120373,116,120425,116,120477,116,8868,84,10201,84,128872,84,65332,84,119827,84,119879,84,119931,84,119983,84,120035,84,120087,84,120139,84,120191,84,120243,84,120295,84,120347,84,120399,84,120451,84,932,84,120507,84,120565,84,120623,84,120681,84,120739,84,11430,84,5026,84,42196,84,93962,84,71868,84,66199,84,66225,84,66325,84,119854,117,119906,117,119958,117,120010,117,120062,117,120114,117,120166,117,120218,117,120270,117,120322,117,120374,117,120426,117,120478,117,42911,117,7452,117,43854,117,43858,117,651,117,965,117,120534,117,120592,117,120650,117,120708,117,120766,117,1405,117,66806,117,71896,117,8746,85,8899,85,119828,85,119880,85,119932,85,119984,85,120036,85,120088,85,120140,85,120192,85,120244,85,120296,85,120348,85,120400,85,120452,85,1357,85,4608,85,66766,85,5196,85,42228,85,94018,85,71864,85,8744,118,8897,118,65366,118,8564,118,119855,118,119907,118,119959,118,120011,118,120063,118,120115,118,120167,118,120219,118,120271,118,120323,118,120375,118,120427,118,120479,118,7456,118,957,118,120526,118,120584,118,120642,118,120700,118,120758,118,1141,118,1496,118,71430,118,43945,118,71872,118,119309,86,1639,86,1783,86,8548,86,119829,86,119881,86,119933,86,119985,86,120037,86,120089,86,120141,86,120193,86,120245,86,120297,86,120349,86,120401,86,120453,86,1140,86,11576,86,5081,86,5167,86,42719,86,42214,86,93960,86,71840,86,66845,86,623,119,119856,119,119908,119,119960,119,120012,119,120064,119,120116,119,120168,119,120220,119,120272,119,120324,119,120376,119,120428,119,120480,119,7457,119,1121,119,1309,119,1377,119,71434,119,71438,119,71439,119,43907,119,71919,87,71910,87,119830,87,119882,87,119934,87,119986,87,120038,87,120090,87,120142,87,120194,87,120246,87,120298,87,120350,87,120402,87,120454,87,1308,87,5043,87,5076,87,42218,87,5742,120,10539,120,10540,120,10799,120,65368,120,8569,120,119857,120,119909,120,119961,120,120013,120,120065,120,120117,120,120169,120,120221,120,120273,120,120325,120,120377,120,120429,120,120481,120,5441,120,5501,120,5741,88,9587,88,66338,88,71916,88,65336,88,8553,88,119831,88,119883,88,119935,88,119987,88,120039,88,120091,88,120143,88,120195,88,120247,88,120299,88,120351,88,120403,88,120455,88,42931,88,935,88,120510,88,120568,88,120626,88,120684,88,120742,88,11436,88,11613,88,5815,88,42219,88,66192,88,66228,88,66327,88,66855,88,611,121,7564,121,65369,121,119858,121,119910,121,119962,121,120014,121,120066,121,120118,121,120170,121,120222,121,120274,121,120326,121,120378,121,120430,121,120482,121,655,121,7935,121,43866,121,947,121,8509,121,120516,121,120574,121,120632,121,120690,121,120748,121,1199,121,4327,121,71900,121,65337,89,119832,89,119884,89,119936,89,119988,89,120040,89,120092,89,120144,89,120196,89,120248,89,120300,89,120352,89,120404,89,120456,89,933,89,978,89,120508,89,120566,89,120624,89,120682,89,120740,89,11432,89,1198,89,5033,89,5053,89,42220,89,94019,89,71844,89,66226,89,119859,122,119911,122,119963,122,120015,122,120067,122,120119,122,120171,122,120223,122,120275,122,120327,122,120379,122,120431,122,120483,122,7458,122,43923,122,71876,122,66293,90,71909,90,65338,90,8484,90,8488,90,119833,90,119885,90,119937,90,119989,90,120041,90,120197,90,120249,90,120301,90,120353,90,120405,90,120457,90,918,90,120493,90,120551,90,120609,90,120667,90,120725,90,5059,90,42204,90,71849,90,65282,34,65284,36,65285,37,65286,38,65290,42,65291,43,65294,46,65295,47,65296,48,65297,49,65298,50,65299,51,65300,52,65301,53,65302,54,65303,55,65304,56,65305,57,65308,60,65309,61,65310,62,65312,64,65316,68,65318,70,65319,71,65324,76,65329,81,65330,82,65333,85,65334,86,65335,87,65343,95,65346,98,65348,100,65350,102,65355,107,65357,109,65358,110,65361,113,65362,114,65364,116,65365,117,65367,119,65370,122,65371,123,65373,125,119846,109],\"_default\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"cs\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"de\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"es\":[8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"fr\":[65374,126,65306,58,65281,33,8216,96,8245,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"it\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"ja\":[8211,45,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65292,44,65307,59],\"ko\":[8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"pl\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"pt-BR\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"qps-ploc\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"ru\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,305,105,921,73,1009,112,215,120,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"tr\":[160,32,8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"zh-hans\":[65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65288,40,65289,41],\"zh-hant\":[8211,45,65374,126,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65307,59]}' ); }); diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index 6a0e4da3099..deefcb96396 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -7,7 +7,7 @@ import { transformErrorForSerialization } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { getAllMethodNames } from 'vs/base/common/objects'; -import { globals, isWeb } from 'vs/base/common/platform'; +import { isWeb } from 'vs/base/common/platform'; import * as strings from 'vs/base/common/strings'; const INITIALIZE = '$initialize'; @@ -324,12 +324,14 @@ export class SimpleWorkerClient extends Disp // Gather loader configuration let loaderConfiguration: any = null; - if (typeof globals.require !== 'undefined' && typeof globals.require.getConfig === 'function') { + + const globalRequire: { getConfig?(): object } | undefined = (globalThis as any).require; + if (typeof globalRequire !== 'undefined' && typeof globalRequire.getConfig === 'function') { // Get the configuration from the Monaco AMD Loader - loaderConfiguration = globals.require.getConfig(); - } else if (typeof globals.requirejs !== 'undefined') { + loaderConfiguration = globalRequire.getConfig(); + } else if (typeof (globalThis as any).requirejs !== 'undefined') { // Get the configuration from requirejs - loaderConfiguration = globals.requirejs.s.contexts._.config; + loaderConfiguration = (globalThis as any).requirejs.s.contexts._.config; } const hostMethods = getAllMethodNames(host); @@ -527,17 +529,17 @@ export class SimpleWorkerServer { // Since this is in a web worker, enable catching errors loaderConfig.catchError = true; - globals.require.config(loaderConfig); + globalThis.require.config(loaderConfig); } return new Promise((resolve, reject) => { // Use the global require to be sure to get the global config // ESM-comment-begin - const req = (globals.require || require); + const req = (globalThis.require || require); // ESM-comment-end // ESM-uncomment-begin - // const req = globals.require; + // const req = globalThis.require; // ESM-uncomment-end req([moduleId], (module: { create: IRequestHandlerFactory }) => { diff --git a/src/vs/base/node/id.ts b/src/vs/base/node/id.ts index 65bff8cc522..a5ea6a2bb0d 100644 --- a/src/vs/base/node/id.ts +++ b/src/vs/base/node/id.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { networkInterfaces } from 'os'; -import * as errors from 'vs/base/common/errors'; import { TernarySearchTree } from 'vs/base/common/ternarySearchTree'; import * as uuid from 'vs/base/common/uuid'; import { getMac } from 'vs/base/node/macAddress'; @@ -78,10 +77,10 @@ export const virtualMachineHint: { value(): number } = new class { }; let machineId: Promise; -export async function getMachineId(): Promise { +export async function getMachineId(errorLogger: (error: any) => void): Promise { if (!machineId) { machineId = (async () => { - const id = await getMacMachineId(); + const id = await getMacMachineId(errorLogger); return id || uuid.generateUuid(); // fallback, generate a UUID })(); @@ -90,13 +89,13 @@ export async function getMachineId(): Promise { return machineId; } -async function getMacMachineId(): Promise { +async function getMacMachineId(errorLogger: (error: any) => void): Promise { try { const crypto = await import('crypto'); const macAddress = getMac(); return crypto.createHash('sha256').update(macAddress, 'utf8').digest('hex'); } catch (err) { - errors.onUnexpectedError(err); + errorLogger(err); return undefined; } } diff --git a/src/vs/base/node/languagePacks.d.ts b/src/vs/base/node/languagePacks.d.ts index 87bff5b75a4..5dd1b1f1ee9 100644 --- a/src/vs/base/node/languagePacks.d.ts +++ b/src/vs/base/node/languagePacks.d.ts @@ -5,6 +5,7 @@ export interface NLSConfiguration { locale: string; + osLocale: string; availableLanguages: { [key: string]: string; }; @@ -21,4 +22,4 @@ export interface InternalNLSConfiguration extends NLSConfiguration { _languagePackSupport?: boolean; } -export function getNLSConfiguration(commit: string | undefined, userDataPath: string, metaDataFile: string, locale: string): Promise; +export function getNLSConfiguration(commit: string | undefined, userDataPath: string, metaDataFile: string, locale: string, osLocale: string): Promise; diff --git a/src/vs/base/node/languagePacks.js b/src/vs/base/node/languagePacks.js index 006cd42d707..0d3d1acf6a3 100644 --- a/src/vs/base/node/languagePacks.js +++ b/src/vs/base/node/languagePacks.js @@ -108,15 +108,24 @@ * @param {string | undefined} commit * @param {string} userDataPath * @param {string} metaDataFile - * @param {string | undefined} locale + * @param {string} locale + * @param {string} osLocale + * @returns {Promise} */ - function getNLSConfiguration(commit, userDataPath, metaDataFile, locale) { + function getNLSConfiguration(commit, userDataPath, metaDataFile, locale, osLocale) { + const defaultResult = function (locale) { + perf.mark('code/didGenerateNls'); + return Promise.resolve({ locale, osLocale, availableLanguages: {} }); + }; + + perf.mark('code/willGenerateNls'); + if (locale === 'pseudo') { - return Promise.resolve({ locale: locale, availableLanguages: {}, pseudo: true }); + return Promise.resolve({ locale, osLocale, availableLanguages: {}, pseudo: true }); } if (process.env['VSCODE_DEV']) { - return Promise.resolve({ locale: locale, availableLanguages: {} }); + return Promise.resolve({ locale, osLocale, availableLanguages: {} }); } // We have a built version so we have extracted nls file. Try to find @@ -125,17 +134,11 @@ // Check if we have an English or English US locale. If so fall to default since that is our // English translation (we don't ship *.nls.en.json files) if (locale && (locale === 'en' || locale === 'en-us')) { - return Promise.resolve({ locale: locale, availableLanguages: {} }); + return Promise.resolve({ locale, osLocale, availableLanguages: {} }); } const initialLocale = locale; - perf.mark('code/willGenerateNls'); - - const defaultResult = function (locale) { - perf.mark('code/didGenerateNls'); - return Promise.resolve({ locale: locale, availableLanguages: {} }); - }; try { if (!commit) { return defaultResult(initialLocale); @@ -144,10 +147,11 @@ if (!configs) { return defaultResult(initialLocale); } - locale = resolveLanguagePackLocale(configs, locale); - if (!locale) { + const resolvedLocale = resolveLanguagePackLocale(configs, locale); + if (!resolvedLocale) { return defaultResult(initialLocale); } + locale = resolvedLocale; const packConfig = configs[locale]; let mainPack; if (!packConfig || typeof packConfig.hash !== 'string' || !packConfig.translations || typeof (mainPack = packConfig.translations['vscode']) !== 'string') { @@ -164,6 +168,7 @@ const corruptedFile = path.join(cacheRoot, 'corrupted.info'); const result = { locale: initialLocale, + osLocale, availableLanguages: { '*': locale }, _languagePackId: packId, _translationsConfigFile: translationsConfigFile, diff --git a/src/vs/base/node/ps.ts b/src/vs/base/node/ps.ts index cc01a30f0ba..93432f17237 100644 --- a/src/vs/base/node/ps.ts +++ b/src/vs/base/node/ps.ts @@ -48,13 +48,8 @@ export function listProcesses(rootPid: number): Promise { function findName(cmd: string): string { - const SHARED_PROCESS_HINT = /--vscode-window-kind=shared-process/i; // TODO@bpasero remove me - const ISSUE_REPORTER_HINT = /--vscode-window-kind=issue-reporter/i; - const PROCESS_EXPLORER_HINT = /--vscode-window-kind=process-explorer/i; const UTILITY_NETWORK_HINT = /--utility-sub-type=network/i; - const UTILITY_EXTENSION_HOST_HINT = /--vscode-utility-kind=extensionHost/i; - const UTILITY_FILE_WATCHER_HOST_HINT = /--vscode-utility-kind=fileWatcher/i; - const UTILITY_SHARED_PROCESS_HINT = /--vscode-utility-kind=shared-process/i; + const NODEJS_PROCESS_HINT = /--ms-enable-electron-run-as-node/i; const WINDOWS_CRASH_REPORTER = /--crashes-directory/i; const WINDOWS_PTY = /\\pipe\\winpty-control/i; const WINDOWS_CONSOLE_HOST = /conhost\.exe/i; @@ -70,7 +65,7 @@ export function listProcesses(rootPid: number): Promise { return 'winpty-process'; } - //find windows console host process + // find windows console host process if (WINDOWS_CONSOLE_HOST.exec(cmd)) { return 'console-window-host (Windows internal process)'; } @@ -79,35 +74,13 @@ export function listProcesses(rootPid: number): Promise { let matches = TYPE.exec(cmd); if (matches && matches.length === 2) { if (matches[1] === 'renderer') { - if (SHARED_PROCESS_HINT.exec(cmd)) { - return 'shared-process'; - } - - if (ISSUE_REPORTER_HINT.exec(cmd)) { - return 'issue-reporter'; - } - - if (PROCESS_EXPLORER_HINT.exec(cmd)) { - return 'process-explorer'; - } - return `window`; } else if (matches[1] === 'utility') { if (UTILITY_NETWORK_HINT.exec(cmd)) { return 'utility-network-service'; } - if (UTILITY_EXTENSION_HOST_HINT.exec(cmd)) { - return 'extension-host'; - } - - if (UTILITY_FILE_WATCHER_HOST_HINT.exec(cmd)) { - return 'file-watcher'; - } - - if (UTILITY_SHARED_PROCESS_HINT.exec(cmd)) { - return 'shared-process'; - } + return 'utility-process'; } else if (matches[1] === 'extensionHost') { return 'extension-host'; // normalize remote extension host type } @@ -126,9 +99,15 @@ export function listProcesses(rootPid: number): Promise { if (result) { if (cmd.indexOf('node ') < 0 && cmd.indexOf('node.exe') < 0) { - return `electron_node ${result}`; + return `electron-nodejs (${result})`; } } + + // find Electron node.js processes + if (NODEJS_PROCESS_HINT.exec(cmd)) { + return `electron-nodejs (${cmd})`; + } + return cmd; } diff --git a/src/vs/base/node/zip.ts b/src/vs/base/node/zip.ts index 2033f7cd98e..171b9e45bbc 100644 --- a/src/vs/base/node/zip.ts +++ b/src/vs/base/node/zip.ts @@ -14,6 +14,9 @@ import * as nls from 'vs/nls'; import { Entry, open as _openZip, ZipFile } from 'yauzl'; import * as yazl from 'yazl'; +export const CorruptZipMessage: string = 'end of central directory record signature not found'; +const CORRUPT_ZIP_PATTERN = new RegExp(CorruptZipMessage); + export interface IExtractOptions { overwrite?: boolean; @@ -63,7 +66,7 @@ function toExtractError(err: Error): ExtractError { let type: ExtractErrorType | undefined = undefined; - if (/end of central directory record signature not found/.test(err.message)) { + if (CORRUPT_ZIP_PATTERN.test(err.message)) { type = 'CorruptZip'; } diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 1d8c4a45efa..d71baaeeeb5 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -949,7 +949,7 @@ export class IPCServer implements IChannelServer, I * An `IPCClient` is both a channel client and a channel server. * * As the owner of a protocol, you should extend both this - * and the `IPCClient` classes to get IPC implementations + * and the `IPCServer` classes to get IPC implementations * for your protocol. */ export class IPCClient implements IChannelClient, IChannelServer, IDisposable { diff --git a/src/vs/base/parts/ipc/node/ipc.cp.ts b/src/vs/base/parts/ipc/node/ipc.cp.ts index a6dd5527c1f..4fcad2758da 100644 --- a/src/vs/base/parts/ipc/node/ipc.cp.ts +++ b/src/vs/base/parts/ipc/node/ipc.cp.ts @@ -195,9 +195,9 @@ export class Client implements IChannelClient, IDisposable { } if (forkOpts.execArgv === undefined) { - // if not set, the forked process inherits the execArgv of the parent process - // --inspect and --inspect-brk can not be inherited as the port would conflict - forkOpts.execArgv = process.execArgv.filter(a => !/^--inspect(-brk)?=/.test(a)); // remove + forkOpts.execArgv = process.execArgv // if not set, the forked process inherits the execArgv of the parent process + .filter(a => !/^--inspect(-brk)?=/.test(a)) // --inspect and --inspect-brk can not be inherited as the port would conflict + .filter(a => !a.startsWith('--vscode-')); // --vscode-* arguments are unsupported by node.js and thus need to remove } removeDangerousEnvVariables(forkOpts.env); diff --git a/src/vs/base/parts/ipc/node/ipc.net.ts b/src/vs/base/parts/ipc/node/ipc.net.ts index 455caa3efeb..0a7f31379f6 100644 --- a/src/vs/base/parts/ipc/node/ipc.net.ts +++ b/src/vs/base/parts/ipc/node/ipc.net.ts @@ -189,7 +189,15 @@ export class NodeSocket implements ISocket { } const enum Constants { - MinHeaderByteSize = 2 + MinHeaderByteSize = 2, + /** + * If we need to write a large buffer, we will split it into 256KB chunks and + * send each chunk as a websocket message. This is to prevent that the sending + * side is stuck waiting for the entire buffer to be compressed before writing + * to the underlying socket or that the receiving side is stuck waiting for the + * entire message to be received before processing the bytes. + */ + MaxWebSocketMessageLength = 256 * 1024 // 256 KB } const enum ReadState { @@ -272,7 +280,14 @@ export class WebSocketNodeSocket extends Disposable implements ISocket, ISocketT })); this._incomingData = new ChunkStream(); this._register(this.socket.onData(data => this._acceptChunk(data))); - this._register(this.socket.onClose((e) => this._onClose.fire(e))); + this._register(this.socket.onClose(async (e) => { + // Delay surfacing the close event until the async inflating is done + // and all data has been emitted + if (this._flowManager.isProcessingReadQueue()) { + await Event.toPromise(this._flowManager.onDidFinishProcessingReadQueue); + } + this._onClose.fire(e); + })); } public override dispose(): void { @@ -300,7 +315,23 @@ export class WebSocketNodeSocket extends Disposable implements ISocket, ISocketT } public write(buffer: VSBuffer): void { - this._flowManager.writeMessage(buffer); + // If we write many logical messages (let's say 1000 messages of 100KB) during a single process tick, we do + // this thing where we install a process.nextTick timer and group all of them together and we then issue a + // single WebSocketNodeSocket.write with a 100MB buffer. + // + // The first problem is that the actual writing to the underlying node socket will only happen after all of + // the 100MB have been deflated (due to waiting on zlib flush). The second problem is on the reading side, + // where we will get a single WebSocketNodeSocket.onData event fired when all the 100MB have arrived, + // delaying processing the 1000 received messages until all have arrived, instead of processing them as each + // one arrives. + // + // We therefore split the buffer into chunks, and issue a write for each chunk. + + let start = 0; + while (start < buffer.byteLength) { + this._flowManager.writeMessage(buffer.slice(start, Math.min(start + Constants.MaxWebSocketMessageLength, buffer.byteLength))); + start += Constants.MaxWebSocketMessageLength; + } } private _write(buffer: VSBuffer, compressed: boolean): void { @@ -465,6 +496,9 @@ class WebSocketFlowManager extends Disposable { private readonly _writeQueue: VSBuffer[] = []; private readonly _readQueue: { data: VSBuffer; isCompressed: boolean; isLastFrameOfMessage: boolean }[] = []; + private readonly _onDidFinishProcessingReadQueue = this._register(new Emitter()); + public readonly onDidFinishProcessingReadQueue = this._onDidFinishProcessingReadQueue.event; + private readonly _onDidFinishProcessingWriteQueue = this._register(new Emitter()); public readonly onDidFinishProcessingWriteQueue = this._onDidFinishProcessingWriteQueue.event; @@ -565,6 +599,11 @@ class WebSocketFlowManager extends Disposable { } } this._isProcessingReadQueue = false; + this._onDidFinishProcessingReadQueue.fire(); + } + + public isProcessingReadQueue(): boolean { + return (this._isProcessingReadQueue); } /** @@ -733,14 +772,10 @@ export function createRandomIPCHandle(): string { return `\\\\.\\pipe\\vscode-ipc-${randomSuffix}-sock`; } - // Mac/Unix: use socket file and prefer - // XDG_RUNTIME_DIR over tmpDir - let result: string; - if (XDG_RUNTIME_DIR) { - result = join(XDG_RUNTIME_DIR, `vscode-ipc-${randomSuffix}.sock`); - } else { - result = join(getNodeDependencies().os.tmpdir(), `vscode-ipc-${randomSuffix}.sock`); - } + // Mac & Unix: Use socket file + // Unix: Prefer XDG_RUNTIME_DIR over user data path + const basePath = process.platform !== 'darwin' && XDG_RUNTIME_DIR ? XDG_RUNTIME_DIR : getNodeDependencies().os.tmpdir(); + const result = join(basePath, `vscode-ipc-${randomSuffix}.sock`); // Validate length validateIPCHandleLength(result); @@ -756,14 +791,20 @@ export function createStaticIPCHandle(directoryPath: string, type: string, versi return `\\\\.\\pipe\\${scope}-${version}-${type}-sock`; } - // Mac/Unix: use socket file and prefer - // XDG_RUNTIME_DIR over user data path - // unless portable + // Mac & Unix: Use socket file + // Unix: Prefer XDG_RUNTIME_DIR over user data path, unless portable + // Trim the version and type values for the socket to prevent too large + // file names causing issues: https://unix.stackexchange.com/q/367008 + + const versionForSocket = version.substr(0, 4); + const typeForSocket = type.substr(0, 6); + const scopeForSocket = scope.substr(0, 8); + let result: string; - if (XDG_RUNTIME_DIR && !process.env['VSCODE_PORTABLE']) { - result = join(XDG_RUNTIME_DIR, `vscode-${scope.substr(0, 8)}-${version}-${type}.sock`); + if (process.platform !== 'darwin' && XDG_RUNTIME_DIR && !process.env['VSCODE_PORTABLE']) { + result = join(XDG_RUNTIME_DIR, `vscode-${scopeForSocket}-${versionForSocket}-${typeForSocket}.sock`); } else { - result = join(directoryPath, `${version}-${type}.sock`); + result = join(directoryPath, `${versionForSocket}-${typeForSocket}.sock`); } // Validate length diff --git a/src/vs/base/parts/ipc/test/node/ipc.net.test.ts b/src/vs/base/parts/ipc/test/node/ipc.net.test.ts index ed797697982..42d77c57bdc 100644 --- a/src/vs/base/parts/ipc/test/node/ipc.net.test.ts +++ b/src/vs/base/parts/ipc/test/node/ipc.net.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { EventEmitter } from 'events'; -import { createServer, Socket } from 'net'; +import { AddressInfo, connect, createServer, Server, Socket } from 'net'; import { tmpdir } from 'os'; import { Barrier, timeout } from 'vs/base/common/async'; import { VSBuffer } from 'vs/base/common/buffer'; @@ -706,4 +706,63 @@ suite('WebSocketNodeSocket', () => { assert.deepStrictEqual(actual, 'Helloworld'); }); }); + + test('Large buffers are split and sent in chunks', async () => { + + let receivingSideOnDataCallCount = 0; + let receivingSideTotalBytes = 0; + const receivingSideSocketClosedBarrier = new Barrier(); + + const server = await listenOnRandomPort((socket) => { + // stop the server when the first connection is received + server.close(); + + const webSocketNodeSocket = new WebSocketNodeSocket(new NodeSocket(socket), true, null, false); + webSocketNodeSocket.onData((data) => { + receivingSideOnDataCallCount++; + receivingSideTotalBytes += data.byteLength; + }); + + webSocketNodeSocket.onClose(() => { + webSocketNodeSocket.dispose(); + receivingSideSocketClosedBarrier.open(); + }); + }); + + const socket = connect({ + host: '127.0.0.1', + port: (server.address()).port + }); + + const buff = generateRandomBuffer(1 * 1024 * 1024); + + const webSocketNodeSocket = new WebSocketNodeSocket(new NodeSocket(socket), true, null, false); + webSocketNodeSocket.write(buff); + await webSocketNodeSocket.drain(); + webSocketNodeSocket.dispose(); + await receivingSideSocketClosedBarrier.wait(); + + assert.strictEqual(receivingSideTotalBytes, buff.byteLength); + assert.strictEqual(receivingSideOnDataCallCount, 4); + }); + + function generateRandomBuffer(size: number): VSBuffer { + const buff = VSBuffer.alloc(size); + for (let i = 0; i < size; i++) { + buff.writeUInt8(Math.floor(256 * Math.random()), i); + } + return buff; + } + + function listenOnRandomPort(handler: (socket: Socket) => void): Promise { + return new Promise((resolve, reject) => { + const server = createServer(handler).listen(0); + server.on('listening', () => { + resolve(server); + }); + server.on('error', (err) => { + reject(err); + }); + }); + } }); diff --git a/src/vs/base/parts/sandbox/electron-browser/preload.js b/src/vs/base/parts/sandbox/electron-sandbox/preload.js similarity index 95% rename from src/vs/base/parts/sandbox/electron-browser/preload.js rename to src/vs/base/parts/sandbox/electron-sandbox/preload.js index 53e38ce14c2..12b8e025027 100644 --- a/src/vs/base/parts/sandbox/electron-browser/preload.js +++ b/src/vs/base/parts/sandbox/electron-sandbox/preload.js @@ -116,7 +116,7 @@ // ####################################################################### /** - * @type {import('../electron-sandbox/globals')} + * @type {import('./globals')} */ const globals = { @@ -124,7 +124,7 @@ * A minimal set of methods exposed from Electron's `ipcRenderer` * to support communication to main process. * - * @typedef {import('../electron-sandbox/electronTypes').IpcRenderer} IpcRenderer + * @typedef {import('./electronTypes').IpcRenderer} IpcRenderer * @typedef {import('electron').IpcRendererEvent} IpcRendererEvent * * @type {IpcRenderer} @@ -194,7 +194,7 @@ }, /** - * @type {import('../electron-sandbox/globals').IpcMessagePort} + * @type {import('./globals').IpcMessagePort} */ ipcMessagePort: { @@ -224,7 +224,7 @@ /** * Support for subset of methods of Electron's `webFrame` type. * - * @type {import('../electron-sandbox/electronTypes').WebFrame} + * @type {import('./electronTypes').WebFrame} */ webFrame: { @@ -244,7 +244,7 @@ * Note: when `sandbox` is enabled, the only properties available * are https://github.com/electron/electron/blob/master/docs/api/process.md#sandbox * - * @typedef {import('../electron-sandbox/globals').ISandboxNodeProcess} ISandboxNodeProcess + * @typedef {import('./globals').ISandboxNodeProcess} ISandboxNodeProcess * * @type {ISandboxNodeProcess} */ @@ -293,7 +293,7 @@ /** * Some information about the context we are running in. * - * @type {import('../electron-sandbox/globals').ISandboxContext} + * @type {import('./globals').ISandboxContext} */ context: { diff --git a/src/vs/base/parts/storage/test/node/storage.test.ts b/src/vs/base/parts/storage/test/node/storage.integrationTest.ts similarity index 100% rename from src/vs/base/parts/storage/test/node/storage.test.ts rename to src/vs/base/parts/storage/test/node/storage.integrationTest.ts diff --git a/src/vs/base/test/browser/markdownRenderer.test.ts b/src/vs/base/test/browser/markdownRenderer.test.ts index f30fc44b962..223a35238bb 100644 --- a/src/vs/base/test/browser/markdownRenderer.test.ts +++ b/src/vs/base/test/browser/markdownRenderer.test.ts @@ -4,8 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { renderMarkdown, renderMarkdownAsPlaintext } from 'vs/base/browser/markdownRenderer'; +import { fillInIncompleteTokens, renderMarkdown, renderMarkdownAsPlaintext } from 'vs/base/browser/markdownRenderer'; import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent'; +import { marked } from 'vs/base/common/marked/marked'; import { parse } from 'vs/base/common/marshalling'; import { isWeb } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; @@ -325,4 +326,185 @@ suite('MarkdownRenderer', () => { assert.strictEqual(result.innerHTML, ``); }); }); + + suite('fillInIncompleteTokens', () => { + function ignoreRaw(...tokenLists: marked.Token[][]): void { + tokenLists.forEach(tokens => { + tokens.forEach(t => t.raw = ''); + }); + } + + const completeTable = '| a | b |\n| --- | --- |'; + + test('complete table', () => { + const tokens = marked.lexer(completeTable); + const newTokens = fillInIncompleteTokens(tokens); + assert.equal(newTokens, tokens); + }); + + test('full header only', () => { + const incompleteTable = '| a | b |'; + const tokens = marked.lexer(incompleteTable); + const completeTableTokens = marked.lexer(completeTable); + + const newTokens = fillInIncompleteTokens(tokens); + assert.deepStrictEqual(newTokens, completeTableTokens); + }); + + test('full header only with trailing space', () => { + const incompleteTable = '| a | b | '; + const tokens = marked.lexer(incompleteTable); + const completeTableTokens = marked.lexer(completeTable); + + const newTokens = fillInIncompleteTokens(tokens); + ignoreRaw(newTokens, completeTableTokens); + assert.deepStrictEqual(newTokens, completeTableTokens); + }); + + test('incomplete header', () => { + const incompleteTable = '| a | b'; + const tokens = marked.lexer(incompleteTable); + const completeTableTokens = marked.lexer(completeTable); + + const newTokens = fillInIncompleteTokens(tokens); + + ignoreRaw(newTokens, completeTableTokens); + assert.deepStrictEqual(newTokens, completeTableTokens); + }); + + test('incomplete header one column', () => { + const incompleteTable = '| a '; + const tokens = marked.lexer(incompleteTable); + const completeTableTokens = marked.lexer(incompleteTable + '|\n| --- |'); + + const newTokens = fillInIncompleteTokens(tokens); + + ignoreRaw(newTokens, completeTableTokens); + assert.deepStrictEqual(newTokens, completeTableTokens); + }); + + test('full header with extras', () => { + const incompleteTable = '| a **bold** | b _italics_ |'; + const tokens = marked.lexer(incompleteTable); + const completeTableTokens = marked.lexer(incompleteTable + '\n| --- | --- |'); + + const newTokens = fillInIncompleteTokens(tokens); + assert.deepStrictEqual(newTokens, completeTableTokens); + }); + + test('full header with leading text', () => { + // Parsing this gives one token and one 'text' subtoken + const incompleteTable = 'here is a table\n| a | b |'; + const tokens = marked.lexer(incompleteTable); + const completeTableTokens = marked.lexer(incompleteTable + '\n| --- | --- |'); + + const newTokens = fillInIncompleteTokens(tokens); + assert.deepStrictEqual(newTokens, completeTableTokens); + }); + + test('full header with leading other stuff', () => { + // Parsing this gives one token and one 'text' subtoken + const incompleteTable = '```js\nconst xyz = 123;\n```\n| a | b |'; + const tokens = marked.lexer(incompleteTable); + const completeTableTokens = marked.lexer(incompleteTable + '\n| --- | --- |'); + + const newTokens = fillInIncompleteTokens(tokens); + assert.deepStrictEqual(newTokens, completeTableTokens); + }); + + test('full header with incomplete separator', () => { + const incompleteTable = '| a | b |\n| ---'; + const tokens = marked.lexer(incompleteTable); + const completeTableTokens = marked.lexer(completeTable); + + const newTokens = fillInIncompleteTokens(tokens); + assert.deepStrictEqual(newTokens, completeTableTokens); + }); + + test('full header with incomplete separator 2', () => { + const incompleteTable = '| a | b |\n| --- |'; + const tokens = marked.lexer(incompleteTable); + const completeTableTokens = marked.lexer(completeTable); + + const newTokens = fillInIncompleteTokens(tokens); + assert.deepStrictEqual(newTokens, completeTableTokens); + }); + + test('full header with incomplete separator 3', () => { + const incompleteTable = '| a | b |\n|'; + const tokens = marked.lexer(incompleteTable); + const completeTableTokens = marked.lexer(completeTable); + + const newTokens = fillInIncompleteTokens(tokens); + assert.deepStrictEqual(newTokens, completeTableTokens); + }); + + test('not a table', () => { + const incompleteTable = '| a | b |\nsome text'; + const tokens = marked.lexer(incompleteTable); + + const newTokens = fillInIncompleteTokens(tokens); + assert.deepStrictEqual(newTokens, tokens); + }); + + test('not a table 2', () => { + const incompleteTable = '| a | b |\n| --- |\nsome text'; + const tokens = marked.lexer(incompleteTable); + + const newTokens = fillInIncompleteTokens(tokens); + assert.deepStrictEqual(newTokens, tokens); + }); + + test('complete code block', () => { + const completeCodeblock = '```js\nconst xyz = 123;\n```'; + const tokens = marked.lexer(completeCodeblock); + const newTokens = fillInIncompleteTokens(tokens); + assert.equal(newTokens, tokens); + }); + + test('code block header only', () => { + const incompleteCodeblock = '```js'; + const tokens = marked.lexer(incompleteCodeblock); + const newTokens = fillInIncompleteTokens(tokens); + + const completeCodeblockTokens = marked.lexer(incompleteCodeblock + '\n```'); + assert.deepStrictEqual(newTokens, completeCodeblockTokens); + }); + + test('code block header no lang', () => { + const incompleteCodeblock = '```'; + const tokens = marked.lexer(incompleteCodeblock); + const newTokens = fillInIncompleteTokens(tokens); + + const completeCodeblockTokens = marked.lexer(incompleteCodeblock + '\n```'); + assert.deepStrictEqual(newTokens, completeCodeblockTokens); + }); + + test('code block header and some code', () => { + const incompleteCodeblock = '```js\nconst'; + const tokens = marked.lexer(incompleteCodeblock); + const newTokens = fillInIncompleteTokens(tokens); + + const completeCodeblockTokens = marked.lexer(incompleteCodeblock + '\n```'); + assert.deepStrictEqual(newTokens, completeCodeblockTokens); + }); + + test('code block header with leading text', () => { + const incompleteCodeblock = 'some text\n```js'; + const tokens = marked.lexer(incompleteCodeblock); + const newTokens = fillInIncompleteTokens(tokens); + + const completeCodeblockTokens = marked.lexer(incompleteCodeblock + '\n```'); + assert.deepStrictEqual(newTokens, completeCodeblockTokens); + }); + + test('code block header with leading text and some code', () => { + const incompleteCodeblock = 'some text\n```js\nconst'; + const tokens = marked.lexer(incompleteCodeblock); + const newTokens = fillInIncompleteTokens(tokens); + + const completeCodeblockTokens = marked.lexer(incompleteCodeblock + '\n```'); + assert.deepStrictEqual(newTokens, completeCodeblockTokens); + }); + }); }); diff --git a/src/vs/base/test/browser/ui/tree/objectTreeModel.test.ts b/src/vs/base/test/browser/ui/tree/objectTreeModel.test.ts index df96ed68409..2b9917e4ef9 100644 --- a/src/vs/base/test/browser/ui/tree/objectTreeModel.test.ts +++ b/src/vs/base/test/browser/ui/tree/objectTreeModel.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { IList } from 'vs/base/browser/ui/tree/indexTreeModel'; import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel'; -import { ITreeFilter, ITreeNode, TreeVisibility } from 'vs/base/browser/ui/tree/tree'; +import { ITreeFilter, ITreeNode, ObjectTreeElementCollapseState, TreeVisibility } from 'vs/base/browser/ui/tree/tree'; import { timeout } from 'vs/base/common/async'; function toList(arr: T[]): IList { @@ -171,6 +171,27 @@ suite('ObjectTreeModel', function () { assert.deepStrictEqual(toArray(list), ['father']); }); + test('collapse state can be optionally preserved with strict identity', () => { + const list: ITreeNode[] = []; + const model = new ObjectTreeModel('test', toList(list), { collapseByDefault: true }); + const data = [{ element: 'father', collapsed: ObjectTreeElementCollapseState.PreserveOrExpanded, children: [{ element: 'child' }] }]; + + model.setChildren(null, data); + assert.deepStrictEqual(toArray(list), ['father', 'child']); + + model.setCollapsed('father', true); + assert.deepStrictEqual(toArray(list), ['father']); + + model.setChildren(null, data); + assert.deepStrictEqual(toArray(list), ['father']); + + model.setCollapsed('father', false); + assert.deepStrictEqual(toArray(list), ['father', 'child']); + + model.setChildren(null, data); + assert.deepStrictEqual(toArray(list), ['father', 'child']); + }); + test('sorter', () => { const compare: (a: string, b: string) => number = (a, b) => a < b ? -1 : 1; diff --git a/src/vs/base/test/common/async.test.ts b/src/vs/base/test/common/async.test.ts index 2b3b4210aea..2d131c8967b 100644 --- a/src/vs/base/test/common/async.test.ts +++ b/src/vs/base/test/common/async.test.ts @@ -395,51 +395,6 @@ suite('Async', () => { }); suite('Limiter', () => { - test('sync', function () { - const factoryFactory = (n: number) => () => { - return Promise.resolve(n); - }; - - let limiter = new async.Limiter(1); - - let promises: Promise[] = []; - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n)))); - - return Promise.all(promises).then((res) => { - assert.strictEqual(10, res.length); - - limiter = new async.Limiter(100); - - promises = []; - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n)))); - - return Promise.all(promises).then((res) => { - assert.strictEqual(10, res.length); - }); - }); - }); - - test('async', function () { - const factoryFactory = (n: number) => () => async.timeout(0).then(() => n); - - let limiter = new async.Limiter(1); - let promises: Promise[] = []; - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n)))); - - return Promise.all(promises).then((res) => { - assert.strictEqual(10, res.length); - - limiter = new async.Limiter(100); - - promises = []; - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n)))); - - return Promise.all(promises).then((res) => { - assert.strictEqual(10, res.length); - }); - }); - }); - test('assert degree of paralellism', function () { let activePromises = 0; const factoryFactory = (n: number) => () => { diff --git a/src/vs/base/test/common/event.test.ts b/src/vs/base/test/common/event.test.ts index ea5cc537bb2..5162306d8c0 100644 --- a/src/vs/base/test/common/event.test.ts +++ b/src/vs/base/test/common/event.test.ts @@ -235,6 +235,27 @@ suite('Event', function () { } }); + test('throwingListener (custom handler)', () => { + + const allError: any[] = []; + + const a = new Emitter({ + onListenerError(e) { allError.push(e); } + }); + let hit = false; + a.event(function () { + // eslint-disable-next-line no-throw-literal + throw 9; + }); + a.event(function () { + hit = true; + }); + a.fire(undefined); + assert.strictEqual(hit, true); + assert.deepStrictEqual(allError, [9]); + + }); + test('reusing event function and context', function () { let counter = 0; function listener() { diff --git a/src/vs/base/test/common/labels.test.ts b/src/vs/base/test/common/labels.test.ts index 36eec1391d6..f02cd55c523 100644 --- a/src/vs/base/test/common/labels.test.ts +++ b/src/vs/base/test/common/labels.test.ts @@ -59,7 +59,7 @@ suite('Labels', () => { assert.deepStrictEqual(labels.shorten(['a', 'a\\b', 'a\\b\\c', 'd\\b\\c', 'd\\b']), ['a', 'a\\b', 'a\\b\\c', 'd\\b\\c', 'd\\b']); assert.deepStrictEqual(labels.shorten(['a', 'a\\b', 'b']), ['a', 'a\\b', 'b']); assert.deepStrictEqual(labels.shorten(['', 'a', 'b', 'b\\c', 'a\\c']), ['.\\', 'a', 'b', 'b\\c', 'a\\c']); - assert.deepStrictEqual(labels.shorten(['src\\vs\\workbench\\parts\\execution\\electron-browser', 'src\\vs\\workbench\\parts\\execution\\electron-browser\\something', 'src\\vs\\workbench\\parts\\terminal\\electron-browser']), ['…\\execution\\electron-browser', '…\\something', '…\\terminal\\…']); + assert.deepStrictEqual(labels.shorten(['src\\vs\\workbench\\parts\\execution\\electron-sandbox', 'src\\vs\\workbench\\parts\\execution\\electron-sandbox\\something', 'src\\vs\\workbench\\parts\\terminal\\electron-sandbox']), ['…\\execution\\electron-sandbox', '…\\something', '…\\terminal\\…']); }); (isWindows ? test.skip : test)('shorten - not windows', () => { diff --git a/src/vs/base/test/node/id.test.ts b/src/vs/base/test/node/id.test.ts index 2ef49a3d4ba..ed4b0d0cb2f 100644 --- a/src/vs/base/test/node/id.test.ts +++ b/src/vs/base/test/node/id.test.ts @@ -11,8 +11,10 @@ import { flakySuite } from 'vs/base/test/node/testUtils'; flakySuite('ID', () => { test('getMachineId', async function () { - const id = await getMachineId(); + const errors = []; + const id = await getMachineId(err => errors.push(err)); assert.ok(id); + assert.strictEqual(errors.length, 0); }); test('getMac', async () => { diff --git a/src/vs/base/worker/workerMain.ts b/src/vs/base/worker/workerMain.ts index 9b4656b31c4..8d322f9cb59 100644 --- a/src/vs/base/worker/workerMain.ts +++ b/src/vs/base/worker/workerMain.ts @@ -5,7 +5,7 @@ (function () { - const MonacoEnvironment = (self).MonacoEnvironment; + const MonacoEnvironment = (globalThis).MonacoEnvironment; const monacoBaseUrl = MonacoEnvironment && MonacoEnvironment.baseUrl ? MonacoEnvironment.baseUrl : '../../../'; const trustedTypesPolicy = ( @@ -29,10 +29,10 @@ try { const func = ( trustedTypesPolicy - ? self.eval(trustedTypesPolicy.createScript('', 'true')) + ? globalThis.eval(trustedTypesPolicy.createScript('', 'true')) : new Function('true') ); - func.call(self); + func.call(globalThis); return true; } catch (err) { return false; @@ -41,12 +41,12 @@ function loadAMDLoader() { return new Promise((resolve, reject) => { - if (typeof (self).define === 'function' && (self).define.amd) { + if (typeof (globalThis).define === 'function' && (globalThis).define.amd) { return resolve(); } const loaderSrc: string | TrustedScriptURL = monacoBaseUrl + 'vs/loader.js'; - const isCrossOrigin = (/^((http:)|(https:)|(file:))/.test(loaderSrc) && loaderSrc.substring(0, self.origin.length) !== self.origin); + const isCrossOrigin = (/^((http:)|(https:)|(file:))/.test(loaderSrc) && loaderSrc.substring(0, globalThis.origin.length) !== globalThis.origin); if (!isCrossOrigin && canUseEval()) { // use `fetch` if possible because `importScripts` // is synchronous and can lead to deadlocks on Safari @@ -59,10 +59,10 @@ text = `${text}\n//# sourceURL=${loaderSrc}`; const func = ( trustedTypesPolicy - ? self.eval(trustedTypesPolicy.createScript('', text) as unknown as string) + ? globalThis.eval(trustedTypesPolicy.createScript('', text) as unknown as string) : new Function(text) ); - func.call(self); + func.call(globalThis); resolve(); }).then(undefined, reject); return; @@ -92,12 +92,13 @@ require([moduleId], function (ws) { setTimeout(function () { const messageHandler = ws.create((msg: any, transfer?: Transferable[]) => { - (self).postMessage(msg, transfer); + (globalThis).postMessage(msg, transfer); }, null); - self.onmessage = (e: MessageEvent) => messageHandler.onmessage(e.data, e.ports); + globalThis.onmessage = (e: MessageEvent) => messageHandler.onmessage(e.data, e.ports); while (beforeReadyMessages.length > 0) { - self.onmessage(beforeReadyMessages.shift()!); + const e = beforeReadyMessages.shift()!; + messageHandler.onmessage(e.data, e.ports); } }, 0); }); @@ -107,13 +108,13 @@ // If the loader is already defined, configure it immediately // This helps in the bundled case, where we must load nls files // and they need a correct baseUrl to be loaded. - if (typeof (self).define === 'function' && (self).define.amd) { + if (typeof (globalThis).define === 'function' && (globalThis).define.amd) { configureAMDLoader(); } let isFirstMessage = true; const beforeReadyMessages: MessageEvent[] = []; - self.onmessage = (message: MessageEvent) => { + globalThis.onmessage = (message: MessageEvent) => { if (!isFirstMessage) { beforeReadyMessages.push(message); return; diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 23c44b398cc..4ed13d3ca3e 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -115,6 +115,7 @@ import { IInitialProtocolUrls, IProtocolUrl } from 'vs/platform/url/electron-mai import { massageMessageBoxOptions } from 'vs/platform/dialogs/common/dialogs'; import { IUtilityProcessWorkerMainService, UtilityProcessWorkerMainService } from 'vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService'; import { ipcUtilityProcessWorkerChannelName } from 'vs/platform/utilityProcess/common/utilityProcessWorkerService'; +import { firstOrDefault } from 'vs/base/common/arrays'; /** * The main VS Code application. There will only ever be one instance, @@ -529,7 +530,7 @@ export class CodeApplication extends Disposable { // Resolve unique machine ID this.logService.trace('Resolving machine identifier...'); - const machineId = await resolveMachineId(this.stateService); + const machineId = await resolveMachineId(this.stateService, this.logService); this.logService.trace(`Resolved machine identifier: ${machineId}`); // Shared process @@ -667,7 +668,7 @@ export class CodeApplication extends Disposable { private shouldBlockURI(uri: URI): boolean { if (uri.authority === Schemas.file && isWindows) { const { options, buttonIndeces } = massageMessageBoxOptions({ - type: 'question', + type: 'warning', buttons: [ localize({ key: 'open', comment: ['&& denotes a mnemonic'] }, "&&Yes"), localize({ key: 'cancel', comment: ['&& denotes a mnemonic'] }, "&&No") @@ -785,16 +786,16 @@ export class CodeApplication extends Disposable { if (windowOpenableFromProtocolUrl) { this.logService.trace('app#handleProtocolUrl() opening protocol url as window:', windowOpenableFromProtocolUrl, uri.toString(true)); - const [window] = await windowsMainService.open({ + const window = firstOrDefault(await windowsMainService.open({ context: OpenContext.API, cli: { ...this.environmentMainService.args }, urisToOpen: [windowOpenableFromProtocolUrl], forceNewWindow: shouldOpenInNewWindow, gotoLineMode: true // remoteAuthority: will be determined based on windowOpenableFromProtocolUrl - }); + })); - window.focus(); // this should help ensuring that the right window gets focus when multiple are opened + window?.focus(); // this should help ensuring that the right window gets focus when multiple are opened return true; } @@ -803,16 +804,16 @@ export class CodeApplication extends Disposable { if (shouldOpenInNewWindow) { this.logService.trace('app#handleProtocolUrl() opening empty window and passing in protocol url:', uri.toString(true)); - const [window] = await windowsMainService.open({ + const window = firstOrDefault(await windowsMainService.open({ context: OpenContext.API, cli: { ...this.environmentMainService.args }, forceNewWindow: true, forceEmpty: true, gotoLineMode: true, remoteAuthority: getRemoteAuthority(uri) - }); + })); - await window.ready(); + await window?.ready(); return urlService.open(uri, options); } @@ -938,7 +939,7 @@ export class CodeApplication extends Disposable { const isInternal = isInternalTelemetry(this.productService, this.configurationService); const channel = getDelayedChannel(sharedProcessReady.then(client => client.getChannel('telemetryAppender'))); const appender = new TelemetryAppenderClient(channel); - const commonProperties = resolveCommonProperties(this.fileService, release(), hostname(), process.arch, this.productService.commit, this.productService.version, machineId, isInternal, this.environmentMainService.installSourcePath); + const commonProperties = resolveCommonProperties(release(), hostname(), process.arch, this.productService.commit, this.productService.version, machineId, isInternal); const piiPaths = getPiiPathsFromEnvironment(this.environmentMainService); const config: ITelemetryServiceConfig = { appenders: [appender], commonProperties, piiPaths, sendErrorTelemetry: true }; @@ -1195,7 +1196,6 @@ export class CodeApplication extends Disposable { private afterWindowOpen(accessor: ServicesAccessor, sharedProcess: SharedProcess): void { const telemetryService = accessor.get(ITelemetryService); - const updateService = accessor.get(IUpdateService); // Observe shared process for errors this.handleSharedProcessErrors(telemetryService, sharedProcess); @@ -1211,11 +1211,6 @@ export class CodeApplication extends Disposable { }); }); - // Initialize update service - if (updateService instanceof Win32UpdateService || updateService instanceof LinuxUpdateService || updateService instanceof DarwinUpdateService) { - updateService.initialize(); - } - // Start to fetch shell environment (if needed) after window has opened // Since this operation can take a long time, we want to warm it up while // the window is opening. @@ -1248,13 +1243,13 @@ export class CodeApplication extends Disposable { // Logging switch (type) { case WindowError.PROCESS_GONE: - this.logService.error(`SharedProcess: renderer process gone (reason: ${details?.reason || ''}, code: ${details?.exitCode || ''})`); + this.logService.error(`[SharedProcess] renderer process gone (reason: ${details?.reason || ''}, code: ${details?.exitCode || ''})`); break; case WindowError.UNRESPONSIVE: - this.logService.error('SharedProcess: detected unresponsive'); + this.logService.error('[SharedProcess] detected unresponsive'); break; case WindowError.LOAD: - this.logService.error(`SharedProcess: failed to load (reason: ${details?.reason || ''}, code: ${details?.exitCode || ''})`); + this.logService.error(`[SharedProcess] failed to load (reason: ${details?.reason || ''}, code: ${details?.exitCode || ''})`); break; } diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 67affd19f69..eba79c0656b 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -16,7 +16,7 @@ import { IPathWithLineAndColumn, isValidBasename, parseLineAndColumnAware, sanit import { once } from 'vs/base/common/functional'; import { getPathLabel } from 'vs/base/common/labels'; import { Schemas } from 'vs/base/common/network'; -import { basename, join, resolve } from 'vs/base/common/path'; +import { basename, resolve } from 'vs/base/common/path'; import { mark } from 'vs/base/common/performance'; import { IProcessEnvironment, isMacintosh, isWindows, OS } from 'vs/base/common/platform'; import { cwd } from 'vs/base/common/process'; @@ -131,7 +131,7 @@ class CodeMain { }); // Delay creation of spdlog for perf reasons (https://github.com/microsoft/vscode/issues/72906) - bufferLogService.logger = loggerService.createLogger(URI.file(join(environmentMainService.logsPath, 'main.log')), { id: 'mainLog', name: localize('mainLog', "Main") }); + bufferLogService.logger = loggerService.createLogger('main', { name: localize('mainLog', "Main") }); // Lifecycle once(lifecycleMainService.onWillShutdown)(evt => { @@ -162,7 +162,7 @@ class CodeMain { services.set(IEnvironmentMainService, environmentMainService); // Logger - const loggerService = new LoggerMainService(getLogLevel(environmentMainService)); + const loggerService = new LoggerMainService(getLogLevel(environmentMainService), environmentMainService.logsHome); services.set(ILoggerMainService, loggerService); // Log: We need to buffer the spdlog logs until we are sure @@ -246,7 +246,7 @@ class CodeMain { Promise.all([ environmentMainService.extensionsPath, environmentMainService.codeCachePath, - environmentMainService.logsPath, + environmentMainService.logsHome.fsPath, userDataProfilesMainService.defaultProfile.globalStorageHome.fsPath, environmentMainService.workspaceStorageHome.fsPath, environmentMainService.localHistoryHome.fsPath, @@ -382,7 +382,7 @@ class CodeMain { // Print --status usage info if (environmentMainService.args.status) { - logService.warn(`Warning: The --status argument can only be used if ${productService.nameShort} is already running. Please run it again after {0} has started.`); + logService.warn('Warning: The --status argument can only be used if {0} is already running. Please run it again after {0} has started.', productService.nameShort); throw new ExpectedError('Terminating...'); } diff --git a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts index 8936cda23bd..a7687cdc47f 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts @@ -23,7 +23,7 @@ import { isRemoteDiagnosticError, SystemInfo } from 'vs/platform/diagnostics/com import { ElectronIPCMainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService'; import { IssueReporterData, IssueReporterExtensionData, IssueReporterStyles, IssueReporterWindowConfiguration, IssueType } from 'vs/platform/issue/common/issue'; import { normalizeGitHubUrl } from 'vs/platform/issue/common/issueReporterUtil'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { NativeHostService } from 'vs/platform/native/electron-sandbox/nativeHostService'; import { applyZoom, zoomIn, zoomOut } from 'vs/platform/window/electron-sandbox/window'; diff --git a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts index 67d48b47d23..19763e979f1 100644 --- a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts @@ -19,7 +19,7 @@ import { IRemoteDiagnosticError, isRemoteDiagnosticError } from 'vs/platform/dia import { ByteSize } from 'vs/platform/files/common/files'; import { ElectronIPCMainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService'; import { ProcessExplorerData, ProcessExplorerStyles, ProcessExplorerWindowConfiguration } from 'vs/platform/issue/common/issue'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { NativeHostService } from 'vs/platform/native/electron-sandbox/nativeHostService'; import { getIconsStyleSheet } from 'vs/platform/theme/browser/iconsStyleSheet'; import { applyZoom, zoomIn, zoomOut } from 'vs/platform/window/electron-sandbox/window'; @@ -163,7 +163,7 @@ class ErrorRenderer implements ITreeRenderer { - constructor(private platform: string, private totalMem: number, private mapPidToWindowTitle: Map) { } + constructor(private platform: string, private totalMem: number, private mapPidToName: Map) { } templateId: string = 'process'; renderTemplate(container: HTMLElement): IProcessItemTemplateData { @@ -179,13 +179,13 @@ class ProcessRenderer implements ITreeRenderer, index: number, templateData: IProcessItemTemplateData, height: number | undefined): void { const { element } = node; - let name = element.name; - if (name === 'window') { - const windowTitle = this.mapPidToWindowTitle.get(element.pid); - name = windowTitle !== undefined ? `${name} (${this.mapPidToWindowTitle.get(element.pid)})` : name; - } const pid = element.pid.toFixed(0); + let name = element.name; + if (this.mapPidToName.has(element.pid)) { + name = this.mapPidToName.get(element.pid)!; + } + templateData.name.textContent = name; templateData.name.title = element.cmd; @@ -230,7 +230,7 @@ function isProcessItem(item: any): item is ProcessItem { class ProcessExplorer { private lastRequestTime: number; - private mapPidToWindowTitle = new Map(); + private mapPidToName = new Map(); private nativeHostService: INativeHostService; @@ -243,10 +243,12 @@ class ProcessExplorer { this.applyStyles(data.styles); this.setEventHandlers(data); - // Map window process pids to titles, annotate process names with this when rendering to distinguish between them - ipcRenderer.on('vscode:windowsInfoResponse', (event: unknown, windows: any[]) => { - this.mapPidToWindowTitle = new Map(); - windows.forEach(window => this.mapPidToWindowTitle.set(window.pid, window.title)); + ipcRenderer.on('vscode:pidToNameResponse', (event: unknown, pidToNames: [number, string][]) => { + this.mapPidToName = new Map(); + + for (const [pid, name] of pidToNames) { + this.mapPidToName.set(pid, name); + } }); ipcRenderer.on('vscode:listProcessesResponse', async (event: unknown, processRoots: MachineProcessInformation[]) => { @@ -267,7 +269,7 @@ class ProcessExplorer { }); this.lastRequestTime = Date.now(); - ipcRenderer.send('vscode:windowsInfoRequest'); + ipcRenderer.send('vscode:pidToNameRequest'); ipcRenderer.send('vscode:listProcesses'); } @@ -304,7 +306,7 @@ class ProcessExplorer { const { totalmem } = await this.nativeHostService.getOSStatistics(); const renderers = [ - new ProcessRenderer(this.data.platform, totalmem, this.mapPidToWindowTitle), + new ProcessRenderer(this.data.platform, totalmem, this.mapPidToName), new ProcessHeaderTreeRenderer(), new MachineRenderer(), new ErrorRenderer() @@ -484,6 +486,7 @@ class ProcessExplorer { if (isLocal) { items.push({ + accelerator: 'Alt+E', label: localize('killProcess', "Kill Process"), click: () => { this.nativeHostService.killProcess(pid, 'SIGTERM'); @@ -555,7 +558,7 @@ class ProcessExplorer { // Wait at least a second between requests. if (waited > 1000) { - ipcRenderer.send('vscode:windowsInfoRequest'); + ipcRenderer.send('vscode:pidToNameRequest'); ipcRenderer.send('vscode:listProcesses'); } else { this.requestProcessList(waited); diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index b2ef0aa70fa..01f5c343bc6 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -25,6 +25,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { randomPath } from 'vs/base/common/extpath'; import { Utils } from 'vs/platform/profiling/common/profiling'; import { FileAccess } from 'vs/base/common/network'; +import { cwd } from 'vs/base/common/process'; function shouldSpawnCliProcess(argv: NativeParsedArgs): boolean { return !!argv['install-source'] @@ -54,18 +55,18 @@ export async function main(argv: string[]): Promise { 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: ChildProcessWithoutNullStreams; if (process.env['VSCODE_DEV']) { - tunnelProcess = spawn('cargo', ['run', '--', 'tunnel', ...argv.slice(5)], { cwd: join(getAppRoot(), 'cli') }); + tunnelProcess = spawn('cargo', ['run', '--', 'tunnel', ...tunnelArgs], { cwd: join(getAppRoot(), 'cli') }); } 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' : ''}`); - const tunnelArgs = argv.slice(3); - tunnelProcess = spawn(tunnelCommand, ['tunnel', ...tunnelArgs]); + tunnelProcess = spawn(tunnelCommand, ['tunnel', ...tunnelArgs], { cwd: cwd() }); } tunnelProcess.stdout.pipe(process.stdout); diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index dff743e9eac..73268f714f7 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -5,7 +5,6 @@ import { hostname, release } from 'os'; import { raceTimeout } from 'vs/base/common/async'; -import { VSBuffer } from 'vs/base/common/buffer'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { isSigPipeError, onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -39,8 +38,7 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; import { NativeLanguagePackService } from 'vs/platform/languagePacks/node/languagePacks'; -import { ConsoleLogger, getLogLevel, ILogger, ILogService, LogLevel } from 'vs/platform/log/common/log'; -import { SpdLogLogger } from 'vs/platform/log/node/spdlogLog'; +import { ConsoleLogger, getLogLevel, ILogger, ILoggerService, ILogService, LogLevel } from 'vs/platform/log/common/log'; import { FilePolicyService } from 'vs/platform/policy/common/filePolicyService'; import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; import { NativePolicyService } from 'vs/platform/policy/node/nativePolicyService'; @@ -62,6 +60,8 @@ import { UserDataProfilesReadonlyService } from 'vs/platform/userDataProfile/nod import { resolveMachineId } from 'vs/platform/telemetry/node/telemetryUtils'; import { ExtensionsProfileScannerService } from 'vs/platform/extensionManagement/node/extensionsProfileScannerService'; import { LogService } from 'vs/platform/log/common/logService'; +import { LoggerService } from 'vs/platform/log/node/loggerService'; +import { localize } from 'vs/nls'; class CliMain extends Disposable { @@ -124,15 +124,18 @@ class CliMain extends Disposable { environmentService.extensionsPath ].map(path => path ? Promises.mkdir(path, { recursive: true }) : undefined)); + // Logger + const loggerService = new LoggerService(getLogLevel(environmentService), environmentService.logsHome); + services.set(ILoggerService, loggerService); + // Log - const logLevel = getLogLevel(environmentService); - const spdLogLogger = new SpdLogLogger('cli', join(environmentService.logsPath, 'cli.log'), true, false, logLevel); + const logger = this._register(loggerService.createLogger('cli', { name: localize('cli', "CLI") })); const otherLoggers: ILogger[] = []; - if (logLevel === LogLevel.Trace) { - otherLoggers.push(new ConsoleLogger(logLevel)); + if (loggerService.getLogLevel() === LogLevel.Trace) { + otherLoggers.push(new ConsoleLogger(loggerService.getLogLevel())); } - const logService = this._register(new LogService(spdLogLogger, otherLoggers)); + const logService = this._register(new LogService(logger, otherLoggers)); services.set(ILogService, logService); // Files @@ -142,8 +145,6 @@ class CliMain extends Disposable { const diskFileSystemProvider = this._register(new DiskFileSystemProvider(logService)); fileService.registerProvider(Schemas.file, diskFileSystemProvider); - // State - // Uri Identity const uriIdentityService = new UriIdentityService(fileService); services.set(IUriIdentityService, uriIdentityService); @@ -169,6 +170,16 @@ class CliMain extends Disposable { configurationService.initialize() ]); + // Get machine ID + let machineId: string | undefined = undefined; + try { + machineId = await resolveMachineId(stateService, logService); + } catch (error) { + if (error.code !== 'ENOENT') { + logService.error(error); + } + } + // Initialize user data profiles after initializing the state userDataProfilesService.init(); @@ -199,23 +210,10 @@ class CliMain extends Disposable { appenders.push(new OneDataSystemAppender(isInternal, 'monacoworkbench', null, productService.aiConfig.ariaKey)); } - const { installSourcePath } = environmentService; - const config: ITelemetryServiceConfig = { appenders, sendErrorTelemetry: false, - commonProperties: (async () => { - let machineId: string | undefined = undefined; - try { - machineId = await resolveMachineId(stateService); - } catch (error) { - if (error.code !== 'ENOENT') { - logService.error(error); - } - } - - return resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version, machineId, isInternal, installSourcePath); - })(), + commonProperties: resolveCommonProperties(release(), hostname(), process.arch, productService.commit, productService.version, machineId, isInternal), piiPaths: getPiiPathsFromEnvironment(environmentService) }; @@ -259,30 +257,25 @@ class CliMain extends Disposable { } const profileLocation = (profile ?? userDataProfilesService.defaultProfile).extensionsResource; - // Install Source - if (this.argv['install-source']) { - return this.setInstallSource(environmentService, fileService, this.argv['install-source']); - } - // List Extensions if (this.argv['list-extensions']) { - return instantiationService.createInstance(ExtensionManagementCLI).listExtensions(!!this.argv['show-versions'], this.argv['category'], profileLocation); + return instantiationService.createInstance(ExtensionManagementCLI, new ConsoleLogger(LogLevel.Info, false)).listExtensions(!!this.argv['show-versions'], this.argv['category'], profileLocation); } // Install Extension else if (this.argv['install-extension'] || this.argv['install-builtin-extension']) { const installOptions: InstallOptions = { isMachineScoped: !!this.argv['do-not-sync'], installPreReleaseVersion: !!this.argv['pre-release'], profileLocation }; - return instantiationService.createInstance(ExtensionManagementCLI).installExtensions(this.asExtensionIdOrVSIX(this.argv['install-extension'] || []), this.argv['install-builtin-extension'] || [], installOptions, !!this.argv['force']); + return instantiationService.createInstance(ExtensionManagementCLI, new ConsoleLogger(LogLevel.Info, false)).installExtensions(this.asExtensionIdOrVSIX(this.argv['install-extension'] || []), this.asExtensionIdOrVSIX(this.argv['install-builtin-extension'] || []), installOptions, !!this.argv['force']); } // Uninstall Extension else if (this.argv['uninstall-extension']) { - return instantiationService.createInstance(ExtensionManagementCLI).uninstallExtensions(this.asExtensionIdOrVSIX(this.argv['uninstall-extension']), !!this.argv['force'], profileLocation); + return instantiationService.createInstance(ExtensionManagementCLI, new ConsoleLogger(LogLevel.Info, false)).uninstallExtensions(this.asExtensionIdOrVSIX(this.argv['uninstall-extension']), !!this.argv['force'], profileLocation); } // Locate Extension else if (this.argv['locate-extension']) { - return instantiationService.createInstance(ExtensionManagementCLI).locateExtension(this.argv['locate-extension']); + return instantiationService.createInstance(ExtensionManagementCLI, new ConsoleLogger(LogLevel.Info, false)).locateExtension(this.argv['locate-extension']); } // Telemetry @@ -294,10 +287,6 @@ class CliMain extends Disposable { private asExtensionIdOrVSIX(inputs: string[]): (string | URI)[] { return inputs.map(input => /\.vsix$/i.test(input) ? URI.file(isAbsolute(input) ? input : join(cwd(), input)) : input); } - - private async setInstallSource(environmentService: INativeEnvironmentService, fileService: IFileService, installSource: string): Promise { - await fileService.writeFile(URI.file(environmentService.installSourcePath), VSBuffer.fromString(installSource.slice(0, 30))); - } } export async function main(argv: NativeParsedArgs): Promise { diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/codeCacheCleaner.ts b/src/vs/code/node/sharedProcess/contrib/codeCacheCleaner.ts similarity index 100% rename from src/vs/code/electron-browser/sharedProcess/contrib/codeCacheCleaner.ts rename to src/vs/code/node/sharedProcess/contrib/codeCacheCleaner.ts diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/extensions.ts b/src/vs/code/node/sharedProcess/contrib/extensions.ts similarity index 100% rename from src/vs/code/electron-browser/sharedProcess/contrib/extensions.ts rename to src/vs/code/node/sharedProcess/contrib/extensions.ts diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts b/src/vs/code/node/sharedProcess/contrib/languagePackCachedDataCleaner.ts similarity index 100% rename from src/vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts rename to src/vs/code/node/sharedProcess/contrib/languagePackCachedDataCleaner.ts diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/localizationsUpdater.ts b/src/vs/code/node/sharedProcess/contrib/localizationsUpdater.ts similarity index 100% rename from src/vs/code/electron-browser/sharedProcess/contrib/localizationsUpdater.ts rename to src/vs/code/node/sharedProcess/contrib/localizationsUpdater.ts diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner.ts b/src/vs/code/node/sharedProcess/contrib/logsDataCleaner.ts similarity index 84% rename from src/vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner.ts rename to src/vs/code/node/sharedProcess/contrib/logsDataCleaner.ts index 7276fa3281d..ab5f8a1d87a 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner.ts +++ b/src/vs/code/node/sharedProcess/contrib/logsDataCleaner.ts @@ -6,7 +6,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Disposable } from 'vs/base/common/lifecycle'; -import { basename, dirname, join } from 'vs/base/common/path'; +import { basename, dirname, joinPath } from 'vs/base/common/resources'; import { Promises } from 'vs/base/node/pfs'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ILogService } from 'vs/platform/log/common/log'; @@ -29,10 +29,10 @@ export class LogsDataCleaner extends Disposable { this.logService.trace('[logs cleanup]: Starting to clean up old logs.'); try { - const currentLog = basename(this.environmentService.logsPath); - const logsRoot = dirname(this.environmentService.logsPath); + const currentLog = basename(this.environmentService.logsHome); + const logsRoot = dirname(this.environmentService.logsHome); - const logFiles = await Promises.readdir(logsRoot); + const logFiles = await Promises.readdir(logsRoot.fsPath); const allSessions = logFiles.filter(logFile => /^\d{8}T\d{6}$/.test(logFile)); const oldSessions = allSessions.sort().filter(session => session !== currentLog); @@ -41,7 +41,7 @@ export class LogsDataCleaner extends Disposable { if (sessionsToDelete.length > 0) { this.logService.trace(`[logs cleanup]: Removing log folders '${sessionsToDelete.join(', ')}'`); - await Promise.all(sessionsToDelete.map(sessionToDelete => Promises.rm(join(logsRoot, sessionToDelete)))); + await Promise.all(sessionsToDelete.map(sessionToDelete => Promises.rm(joinPath(logsRoot, sessionToDelete).fsPath))); } } catch (error) { onUnexpectedError(error); diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts b/src/vs/code/node/sharedProcess/contrib/storageDataCleaner.ts similarity index 95% rename from src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts rename to src/vs/code/node/sharedProcess/contrib/storageDataCleaner.ts index 1f55a52057a..fc3f2eb117a 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts +++ b/src/vs/code/node/sharedProcess/contrib/storageDataCleaner.ts @@ -9,12 +9,12 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { join } from 'vs/base/common/path'; import { Promises } from 'vs/base/node/pfs'; import { INativeEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; import { ILogService } from 'vs/platform/log/common/log'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; import { StorageClient } from 'vs/platform/storage/common/storageIpc'; import { EXTENSION_DEVELOPMENT_EMPTY_WINDOW_WORKSPACE } from 'vs/platform/workspace/common/workspace'; import { NON_EMPTY_WORKSPACE_ID_LENGTH } from 'vs/platform/workspaces/node/workspaces'; +import { INativeHostService } from 'vs/platform/native/common/native'; +import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService'; export class UnusedWorkspaceStorageDataCleaner extends Disposable { diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/userDataProfilesCleaner.ts b/src/vs/code/node/sharedProcess/contrib/userDataProfilesCleaner.ts similarity index 100% rename from src/vs/code/electron-browser/sharedProcess/contrib/userDataProfilesCleaner.ts rename to src/vs/code/node/sharedProcess/contrib/userDataProfilesCleaner.ts diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcess-dev.html b/src/vs/code/node/sharedProcess/sharedProcess-dev.html similarity index 100% rename from src/vs/code/electron-browser/sharedProcess/sharedProcess-dev.html rename to src/vs/code/node/sharedProcess/sharedProcess-dev.html diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcess.html b/src/vs/code/node/sharedProcess/sharedProcess.html similarity index 100% rename from src/vs/code/electron-browser/sharedProcess/sharedProcess.html rename to src/vs/code/node/sharedProcess/sharedProcess.html diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcess.js b/src/vs/code/node/sharedProcess/sharedProcess.js similarity index 91% rename from src/vs/code/electron-browser/sharedProcess/sharedProcess.js rename to src/vs/code/node/sharedProcess/sharedProcess.js index 1383bc8331e..dfb0cefbede 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcess.js +++ b/src/vs/code/node/sharedProcess/sharedProcess.js @@ -10,7 +10,7 @@ const bootstrapWindow = bootstrapWindowLib(); // Load shared process into window - bootstrapWindow.load(['vs/code/electron-browser/sharedProcess/sharedProcessMain'], function (sharedProcess, configuration) { + bootstrapWindow.load(['vs/code/node/sharedProcess/sharedProcessMain'], function (sharedProcess, configuration) { return sharedProcess.main(configuration); }, { diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/node/sharedProcess/sharedProcessMain.ts similarity index 90% rename from src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts rename to src/vs/code/node/sharedProcess/sharedProcessMain.ts index 486db15af16..cd4ebe3db1f 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/node/sharedProcess/sharedProcessMain.ts @@ -3,21 +3,25 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +/* eslint-disable local/code-layering, local/code-import-patterns */ +// TODO@bpasero remove these once utility process is the only way +import { Server as BrowserWindowMessagePortServer } from 'vs/base/parts/ipc/electron-browser/ipc.mp'; +import { SharedProcessWorkerService } from 'vs/platform/sharedProcess/electron-browser/sharedProcessWorkerService'; +import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal'; + import { hostname, release } from 'os'; 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 { joinPath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { IPCServer, ProxyChannel, StaticRouter } from 'vs/base/parts/ipc/common/ipc'; -import { Server as BrowserWindowMessagePortServer } from 'vs/base/parts/ipc/electron-browser/ipc.mp'; import { Server as UtilityProcessMessagePortServer, once } from 'vs/base/parts/ipc/node/ipc.mp'; -import { CodeCacheCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/codeCacheCleaner'; -import { LanguagePackCachedDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner'; -import { LocalizationsUpdater } from 'vs/code/electron-browser/sharedProcess/contrib/localizationsUpdater'; -import { LogsDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner'; -import { UnusedWorkspaceStorageDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner'; +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'; +import { LogsDataCleaner } from 'vs/code/node/sharedProcess/contrib/logsDataCleaner'; +import { UnusedWorkspaceStorageDataCleaner } from 'vs/code/node/sharedProcess/contrib/storageDataCleaner'; import { IChecksumService } from 'vs/platform/checksum/common/checksumService'; import { ChecksumService } from 'vs/platform/checksum/node/checksumService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -33,10 +37,8 @@ import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/ import { IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionSignatureVerificationService, IExtensionSignatureVerificationService } from 'vs/platform/extensionManagement/node/extensionSignatureVerificationService'; import { ExtensionManagementChannel, ExtensionTipsChannel } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; -import { ExtensionTipsService } from 'vs/platform/extensionManagement/electron-sandbox/extensionTipsService'; import { ExtensionManagementService, INativeServerExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { IExtensionRecommendationNotificationService } from 'vs/platform/extensionRecommendations/common/extensionRecommendations'; -import { ExtensionRecommendationNotificationServiceChannelClient } from 'vs/platform/extensionRecommendations/electron-sandbox/extensionRecommendationsIpc'; import { IFileService } from 'vs/platform/files/common/files'; import { FileService } from 'vs/platform/files/common/fileService'; import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; @@ -44,19 +46,15 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { MessagePortMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; -import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; import { NativeLanguagePackService } from 'vs/platform/languagePacks/node/languagePacks'; import { ConsoleLogger, ILoggerService, ILogService } from 'vs/platform/log/common/log'; import { LoggerChannelClient } from 'vs/platform/log/common/logIpc'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; import product from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/productService'; import { IRequestService } from 'vs/platform/request/common/request'; import { ISharedProcessConfiguration } from 'vs/platform/sharedProcess/node/sharedProcess'; import { IStorageService } from 'vs/platform/storage/common/storage'; -import { NativeStorageService } from 'vs/platform/storage/electron-sandbox/storageService'; import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties'; import { ICustomEndpointTelemetryService, ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc'; @@ -65,7 +63,6 @@ import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService' import { supportsTelemetry, ITelemetryAppender, NullAppender, NullTelemetryService, getPiiPathsFromEnvironment, isInternalTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; import { CustomEndpointTelemetryService } from 'vs/platform/telemetry/node/customEndpointTelemetryService'; import { LocalReconnectConstants, TerminalIpcChannels, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; -import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal'; import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService'; import { ExtensionStorageService, IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage'; import { IgnoredExtensionsManagementService, IIgnoredExtensionsManagementService } from 'vs/platform/userDataSync/common/ignoredExtensions'; @@ -79,9 +76,8 @@ import { UserDataSyncEnablementService } from 'vs/platform/userDataSync/common/u import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService'; import { UserDataSyncChannel } from 'vs/platform/userDataSync/common/userDataSyncServiceIpc'; import { UserDataSyncStoreManagementService, UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; -import { UserDataAutoSyncService } from 'vs/platform/userDataSync/electron-sandbox/userDataAutoSyncService'; -import { UserDataProfileStorageService } from 'vs/platform/userDataProfile/electron-sandbox/userDataProfileStorageService'; import { IUserDataProfileStorageService } from 'vs/platform/userDataProfile/common/userDataProfileStorageService'; +import { NativeUserDataProfileStorageService } from 'vs/platform/userDataProfile/node/userDataProfileStorageService'; import { ActiveWindowManager } from 'vs/platform/windows/node/windowTracker'; import { ISignService } from 'vs/platform/sign/common/sign'; import { SignService } from 'vs/platform/sign/node/signService'; @@ -90,7 +86,6 @@ import { SharedTunnelsService } from 'vs/platform/tunnel/node/tunnelService'; import { ipcSharedProcessTunnelChannelName, ISharedProcessTunnelService } from 'vs/platform/remote/common/sharedProcessTunnelService'; import { SharedProcessTunnelService } from 'vs/platform/tunnel/node/sharedProcessTunnelService'; import { ISharedProcessWorkerService } from 'vs/platform/sharedProcess/common/sharedProcessWorkerService'; -import { SharedProcessWorkerService } from 'vs/platform/sharedProcess/electron-browser/sharedProcessWorkerService'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { isLinux } from 'vs/base/common/platform'; @@ -105,19 +100,25 @@ import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagemen import { PolicyChannelClient } from 'vs/platform/policy/common/policyIpc'; import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; import { UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfileIpc'; -import { SharedProcessRequestService } from 'vs/platform/request/electron-browser/sharedProcessRequestService'; import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; -import { UserDataProfilesCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/userDataProfilesCleaner'; -import { RemoteTunnelService } from 'vs/platform/remoteTunnel/electron-browser/remoteTunnelService'; +import { UserDataProfilesCleaner } from 'vs/code/node/sharedProcess/contrib/userDataProfilesCleaner'; import { IRemoteTunnelService } from 'vs/platform/remoteTunnel/common/remoteTunnel'; -import { ISharedProcessLifecycleService, SharedProcessLifecycleService } from 'vs/platform/lifecycle/electron-browser/sharedProcessLifecycleService'; import { UserDataSyncResourceProviderService } from 'vs/platform/userDataSync/common/userDataSyncResourceProvider'; -import { ExtensionsContributions } from 'vs/code/electron-browser/sharedProcess/contrib/extensions'; -import { ExtensionsProfileScannerService } from 'vs/platform/extensionManagement/electron-sandbox/extensionsProfileScannerService'; +import { ExtensionsContributions } from 'vs/code/node/sharedProcess/contrib/extensions'; import { localize } from 'vs/nls'; import { LogService } from 'vs/platform/log/common/logService'; import { ipcUtilityProcessWorkerChannelName, IUtilityProcessWorkerConfiguration } from 'vs/platform/utilityProcess/common/utilityProcessWorkerService'; import { isUtilityProcess } from 'vs/base/parts/sandbox/node/electronTypes'; +import { ISharedProcessLifecycleService, SharedProcessLifecycleService } from 'vs/platform/lifecycle/node/sharedProcessLifecycleService'; +import { RemoteTunnelService } from 'vs/platform/remoteTunnel/node/remoteTunnelService'; +import { ExtensionsProfileScannerService } from 'vs/platform/extensionManagement/node/extensionsProfileScannerService'; +import { RequestChannelClient } from 'vs/platform/request/common/requestIpc'; +import { ExtensionRecommendationNotificationServiceChannelClient } from 'vs/platform/extensionRecommendations/common/extensionRecommendationsIpc'; +import { INativeHostService } from 'vs/platform/native/common/native'; +import { UserDataAutoSyncService } from 'vs/platform/userDataSync/node/userDataAutoSyncService'; +import { ExtensionTipsService } from 'vs/platform/extensionManagement/node/extensionTipsService'; +import { IMainProcessService, MainProcessService } from 'vs/platform/ipc/common/mainProcessService'; +import { RemoteStorageService } from 'vs/platform/storage/common/storageService'; class SharedProcessMain extends Disposable { @@ -142,9 +143,14 @@ class SharedProcessMain extends Disposable { private registerListeners(): void { // Shared process lifecycle - const onExit = async () => { - this.lifecycleService?.fireOnWillShutdown(); - this.dispose(); + let didExit = false; + const onExit = () => { + if (!didExit) { + didExit = true; + + this.lifecycleService?.fireOnWillShutdown(); + this.dispose(); + } }; process.once('exit', onExit); if (isUtilityProcess(process)) { @@ -214,7 +220,7 @@ class SharedProcessMain extends Disposable { // Main Process const mainRouter = new StaticRouter(ctx => ctx === 'main'); - const mainProcessService = new MessagePortMainProcessService(this.server, mainRouter); + const mainProcessService = new MainProcessService(this.server, mainRouter); services.set(IMainProcessService, mainProcessService); // Policies @@ -226,11 +232,11 @@ class SharedProcessMain extends Disposable { services.set(INativeEnvironmentService, environmentService); // Logger - const loggerService = new LoggerChannelClient(undefined, this.configuration.logLevel, this.configuration.loggers.map(loggerResource => ({ ...loggerResource, resource: URI.revive(loggerResource.resource) })), mainProcessService.getChannel('logger')); + const loggerService = new LoggerChannelClient(undefined, this.configuration.logLevel, environmentService.logsHome, this.configuration.loggers.map(loggerResource => ({ ...loggerResource, resource: URI.revive(loggerResource.resource) })), mainProcessService.getChannel('logger')); services.set(ILoggerService, loggerService); // Log - const logger = this._register(loggerService.createLogger(joinPath(URI.file(environmentService.logsPath), 'sharedprocess.log'), { id: 'sharedLog', name: localize('sharedLog', "Shared") })); + const logger = this._register(loggerService.createLogger('sharedprocess', { name: localize('sharedLog', "Shared") })); const consoleLogger = this._register(new ConsoleLogger(logger.getLevel())); const logService = this._register(new LogService(logger, [consoleLogger])); services.set(ILogService, logService); @@ -263,7 +269,7 @@ class SharedProcessMain extends Disposable { fileService.registerProvider(Schemas.vscodeUserData, userDataFileSystemProvider); // User Data Profiles - const userDataProfilesService = this._register(new UserDataProfilesService(this.configuration.profiles.all, URI.revive(this.configuration.profiles.home), mainProcessService.getChannel('userDataProfiles'))); + const userDataProfilesService = this._register(new UserDataProfilesService(this.configuration.profiles.all, URI.revive(this.configuration.profiles.home).with({ scheme: environmentService.userRoamingDataHome.scheme }), mainProcessService.getChannel('userDataProfiles'))); services.set(IUserDataProfilesService, userDataProfilesService); // Configuration @@ -271,7 +277,7 @@ class SharedProcessMain extends Disposable { services.set(IConfigurationService, configurationService); // Storage (global access only) - const storageService = new NativeStorageService(undefined, { defaultProfile: userDataProfilesService.defaultProfile, currentProfile: userDataProfilesService.defaultProfile }, mainProcessService, environmentService); + const storageService = new RemoteStorageService(undefined, { defaultProfile: userDataProfilesService.defaultProfile, currentProfile: userDataProfilesService.defaultProfile }, mainProcessService, environmentService); services.set(IStorageService, storageService); this._register(toDisposable(() => storageService.flush())); @@ -286,7 +292,7 @@ class SharedProcessMain extends Disposable { services.set(IUriIdentityService, uriIdentityService); // Request - services.set(IRequestService, new SharedProcessRequestService(mainProcessService, configurationService, logService)); + services.set(IRequestService, new RequestChannelClient(mainProcessService.getChannel('request'))); // Checksum services.set(IChecksumService, new SyncDescriptor(ChecksumService, undefined, false /* proxied to other processes */)); @@ -313,7 +319,6 @@ class SharedProcessMain extends Disposable { if (supportsTelemetry(productService, environmentService)) { const logAppender = new TelemetryLogAppender(logService, loggerService, environmentService, productService); appenders.push(logAppender); - const { installSourcePath } = environmentService; if (productService.aiConfig?.ariaKey) { const collectorAppender = new OneDataSystemAppender(internalTelemetry, 'monacoworkbench', null, productService.aiConfig.ariaKey); this._register(toDisposable(() => collectorAppender.flush())); // Ensure the 1DS appender is disposed so that it flushes remaining data @@ -322,7 +327,7 @@ class SharedProcessMain extends Disposable { telemetryService = new TelemetryService({ appenders, - commonProperties: resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version, this.configuration.machineId, internalTelemetry, installSourcePath), + commonProperties: resolveCommonProperties(release(), hostname(), process.arch, productService.commit, productService.version, this.configuration.machineId, internalTelemetry), sendErrorTelemetry: true, piiPaths: getPiiPathsFromEnvironment(environmentService), }, configurationService, productService); @@ -370,7 +375,7 @@ class SharedProcessMain extends Disposable { services.set(IUserDataSyncBackupStoreService, new SyncDescriptor(UserDataSyncBackupStoreService, undefined, false /* Eagerly cleans up old backups */)); services.set(IUserDataSyncEnablementService, new SyncDescriptor(UserDataSyncEnablementService, undefined, true)); services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService, undefined, false /* Initializes the Sync State */)); - services.set(IUserDataProfileStorageService, new SyncDescriptor(UserDataProfileStorageService, undefined, true)); + services.set(IUserDataProfileStorageService, new SyncDescriptor(NativeUserDataProfileStorageService, undefined, true)); services.set(IUserDataSyncResourceProviderService, new SyncDescriptor(UserDataSyncResourceProviderService, undefined, true)); // Terminal @@ -380,7 +385,7 @@ class SharedProcessMain extends Disposable { shortGraceTime: LocalReconnectConstants.ShortGraceTime, scrollback: configurationService.getValue(TerminalSettingId.PersistentSessionScrollback) ?? 100 }, - localize('ptyHost', "Pty Host"), + false, configurationService, environmentService, logService, @@ -475,7 +480,7 @@ class SharedProcessMain extends Disposable { process.on('uncaughtException', error => onUnexpectedError(error)); process.on('unhandledRejection', (reason: unknown) => onUnexpectedError(reason)); } else { - window.addEventListener('unhandledrejection', (event: PromiseRejectionEvent) => { + (globalThis as any).addEventListener('unhandledrejection', (event: any) => { // See https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent onUnexpectedError(event.reason); diff --git a/src/vs/editor/browser/config/editorConfiguration.ts b/src/vs/editor/browser/config/editorConfiguration.ts index e3f41e0d416..7e99e40ce47 100644 --- a/src/vs/editor/browser/config/editorConfiguration.ts +++ b/src/vs/editor/browser/config/editorConfiguration.ts @@ -12,7 +12,7 @@ import * as platform from 'vs/base/common/platform'; import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver'; import { FontMeasurements } from 'vs/editor/browser/config/fontMeasurements'; import { migrateOptions } from 'vs/editor/browser/config/migrateOptions'; -import { TabFocus } from 'vs/editor/browser/config/tabFocus'; +import { TabFocus, TabFocusContext } from 'vs/editor/browser/config/tabFocus'; import { ComputeOptionsMemory, ConfigurationChangedEvent, EditorOption, editorOptionsRegistry, FindComputedEditorOptionValueById, IComputedEditorOptions, IEditorOptions, IEnvironmentalOptions } from 'vs/editor/common/config/editorOptions'; import { EditorZoom } from 'vs/editor/common/config/editorZoom'; import { BareFontInfo, FontInfo, IValidatedEditorOptions } from 'vs/editor/common/config/fontInfo'; @@ -116,7 +116,7 @@ export class EditorConfiguration extends Disposable implements IEditorConfigurat lineNumbersDigitCount: this._lineNumbersDigitCount, emptySelectionClipboard: partialEnv.emptySelectionClipboard, pixelRatio: partialEnv.pixelRatio, - tabFocusMode: TabFocus.getTabFocusMode(), + tabFocusMode: TabFocus.getTabFocusMode(TabFocusContext.Editor), accessibilitySupport: partialEnv.accessibilitySupport }; return EditorOptionsUtil.computeOptions(this._validatedOptions, env); diff --git a/src/vs/editor/browser/config/tabFocus.ts b/src/vs/editor/browser/config/tabFocus.ts index 70f8bb92056..3575cfed1af 100644 --- a/src/vs/editor/browser/config/tabFocus.ts +++ b/src/vs/editor/browser/config/tabFocus.ts @@ -5,23 +5,29 @@ import { Emitter, Event } from 'vs/base/common/event'; +export const enum TabFocusContext { + Terminal = 'terminalFocus', + Editor = 'editorFocus' +} + class TabFocusImpl { - private _tabFocus: boolean = false; + private _tabFocusTerminal: boolean = false; + private _tabFocusEditor: boolean = false; - private readonly _onDidChangeTabFocus = new Emitter(); - public readonly onDidChangeTabFocus: Event = this._onDidChangeTabFocus.event; + private readonly _onDidChangeTabFocus = new Emitter(); + public readonly onDidChangeTabFocus: Event = this._onDidChangeTabFocus.event; - public getTabFocusMode(): boolean { - return this._tabFocus; + public getTabFocusMode(context: TabFocusContext): boolean { + return context === TabFocusContext.Terminal ? this._tabFocusTerminal : this._tabFocusEditor; } - public setTabFocusMode(tabFocusMode: boolean): void { - if (this._tabFocus === tabFocusMode) { - return; + public setTabFocusMode(tabFocusMode: boolean, context: TabFocusContext): void { + if (context === TabFocusContext.Terminal) { + this._tabFocusTerminal = tabFocusMode; + } else { + this._tabFocusEditor = tabFocusMode; } - - this._tabFocus = tabFocusMode; - this._onDidChangeTabFocus.fire(this._tabFocus); + this._onDidChangeTabFocus.fire(); } } diff --git a/src/vs/editor/browser/editorExtensions.ts b/src/vs/editor/browser/editorExtensions.ts index a9fb282cb57..6536ffb9034 100644 --- a/src/vs/editor/browser/editorExtensions.ts +++ b/src/vs/editor/browser/editorExtensions.ts @@ -25,10 +25,9 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { ILogService } from 'vs/platform/log/common/log'; - export type ServicesAccessor = InstantiationServicesAccessor; -export type IEditorContributionCtor = IConstructorSignature; -export type IDiffEditorContributionCtor = IConstructorSignature; +export type EditorContributionCtor = IConstructorSignature; +export type DiffEditorContributionCtor = IConstructorSignature; export const enum EditorContributionInstantiation { /** @@ -65,13 +64,13 @@ export const enum EditorContributionInstantiation { export interface IEditorContributionDescription { readonly id: string; - readonly ctor: IEditorContributionCtor; + readonly ctor: EditorContributionCtor; readonly instantiation: EditorContributionInstantiation; } export interface IDiffEditorContributionDescription { id: string; - ctor: IDiffEditorContributionCtor; + ctor: DiffEditorContributionCtor; } //#region Command @@ -515,10 +514,18 @@ export function registerInstantiatedEditorAction(editorAction: EditorAction): vo EditorContributionRegistry.INSTANCE.registerEditorAction(editorAction); } +/** + * Registers an editor contribution. Editor contributions have a lifecycle which is bound + * to a specific code editor instance. + */ export function registerEditorContribution(id: string, ctor: { new(editor: ICodeEditor, ...services: Services): IEditorContribution }, instantiation: EditorContributionInstantiation): void { EditorContributionRegistry.INSTANCE.registerEditorContribution(id, ctor, instantiation); } +/** + * Registers a diff editor contribution. Diff editor contributions have a lifecycle which + * is bound to a specific diff editor instance. + */ export function registerDiffEditorContribution(id: string, ctor: { new(editor: IDiffEditor, ...services: Services): IEditorContribution }): void { EditorContributionRegistry.INSTANCE.registerDiffEditorContribution(id, ctor); } @@ -555,20 +562,16 @@ class EditorContributionRegistry { public static readonly INSTANCE = new EditorContributionRegistry(); - private readonly editorContributions: IEditorContributionDescription[]; - private readonly diffEditorContributions: IDiffEditorContributionDescription[]; - private readonly editorActions: EditorAction[]; - private readonly editorCommands: { [commandId: string]: EditorCommand }; + private readonly editorContributions: IEditorContributionDescription[] = []; + private readonly diffEditorContributions: IDiffEditorContributionDescription[] = []; + private readonly editorActions: EditorAction[] = []; + private readonly editorCommands: { [commandId: string]: EditorCommand } = Object.create(null); constructor() { - this.editorContributions = []; - this.diffEditorContributions = []; - this.editorActions = []; - this.editorCommands = Object.create(null); } public registerEditorContribution(id: string, ctor: { new(editor: ICodeEditor, ...services: Services): IEditorContribution }, instantiation: EditorContributionInstantiation): void { - this.editorContributions.push({ id, ctor: ctor as IEditorContributionCtor, instantiation }); + this.editorContributions.push({ id, ctor: ctor as EditorContributionCtor, instantiation }); } public getEditorContributions(): IEditorContributionDescription[] { @@ -576,7 +579,7 @@ class EditorContributionRegistry { } public registerDiffEditorContribution(id: string, ctor: { new(editor: IDiffEditor, ...services: Services): IEditorContribution }): void { - this.diffEditorContributions.push({ id, ctor: ctor as IDiffEditorContributionCtor }); + this.diffEditorContributions.push({ id, ctor: ctor as DiffEditorContributionCtor }); } public getDiffEditorContributions(): IDiffEditorContributionDescription[] { diff --git a/src/vs/editor/browser/services/abstractCodeEditorService.ts b/src/vs/editor/browser/services/abstractCodeEditorService.ts index fd7ffee97c5..62db35d5a0c 100644 --- a/src/vs/editor/browser/services/abstractCodeEditorService.ts +++ b/src/vs/editor/browser/services/abstractCodeEditorService.ts @@ -21,12 +21,18 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC declare readonly _serviceBrand: undefined; + private readonly _onWillCreateCodeEditor = this._register(new Emitter()); + public readonly onWillCreateCodeEditor = this._onWillCreateCodeEditor.event; + private readonly _onCodeEditorAdd: Emitter = this._register(new Emitter()); public readonly onCodeEditorAdd: Event = this._onCodeEditorAdd.event; private readonly _onCodeEditorRemove: Emitter = this._register(new Emitter()); public readonly onCodeEditorRemove: Event = this._onCodeEditorRemove.event; + private readonly _onWillCreateDiffEditor = this._register(new Emitter()); + public readonly onWillCreateDiffEditor = this._onWillCreateDiffEditor.event; + private readonly _onDiffEditorAdd: Emitter = this._register(new Emitter()); public readonly onDiffEditorAdd: Event = this._onDiffEditorAdd.event; @@ -55,6 +61,10 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC this._globalStyleSheet = null; } + willCreateCodeEditor(): void { + this._onWillCreateCodeEditor.fire(); + } + addCodeEditor(editor: ICodeEditor): void { this._codeEditors[editor.getId()] = editor; this._onCodeEditorAdd.fire(editor); @@ -70,6 +80,10 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC return Object.keys(this._codeEditors).map(id => this._codeEditors[id]); } + willCreateDiffEditor(): void { + this._onWillCreateDiffEditor.fire(); + } + addDiffEditor(editor: IDiffEditor): void { this._diffEditors[editor.getId()] = editor; this._onDiffEditorAdd.fire(editor); @@ -225,8 +239,11 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC this._transientWatchers[uri] = w; } - w.set(key, value); - this._onDidChangeTransientModelProperty.fire(model); + const previousValue = w.get(key); + if (previousValue !== value) { + w.set(key, value); + this._onDidChangeTransientModelProperty.fire(model); + } } public getTransientModelProperty(model: ITextModel, key: string): any { diff --git a/src/vs/editor/browser/services/codeEditorService.ts b/src/vs/editor/browser/services/codeEditorService.ts index 9de2e964a03..d7119b2506e 100644 --- a/src/vs/editor/browser/services/codeEditorService.ts +++ b/src/vs/editor/browser/services/codeEditorService.ts @@ -17,20 +17,23 @@ export const ICodeEditorService = createDecorator('codeEdito export interface ICodeEditorService { readonly _serviceBrand: undefined; + readonly onWillCreateCodeEditor: Event; readonly onCodeEditorAdd: Event; readonly onCodeEditorRemove: Event; + readonly onWillCreateDiffEditor: Event; readonly onDiffEditorAdd: Event; readonly onDiffEditorRemove: Event; readonly onDidChangeTransientModelProperty: Event; readonly onDecorationTypeRegistered: Event; - + willCreateCodeEditor(): void; addCodeEditor(editor: ICodeEditor): void; removeCodeEditor(editor: ICodeEditor): void; listCodeEditors(): readonly ICodeEditor[]; + willCreateDiffEditor(): void; addDiffEditor(editor: IDiffEditor): void; removeDiffEditor(editor: IDiffEditor): void; listDiffEditors(): readonly IDiffEditor[]; diff --git a/src/vs/editor/browser/services/editorWorkerService.ts b/src/vs/editor/browser/services/editorWorkerService.ts index 48625e8c0a2..324dd59586d 100644 --- a/src/vs/editor/browser/services/editorWorkerService.ts +++ b/src/vs/editor/browser/services/editorWorkerService.ts @@ -21,13 +21,14 @@ import { regExpFlags } from 'vs/base/common/strings'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { ILogService } from 'vs/platform/log/common/log'; import { StopWatch } from 'vs/base/common/stopwatch'; -import { canceled } from 'vs/base/common/errors'; +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 { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; -import { LineRangeMapping, LineRange, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { ILinesDiffComputerOptions, LineRangeMapping, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { LineRange } from 'vs/editor/common/core/lineRange'; /** * Stop syncing a model to the worker if it was not needed for 1 min. @@ -131,13 +132,13 @@ export class EditorWorkerService extends Disposable implements IEditorWorkerServ return this._workerManager.withWorker().then(client => client.computeDirtyDiff(original, modified, ignoreTrimWhitespace)); } - public computeMoreMinimalEdits(resource: URI, edits: languages.TextEdit[] | null | undefined): Promise { + public computeMoreMinimalEdits(resource: URI, edits: languages.TextEdit[] | null | undefined, pretty: boolean = false): Promise { if (isNonEmptyArray(edits)) { if (!canSyncModel(this._modelService, resource)) { return Promise.resolve(edits); // File too large } const sw = StopWatch.create(true); - const result = this._workerManager.withWorker().then(client => client.computeMoreMinimalEdits(resource, edits)); + const result = this._workerManager.withWorker().then(client => client.computeMoreMinimalEdits(resource, edits, pretty)); result.finally(() => this._logService.trace('FORMAT#computeMoreMinimalEdits', resource.toString(true), sw.elapsed())); return Promise.race([result, timeout(1000).then(() => edits)]); @@ -146,6 +147,25 @@ export class EditorWorkerService extends Disposable implements IEditorWorkerServ } } + public computeHumanReadableDiff(resource: URI, edits: languages.TextEdit[] | null | undefined): Promise { + if (isNonEmptyArray(edits)) { + if (!canSyncModel(this._modelService, resource)) { + return Promise.resolve(edits); // File too large + } + const sw = StopWatch.create(true); + const result = this._workerManager.withWorker().then(client => client.computeHumanReadableDiff(resource, edits, { ignoreTrimWhitespace: false, maxComputationTimeMs: 1000 })).catch((err) => { + onUnexpectedError(err); + // In case of an exception, fall back to computeMoreMinimalEdits + return this.computeMoreMinimalEdits(resource, edits, true); + }); + result.finally(() => this._logService.trace('FORMAT#computeHumanReadableDiff', resource.toString(true), sw.elapsed())); + return result; + + } else { + return Promise.resolve(undefined); + } + } + public canNavigateValueSet(resource: URI): boolean { return (canSyncModel(this._modelService, resource)); } @@ -528,9 +548,15 @@ export class EditorWorkerClient extends Disposable implements IEditorWorkerClien }); } - public computeMoreMinimalEdits(resource: URI, edits: languages.TextEdit[]): Promise { + public computeMoreMinimalEdits(resource: URI, edits: languages.TextEdit[], pretty: boolean): Promise { return this._withSyncedResources([resource]).then(proxy => { - return proxy.computeMoreMinimalEdits(resource.toString(), edits); + return proxy.computeMoreMinimalEdits(resource.toString(), edits, pretty); + }); + } + + public computeHumanReadableDiff(resource: URI, edits: languages.TextEdit[], options: ILinesDiffComputerOptions): Promise { + return this._withSyncedResources([resource]).then(proxy => { + return proxy.computeHumanReadableDiff(resource.toString(), edits, options); }); } diff --git a/src/vs/editor/browser/view.ts b/src/vs/editor/browser/view.ts index 85c02d77290..37c48f99305 100644 --- a/src/vs/editor/browser/view.ts +++ b/src/vs/editor/browser/view.ts @@ -199,7 +199,6 @@ export class View extends ViewEventHandler { this._linesContent.appendChild(contentViewOverlays.getDomNode()); this._linesContent.appendChild(rulers.domNode); - this._linesContent.appendChild(blockOutline.domNode); this._linesContent.appendChild(this._viewZones.domNode); this._linesContent.appendChild(this._viewLines.getDomNode()); this._linesContent.appendChild(this._contentWidgets.domNode); @@ -211,6 +210,7 @@ export class View extends ViewEventHandler { this._overflowGuardContainer.appendChild(this._textAreaHandler.textAreaCover); this._overflowGuardContainer.appendChild(this._overlayWidgets.getDomNode()); this._overflowGuardContainer.appendChild(minimap.getDomNode()); + this._overflowGuardContainer.appendChild(blockOutline.domNode); this.domNode.appendChild(this._overflowGuardContainer); if (overflowWidgetsDomNode) { diff --git a/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css b/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css index f2100bd4846..c3e839f7c78 100644 --- a/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css +++ b/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css @@ -6,6 +6,7 @@ .monaco-editor .blockDecorations-container { position: absolute; top: 0; + pointer-events: none; } .monaco-editor .blockDecorations-block { diff --git a/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts b/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts index 87057ba9ce6..49d18e74873 100644 --- a/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts +++ b/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts @@ -18,6 +18,7 @@ export class BlockDecorations extends ViewPart { private readonly blocks: FastDomNode[] = []; private contentWidth: number = -1; + private contentLeft: number = 0; constructor(context: ViewContext) { super(context); @@ -41,6 +42,12 @@ export class BlockDecorations extends ViewPart { didChange = true; } + const newContentLeft = layoutInfo.contentLeft; + if (this.contentLeft !== newContentLeft) { + this.contentLeft = newContentLeft; + didChange = true; + } + return didChange; } @@ -92,16 +99,18 @@ export class BlockDecorations extends ViewPart { bottom = ctx.getVerticalOffsetAfterLineNumber(decoration.range.endLineNumber, true); } else { top = ctx.getVerticalOffsetForLineNumber(decoration.range.startLineNumber, true); - bottom = decoration.range.isEmpty() + bottom = decoration.range.isEmpty() && !decoration.options.blockDoesNotCollapse ? ctx.getVerticalOffsetForLineNumber(decoration.range.startLineNumber, false) : ctx.getVerticalOffsetAfterLineNumber(decoration.range.endLineNumber, true); } + const [paddingTop, paddingRight, paddingBottom, paddingLeft] = decoration.options.blockPadding ?? [0, 0, 0, 0]; + block.setClassName('blockDecorations-block ' + decoration.options.blockClassName); - block.setLeft(ctx.scrollLeft); - block.setWidth(this.contentWidth); - block.setTop(top); - block.setHeight(bottom - top); + block.setLeft(this.contentLeft - paddingLeft); + block.setWidth(this.contentWidth + paddingLeft + paddingRight); + block.setTop(top - ctx.scrollTop - paddingTop); + block.setHeight(bottom - top + paddingTop + paddingBottom); count++; } diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index bcfe4c68713..22d087786c5 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -60,6 +60,7 @@ import { IEditorConfiguration } from 'vs/editor/common/config/editorConfiguratio import { IDimension } from 'vs/editor/common/core/dimension'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { CodeEditorContributions } from 'vs/editor/browser/widget/codeEditorContributions'; +import { TabFocus, TabFocusContext } from 'vs/editor/browser/config/tabFocus'; let EDITOR_ID = 0; @@ -284,6 +285,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, ) { super(); + codeEditorService.willCreateCodeEditor(); const options = { ..._options }; @@ -1081,7 +1083,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE const action = this.getAction(handlerId); if (action) { - Promise.resolve(action.run()).then(undefined, onUnexpectedError); + Promise.resolve(action.run(payload)).then(undefined, onUnexpectedError); return; } @@ -1962,6 +1964,7 @@ class EditorContextKeysManager extends Disposable { this._register(this._editor.onDidBlurEditorText(() => this._updateFromFocus())); this._register(this._editor.onDidChangeModel(() => this._updateFromModel())); this._register(this._editor.onDidChangeConfiguration(() => this._updateFromModel())); + this._register(TabFocus.onDidChangeTabFocus(() => this._editorTabMovesFocus.set(TabFocus.getTabFocusMode(TabFocusContext.Editor)))); this._updateFromConfig(); this._updateFromSelection(); @@ -1974,7 +1977,7 @@ class EditorContextKeysManager extends Disposable { private _updateFromConfig(): void { const options = this._editor.getOptions(); - this._editorTabMovesFocus.set(options.get(EditorOption.tabFocusMode)); + this._editorTabMovesFocus.set(TabFocus.getTabFocusMode(TabFocusContext.Editor)); this._editorReadonly.set(options.get(EditorOption.readOnly)); this._inDiffEditor.set(options.get(EditorOption.inDiffEditor)); this._editorColumnSelection.set(options.get(EditorOption.columnSelection)); diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 14de272ba9f..49830dc5284 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -252,6 +252,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE @IEditorProgressService private readonly _editorProgressService: IEditorProgressService ) { super(); + codeEditorService.willCreateDiffEditor(); this._documentDiffProvider = this._register(instantiationService.createInstance(WorkerBasedDocumentDiffProvider, options)); this._register(this._documentDiffProvider.onDidChange(e => this._beginUpdateDecorationsSoon())); diff --git a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts index 1d24e5e5887..9fea174a584 100644 --- a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts +++ b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts @@ -6,7 +6,7 @@ import * as objects from 'vs/base/common/objects'; import { ICodeEditor, IDiffEditorConstructionOptions } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; +import { CodeEditorWidget, ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget'; import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget'; import { ConfigurationChangedEvent, IDiffEditorOptions, IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -29,6 +29,7 @@ export class EmbeddedCodeEditorWidget extends CodeEditorWidget { constructor( domElement: HTMLElement, options: IEditorOptions, + codeEditorWidgetOptions: ICodeEditorWidgetOptions, parentEditor: ICodeEditor, @IInstantiationService instantiationService: IInstantiationService, @ICodeEditorService codeEditorService: ICodeEditorService, @@ -40,7 +41,7 @@ export class EmbeddedCodeEditorWidget extends CodeEditorWidget { @ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService, @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, ) { - super(domElement, { ...parentEditor.getRawOptions(), overflowWidgetsDomNode: parentEditor.getOverflowWidgetsDomNode() }, {}, instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService, accessibilityService, languageConfigurationService, languageFeaturesService); + super(domElement, { ...parentEditor.getRawOptions(), overflowWidgetsDomNode: parentEditor.getOverflowWidgetsDomNode() }, codeEditorWidgetOptions, instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService, accessibilityService, languageConfigurationService, languageFeaturesService); this._parentEditor = parentEditor; this._overwriteOptions = options; diff --git a/src/vs/editor/common/config/editorConfigurationSchema.ts b/src/vs/editor/common/config/editorConfigurationSchema.ts index 965205f5c5c..a400b4015f5 100644 --- a/src/vs/editor/common/config/editorConfigurationSchema.ts +++ b/src/vs/editor/common/config/editorConfigurationSchema.ts @@ -95,6 +95,17 @@ const editorConfiguration: IConfigurationNode = { default: 20_000, description: nls.localize('maxTokenizationLineLength', "Lines above this length will not be tokenized for performance reasons") }, + 'editor.experimental.asyncTokenization': { + type: 'boolean', + default: false, + description: nls.localize('editor.experimental.asyncTokenization', "Controls whether the tokenization should happen asynchronously on a web worker."), + tags: ['experimental'], + }, + 'editor.experimental.asyncTokenizationLogging': { + type: 'boolean', + default: false, + description: nls.localize('editor.experimental.asyncTokenizationLogging', "Controls whether async tokenization should be logged. For debugging only."), + }, 'editor.language.brackets': { type: ['array', 'null'], default: null, // We want to distinguish the empty array from not configured. diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 1de055a7f5c..4e0ba79f54a 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -57,6 +57,10 @@ export interface IEditorOptions { * The aria label for the editor's textarea (when it is focused). */ ariaLabel?: string; + /** + * Control whether a screen reader announces inline suggestion content immediately. + */ + screenReaderAnnounceInlineSuggestion?: boolean; /** * The `tabindex` property of the editor's textarea */ @@ -698,6 +702,11 @@ export interface IEditorOptions { * When enabled, this shows a preview of the drop location and triggers an `onDropIntoEditor` event. */ dropIntoEditor?: IDropIntoEditorOptions; + + /** + * Controls whether the editor receives tabs or defers them to the workbench for navigation. + */ + tabFocusMode?: boolean; } /** @@ -2649,7 +2658,10 @@ export interface IEditorStickyScrollOptions { * Maximum number of sticky lines to show */ maxLineCount?: number; - + /** + * Model to choose for sticky scroll by default + */ + defaultModel?: 'outlineModel' | 'foldingProviderModel' | 'indentationModel'; } /** @@ -2660,21 +2672,27 @@ export type EditorStickyScrollOptions = Readonly { constructor() { - const defaults: EditorStickyScrollOptions = { enabled: false, maxLineCount: 5 }; + const defaults: EditorStickyScrollOptions = { enabled: false, maxLineCount: 5, defaultModel: 'outlineModel' }; super( EditorOption.stickyScroll, 'stickyScroll', defaults, { 'editor.stickyScroll.enabled': { type: 'boolean', default: defaults.enabled, - description: nls.localize('editor.stickyScroll', "Shows the nested current scopes during the scroll at the top of the editor.") + description: nls.localize('editor.stickyScroll.enabled', "Shows the nested current scopes during the scroll at the top of the editor.") }, 'editor.stickyScroll.maxLineCount': { type: 'number', default: defaults.maxLineCount, minimum: 1, maximum: 10, - description: nls.localize('editor.stickyScroll.', "Defines the maximum number of sticky lines to show.") + description: nls.localize('editor.stickyScroll.maxLineCount', "Defines the maximum number of sticky lines to show.") + }, + 'editor.stickyScroll.defaultModel': { + type: 'string', + enum: ['outlineModel', 'foldingProviderModel', 'indentationModel'], + default: defaults.defaultModel, + description: nls.localize('editor.stickyScroll.defaultModel', "Defines the model to use for determining which lines to stick. If the outline model does not exist, it will fall back on the folding provider model which falls back on the indentation model. This order is respected in all three cases.") }, } ); @@ -2688,6 +2706,7 @@ class EditorStickyScroll extends BaseEditorOption(input.defaultModel, this.defaultValue.defaultModel, ['outlineModel', 'foldingProviderModel', 'indentationModel']), }; } } @@ -3786,6 +3805,8 @@ export interface IInlineSuggestOptions { mode?: 'prefix' | 'subword' | 'subwordSmart'; showToolbar?: 'always' | 'onHover'; + + suppressSuggestions?: boolean; } /** @@ -3802,6 +3823,7 @@ class InlineEditorSuggest extends BaseEditorOption { - - constructor() { - super(EditorOption.tabFocusMode); - } - - public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: boolean): boolean { - const readOnly = options.get(EditorOption.readOnly); - return (readOnly ? true : env.tabFocusMode); - } -} - -//#endregion - //#region wrappingIndent /** @@ -4765,6 +4777,7 @@ export const enum EditorOption { accessibilityPageSize, ariaLabel, autoClosingBrackets, + screenReaderAnnounceInlineSuggestion, autoClosingDelete, autoClosingOvertype, autoClosingQuotes, @@ -4929,6 +4942,13 @@ export const EditorOptions = { ariaLabel: register(new EditorStringOption( EditorOption.ariaLabel, 'ariaLabel', nls.localize('editorViewAccessibleLabel', "Editor content") )), + screenReaderAnnounceInlineSuggestion: register(new EditorBooleanOption( + EditorOption.screenReaderAnnounceInlineSuggestion, 'screenReaderAnnounceInlineSuggestion', false, + { + description: nls.localize('screenReaderAnnounceInlineSuggestion', "Control whether inline suggestions are announced by a screen reader. Note that this does not work on macOS with VoiceOver."), + tags: ['accessibility'] + } + )), autoClosingBrackets: register(new EditorStringEnumOption( EditorOption.autoClosingBrackets, 'autoClosingBrackets', 'languageDefined' as 'always' | 'languageDefined' | 'beforeWhitespace' | 'never', @@ -5619,7 +5639,9 @@ export const EditorOptions = { // Leave these at the end (because they have dependencies!) editorClassName: register(new EditorClassName()), pixelRatio: register(new EditorPixelRatio()), - tabFocusMode: register(new EditorTabFocusMode()), + tabFocusMode: register(new EditorBooleanOption(EditorOption.tabFocusMode, 'tabFocusMode', false, + { markdownDescription: nls.localize('tabFocusMode', "Controls whether the editor receives tabs or defers them to the workbench for navigation.") } + )), layoutInfo: register(new EditorLayoutInfoComputer()), wrappingInfo: register(new EditorWrappingInfoComputer()), wrappingIndent: register(new WrappingIndentOption()), diff --git a/src/vs/editor/common/core/lineRange.ts b/src/vs/editor/common/core/lineRange.ts new file mode 100644 index 00000000000..183ba5d6e36 --- /dev/null +++ b/src/vs/editor/common/core/lineRange.ts @@ -0,0 +1,91 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { BugIndicatingError } from 'vs/base/common/errors'; + +/** + * A range of lines (1-based). + */ +export class LineRange { + /** + * The start line number. + */ + public readonly startLineNumber: number; + + /** + * The end line number (exclusive). + */ + public readonly endLineNumberExclusive: number; + + constructor( + startLineNumber: number, + endLineNumberExclusive: number, + ) { + if (startLineNumber > endLineNumberExclusive) { + throw new BugIndicatingError(`startLineNumber ${startLineNumber} cannot be after endLineNumberExclusive ${endLineNumberExclusive}`); + } + this.startLineNumber = startLineNumber; + this.endLineNumberExclusive = endLineNumberExclusive; + } + + /** + * Indicates if this line range contains the given line number. + */ + public contains(lineNumber: number): boolean { + return this.startLineNumber <= lineNumber && lineNumber < this.endLineNumberExclusive; + } + + /** + * Indicates if this line range is empty. + */ + get isEmpty(): boolean { + return this.startLineNumber === this.endLineNumberExclusive; + } + + /** + * Moves this line range by the given offset of line numbers. + */ + public delta(offset: number): LineRange { + return new LineRange(this.startLineNumber + offset, this.endLineNumberExclusive + offset); + } + + /** + * The number of lines this line range spans. + */ + public get length(): number { + return this.endLineNumberExclusive - this.startLineNumber; + } + + /** + * Creates a line range that combines this and the given line range. + */ + public join(other: LineRange): LineRange { + return new LineRange( + Math.min(this.startLineNumber, other.startLineNumber), + Math.max(this.endLineNumberExclusive, other.endLineNumberExclusive) + ); + } + + public toString(): string { + return `[${this.startLineNumber},${this.endLineNumberExclusive})`; + } + + /** + * The resulting range is empty if the ranges do not intersect, but touch. + * If the ranges don't even touch, the result is undefined. + */ + public intersect(other: LineRange): LineRange | undefined { + const startLineNumber = Math.max(this.startLineNumber, other.startLineNumber); + const endLineNumberExclusive = Math.min(this.endLineNumberExclusive, other.endLineNumberExclusive); + if (startLineNumber <= endLineNumberExclusive) { + return new LineRange(startLineNumber, endLineNumberExclusive); + } + return undefined; + } + + public overlapOrTouch(other: LineRange): boolean { + return this.startLineNumber <= other.endLineNumberExclusive && other.startLineNumber <= this.endLineNumberExclusive; + } +} diff --git a/src/vs/editor/common/core/offsetRange.ts b/src/vs/editor/common/core/offsetRange.ts new file mode 100644 index 00000000000..14ff2039fc7 --- /dev/null +++ b/src/vs/editor/common/core/offsetRange.ts @@ -0,0 +1,93 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { BugIndicatingError } from 'vs/base/common/errors'; + +/** + * A range of offsets (0-based). +*/ +export class OffsetRange { + public static addRange(range: OffsetRange, sortedRanges: OffsetRange[]): void { + let i = 0; + while (i < sortedRanges.length && sortedRanges[i].endExclusive < range.start) { + i++; + } + let j = i; + while (j < sortedRanges.length && sortedRanges[j].start <= range.endExclusive) { + j++; + } + if (i === j) { + sortedRanges.splice(i, 0, range); + } else { + const start = Math.min(range.start, sortedRanges[i].start); + const end = Math.max(range.endExclusive, sortedRanges[j - 1].endExclusive); + sortedRanges.splice(i, j - i, new OffsetRange(start, end)); + } + } + + public static tryCreate(start: number, endExclusive: number): OffsetRange | undefined { + if (start > endExclusive) { + return undefined; + } + return new OffsetRange(start, endExclusive); + } + + constructor(public readonly start: number, public readonly endExclusive: number) { + if (start > endExclusive) { + throw new BugIndicatingError(`Invalid range: ${this.toString()}`); + } + } + + get isEmpty(): boolean { + return this.start === this.endExclusive; + } + + public delta(offset: number): OffsetRange { + return new OffsetRange(this.start + offset, this.endExclusive + offset); + } + + public get length(): number { + return this.endExclusive - this.start; + } + + public toString() { + return `[${this.start}, ${this.endExclusive})`; + } + + public equals(other: OffsetRange): boolean { + return this.start === other.start && this.endExclusive === other.endExclusive; + } + + public containsRange(other: OffsetRange): boolean { + return this.start <= other.start && other.endExclusive <= this.endExclusive; + } + + public contains(offset: number): boolean { + return this.start <= offset && offset < this.endExclusive; + } + + /** + * for all numbers n: range1.contains(n) or range2.contains(n) => range1.join(range2).contains(n) + * The joined range is the smallest range that contains both ranges. + */ + public join(other: OffsetRange): OffsetRange { + return new OffsetRange(Math.min(this.start, other.start), Math.max(this.endExclusive, other.endExclusive)); + } + + /** + * for all numbers n: range1.contains(n) and range2.contains(n) <=> range1.intersect(range2).contains(n) + * + * The resulting range is empty if the ranges do not intersect, but touch. + * If the ranges don't even touch, the result is undefined. + */ + public intersect(other: OffsetRange): OffsetRange | undefined { + const start = Math.max(this.start, other.start); + const end = Math.min(this.endExclusive, other.endExclusive); + if (start <= end) { + return new OffsetRange(start, end); + } + return undefined; + } +} diff --git a/src/vs/editor/common/diff/algorithms/diffAlgorithm.ts b/src/vs/editor/common/diff/algorithms/diffAlgorithm.ts index 1ac613d3109..b38955a63e5 100644 --- a/src/vs/editor/common/diff/algorithms/diffAlgorithm.ts +++ b/src/vs/editor/common/diff/algorithms/diffAlgorithm.ts @@ -3,17 +3,39 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { BugIndicatingError } from 'vs/base/common/errors'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; + /** * Represents a synchronous diff algorithm. Should be executed in a worker. */ export interface IDiffAlgorithm { - compute(sequence1: ISequence, sequence2: ISequence): SequenceDiff[]; + compute(sequence1: ISequence, sequence2: ISequence, timeout?: ITimeout): DiffAlgorithmResult; +} + +export class DiffAlgorithmResult { + static trivial(seq1: ISequence, seq2: ISequence): DiffAlgorithmResult { + return new DiffAlgorithmResult([new SequenceDiff(new OffsetRange(0, seq1.length), new OffsetRange(0, seq2.length))], false); + } + + static trivialTimedOut(seq1: ISequence, seq2: ISequence): DiffAlgorithmResult { + return new DiffAlgorithmResult([new SequenceDiff(new OffsetRange(0, seq1.length), new OffsetRange(0, seq2.length))], true); + } + + constructor( + public readonly diffs: SequenceDiff[], + /** + * Indicates if the time out was reached. + * In that case, the diffs might be an approximation and the user should be asked to rerun the diff with more time. + */ + public readonly hitTimeout: boolean, + ) { } } export class SequenceDiff { constructor( public readonly seq1Range: OffsetRange, - public readonly seq2Range: OffsetRange + public readonly seq2Range: OffsetRange, ) { } public reverse(): SequenceDiff { @@ -23,32 +45,9 @@ export class SequenceDiff { public toString(): string { return `${this.seq1Range} <-> ${this.seq2Range}`; } -} -/** - * Todo move this class to some top level utils. -*/ -export class OffsetRange { - constructor(public readonly start: number, public readonly endExclusive: number) { } - - get isEmpty(): boolean { - return this.start === this.endExclusive; - } - - public delta(offset: number): OffsetRange { - return new OffsetRange(this.start + offset, this.endExclusive + offset); - } - - public get length(): number { - return this.endExclusive - this.start; - } - - public toString() { - return `[${this.start}, ${this.endExclusive})`; - } - - public join(other: OffsetRange): OffsetRange { - return new OffsetRange(Math.min(this.start, other.start), Math.max(this.endExclusive, other.endExclusive)); + public join(other: SequenceDiff): SequenceDiff { + return new SequenceDiff(this.seq1Range.join(other.seq1Range), this.seq2Range.join(other.seq2Range)); } } @@ -63,3 +62,43 @@ export interface ISequence { */ getBoundaryScore?(length: number): number; } + +export interface ITimeout { + isValid(): boolean; +} + +export class InfiniteTimeout implements ITimeout { + public static instance = new InfiniteTimeout(); + + isValid(): boolean { + return true; + } +} + +export class DateTimeout implements ITimeout { + private readonly startTime = Date.now(); + private valid = true; + + constructor(private timeout: number) { + if (timeout <= 0) { + throw new BugIndicatingError('timeout must be positive'); + } + } + + // Recommendation: Set a log-point `{this.disable()}` in the body + public isValid(): boolean { + const valid = Date.now() - this.startTime < this.timeout; + if (!valid && this.valid) { + this.valid = false; // timeout reached + // eslint-disable-next-line no-debugger + debugger; // WARNING: Most likely debugging caused the timeout. Call `this.disable()` to continue without timing out. + } + return this.valid; + } + + public disable() { + this.timeout = Number.MAX_SAFE_INTEGER; + this.isValid = () => true; + this.valid = true; + } +} diff --git a/src/vs/editor/common/diff/algorithms/dynamicProgrammingDiffing.ts b/src/vs/editor/common/diff/algorithms/dynamicProgrammingDiffing.ts index ef264e21b2e..2212ebef27e 100644 --- a/src/vs/editor/common/diff/algorithms/dynamicProgrammingDiffing.ts +++ b/src/vs/editor/common/diff/algorithms/dynamicProgrammingDiffing.ts @@ -3,7 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDiffAlgorithm, SequenceDiff, OffsetRange, ISequence } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; +import { IDiffAlgorithm, SequenceDiff, ISequence, ITimeout, InfiniteTimeout, DiffAlgorithmResult } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; import { Array2D } from 'vs/editor/common/diff/algorithms/utils'; /** @@ -11,7 +12,11 @@ import { Array2D } from 'vs/editor/common/diff/algorithms/utils'; * The algorithm can be improved by processing the 2d array diagonally. */ export class DynamicProgrammingDiffing implements IDiffAlgorithm { - compute(sequence1: ISequence, sequence2: ISequence, equalityScore?: (offset1: number, offset2: number) => number): SequenceDiff[] { + compute(sequence1: ISequence, sequence2: ISequence, timeout: ITimeout = InfiniteTimeout.instance, equalityScore?: (offset1: number, offset2: number) => number): DiffAlgorithmResult { + if (sequence1.length === 0 || sequence2.length === 0) { + return DiffAlgorithmResult.trivial(sequence1, sequence2); + } + /** * lcsLengths.get(i, j): Length of the longest common subsequence of sequence1.substring(0, i + 1) and sequence2.substring(0, j + 1). */ @@ -22,6 +27,10 @@ export class DynamicProgrammingDiffing implements IDiffAlgorithm { // ==== Initializing lcsLengths ==== for (let s1 = 0; s1 < sequence1.length; s1++) { for (let s2 = 0; s2 < sequence2.length; s2++) { + if (!timeout.isValid()) { + return DiffAlgorithmResult.trivialTimedOut(sequence1, sequence2); + } + const horizontalLen = s1 === 0 ? 0 : lcsLengths.get(s1 - 1, s2); const verticalLen = s2 === 0 ? 0 : lcsLengths.get(s1, s2 - 1); @@ -93,6 +102,6 @@ export class DynamicProgrammingDiffing implements IDiffAlgorithm { } reportDecreasingAligningPositions(-1, -1); result.reverse(); - return result; + return new DiffAlgorithmResult(result, false); } } diff --git a/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts b/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts index 88a0a86741f..ca88296ea7f 100644 --- a/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts +++ b/src/vs/editor/common/diff/algorithms/joinSequenceDiffs.ts @@ -3,7 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ISequence, OffsetRange, SequenceDiff } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; +import { ISequence, SequenceDiff } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; export function optimizeSequenceDiffs(sequence1: ISequence, sequence2: ISequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { let result = sequenceDiffs; diff --git a/src/vs/editor/common/diff/algorithms/myersDiffAlgorithm.ts b/src/vs/editor/common/diff/algorithms/myersDiffAlgorithm.ts index 525a3f4d2a7..963019683ad 100644 --- a/src/vs/editor/common/diff/algorithms/myersDiffAlgorithm.ts +++ b/src/vs/editor/common/diff/algorithms/myersDiffAlgorithm.ts @@ -3,19 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDiffAlgorithm, ISequence, SequenceDiff, OffsetRange } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; +import { DiffAlgorithmResult, IDiffAlgorithm, ISequence, ITimeout, InfiniteTimeout, SequenceDiff } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; /** * An O(ND) diff algorithm that has a quadratic space worst-case complexity. */ export class MyersDiffAlgorithm implements IDiffAlgorithm { - compute(seq1: ISequence, seq2: ISequence): SequenceDiff[] { + compute(seq1: ISequence, seq2: ISequence, timeout: ITimeout = InfiniteTimeout.instance): DiffAlgorithmResult { // These are common special cases. // The early return improves performance dramatically. - if (seq1.length === 0) { - return [new SequenceDiff(new OffsetRange(0, 0), new OffsetRange(0, seq2.length))]; - } else if (seq2.length === 0) { - return [new SequenceDiff(new OffsetRange(0, seq1.length), new OffsetRange(0, 0))]; + if (seq1.length === 0 || seq2.length === 0) { + return DiffAlgorithmResult.trivial(seq1, seq2); } function getXAfterSnake(x: number, y: number): number { @@ -41,6 +40,10 @@ export class MyersDiffAlgorithm implements IDiffAlgorithm { loop: while (true) { d++; for (k = -d; k <= d; k += 2) { + if (!timeout.isValid()) { + return DiffAlgorithmResult.trivialTimedOut(seq1, seq2); + } + const maxXofDLineTop = k === d ? -1 : V.get(k + 1); // We take a vertical non-diagonal const maxXofDLineLeft = k === -d ? -1 : V.get(k - 1) + 1; // We take a horizontal non-diagonal (+1 x) const x = Math.min(Math.max(maxXofDLineTop, maxXofDLineLeft), seq1.length); @@ -81,7 +84,7 @@ export class MyersDiffAlgorithm implements IDiffAlgorithm { } result.reverse(); - return result; + return new DiffAlgorithmResult(result, false); } } diff --git a/src/vs/editor/common/diff/linesDiffComputer.ts b/src/vs/editor/common/diff/linesDiffComputer.ts index 9a9961f77cd..c7161243531 100644 --- a/src/vs/editor/common/diff/linesDiffComputer.ts +++ b/src/vs/editor/common/diff/linesDiffComputer.ts @@ -3,10 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { LineRange } from 'vs/editor/common/core/lineRange'; import { Range } from 'vs/editor/common/core/range'; export interface ILinesDiffComputer { - computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): ILinesDiff; + computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): LinesDiff; } export interface ILinesDiffComputerOptions { @@ -14,9 +15,17 @@ export interface ILinesDiffComputerOptions { readonly maxComputationTimeMs: number; } -export interface ILinesDiff { - readonly quitEarly: boolean; - readonly changes: LineRangeMapping[]; +export class LinesDiff { + constructor( + readonly changes: readonly LineRangeMapping[], + + /** + * Indicates if the time out was reached. + * In that case, the diffs might be an approximation and the user should be asked to rerun the diff with more time. + */ + readonly hitTimeout: boolean, + ) { + } } /** @@ -36,7 +45,7 @@ export class LineRangeMapping { /** * If inner changes have not been computed, this is set to undefined. * Otherwise, it represents the character-level diff in this line range. - * The original range of each range mapping should be contained in the original line range (same for modified). + * The original range of each range mapping should be contained in the original line range (same for modified), exceptions are new-lines. * Must not be an empty array. */ public readonly innerChanges: RangeMapping[] | undefined; @@ -83,61 +92,3 @@ export class RangeMapping { return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`; } } - -/** - * A range of lines (1-based). - */ -export class LineRange { - /** - * The start line number. - */ - public readonly startLineNumber: number; - - /** - * The end line number (exclusive). - */ - public readonly endLineNumberExclusive: number; - - constructor( - startLineNumber: number, - endLineNumberExclusive: number, - ) { - this.startLineNumber = startLineNumber; - this.endLineNumberExclusive = endLineNumberExclusive; - } - - /** - * Indicates if this line range is empty. - */ - get isEmpty(): boolean { - return this.startLineNumber === this.endLineNumberExclusive; - } - - /** - * Moves this line range by the given offset of line numbers. - */ - public delta(offset: number): LineRange { - return new LineRange(this.startLineNumber + offset, this.endLineNumberExclusive + offset); - } - - /** - * The number of lines this line range spans. - */ - public get length(): number { - return this.endLineNumberExclusive - this.startLineNumber; - } - - /** - * Creates a line range that combines this and the given line range. - */ - public join(other: LineRange): LineRange { - return new LineRange( - Math.min(this.startLineNumber, other.startLineNumber), - Math.max(this.endLineNumberExclusive, other.endLineNumberExclusive) - ); - } - - public toString(): string { - return `[${this.startLineNumber},${this.endLineNumberExclusive})`; - } -} diff --git a/src/vs/editor/common/diff/smartLinesDiffComputer.ts b/src/vs/editor/common/diff/smartLinesDiffComputer.ts index 9c514f6a2d6..421a7e15b3e 100644 --- a/src/vs/editor/common/diff/smartLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/smartLinesDiffComputer.ts @@ -5,15 +5,16 @@ import { CharCode } from 'vs/base/common/charCode'; import { IDiffChange, ISequence, LcsDiff, IDiffResult } from 'vs/base/common/diff/diff'; -import { ILinesDiffComputer, ILinesDiff, ILinesDiffComputerOptions, LineRange, RangeMapping, LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { ILinesDiffComputer, ILinesDiffComputerOptions, RangeMapping, LineRangeMapping, LinesDiff } from 'vs/editor/common/diff/linesDiffComputer'; import * as strings from 'vs/base/common/strings'; import { Range } from 'vs/editor/common/core/range'; import { assertFn, checkAdjacentItems } from 'vs/base/common/assert'; +import { LineRange } from 'vs/editor/common/core/lineRange'; const MINIMUM_MATCHING_CHARACTER_LENGTH = 3; export class SmartLinesDiffComputer implements ILinesDiffComputer { - computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): ILinesDiff { + computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): LinesDiff { const diffComputer = new DiffComputer(originalLines, modifiedLines, { maxComputationTime: options.maxComputationTimeMs, shouldIgnoreTrimWhitespace: options.ignoreTrimWhitespace, @@ -74,10 +75,7 @@ export class SmartLinesDiffComputer implements ILinesDiffComputer { ); }); - return { - quitEarly: result.quitEarly, - changes, - }; + return new LinesDiff(changes, result.quitEarly); } } diff --git a/src/vs/editor/common/diff/standardLinesDiffComputer.ts b/src/vs/editor/common/diff/standardLinesDiffComputer.ts index de289902022..47e7c76da35 100644 --- a/src/vs/editor/common/diff/standardLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/standardLinesDiffComputer.ts @@ -5,22 +5,24 @@ import { assertFn, checkAdjacentItems } from 'vs/base/common/assert'; import { CharCode } from 'vs/base/common/charCode'; +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 { OffsetRange, SequenceDiff, ISequence } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; +import { DateTimeout, ISequence, ITimeout, InfiniteTimeout, SequenceDiff } from 'vs/editor/common/diff/algorithms/diffAlgorithm'; import { DynamicProgrammingDiffing } from 'vs/editor/common/diff/algorithms/dynamicProgrammingDiffing'; import { optimizeSequenceDiffs, smoothenSequenceDiffs } from 'vs/editor/common/diff/algorithms/joinSequenceDiffs'; import { MyersDiffAlgorithm } from 'vs/editor/common/diff/algorithms/myersDiffAlgorithm'; -import { ILinesDiff, ILinesDiffComputer, ILinesDiffComputerOptions, LineRange, LineRangeMapping, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping, LinesDiff, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; export class StandardLinesDiffComputer implements ILinesDiffComputer { private readonly dynamicProgrammingDiffing = new DynamicProgrammingDiffing(); private readonly myersDiffingAlgorithm = new MyersDiffAlgorithm(); - constructor( - ) { } + computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): LinesDiff { + const timeout = options.maxComputationTimeMs === 0 ? InfiniteTimeout.instance : new DateTimeout(options.maxComputationTimeMs); + const considerWhitespaceChanges = !options.ignoreTrimWhitespace; - computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): ILinesDiff { const perfectHashes = new Map(); function getOrCreateHash(text: string): number { let hash = perfectHashes.get(text); @@ -37,12 +39,13 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { const sequence1 = new LineSequence(srcDocLines, originalLines); const sequence2 = new LineSequence(tgtDocLines, modifiedLines); - let lineAlignments = (() => { + const lineAlignmentResult = (() => { if (sequence1.length + sequence2.length < 1500) { // Use the improved algorithm for small files return this.dynamicProgrammingDiffing.compute( sequence1, sequence2, + timeout, (offset1, offset2) => originalLines[offset1] === modifiedLines[offset2] ? modifiedLines[offset2].length === 0 @@ -58,11 +61,17 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { ); })(); + let lineAlignments = lineAlignmentResult.diffs; + let hitTimeout = lineAlignmentResult.hitTimeout; lineAlignments = optimizeSequenceDiffs(sequence1, sequence2, lineAlignments); const alignments: RangeMapping[] = []; const scanForWhitespaceChanges = (equalLinesCount: number) => { + if (!considerWhitespaceChanges) { + return; + } + for (let i = 0; i < equalLinesCount; i++) { const seq1Offset = seq1LastStart + i; const seq2Offset = seq2LastStart + i; @@ -70,11 +79,14 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { // This is because of whitespace changes, diff these lines const characterDiffs = this.refineDiff(originalLines, modifiedLines, new SequenceDiff( new OffsetRange(seq1Offset, seq1Offset + 1), - new OffsetRange(seq2Offset, seq2Offset + 1) - )); - for (const a of characterDiffs) { + new OffsetRange(seq2Offset, seq2Offset + 1), + ), timeout, considerWhitespaceChanges); + for (const a of characterDiffs.mappings) { alignments.push(a); } + if (characterDiffs.hitTimeout) { + hitTimeout = true; + } } } }; @@ -92,64 +104,161 @@ export class StandardLinesDiffComputer implements ILinesDiffComputer { seq1LastStart = diff.seq1Range.endExclusive; seq2LastStart = diff.seq2Range.endExclusive; - const characterDiffs = this.refineDiff(originalLines, modifiedLines, diff); - for (const a of characterDiffs) { + const characterDiffs = this.refineDiff(originalLines, modifiedLines, diff, timeout, considerWhitespaceChanges); + if (characterDiffs.hitTimeout) { + hitTimeout = true; + } + for (const a of characterDiffs.mappings) { alignments.push(a); } } scanForWhitespaceChanges(originalLines.length - seq1LastStart); - const changes: LineRangeMapping[] = lineRangeMappingFromRangeMappings(alignments); - - return { - quitEarly: false, - changes: changes, - }; + const changes = lineRangeMappingFromRangeMappings(alignments, originalLines, modifiedLines); + return new LinesDiff(changes, hitTimeout); } - private refineDiff(originalLines: string[], modifiedLines: string[], diff: SequenceDiff): RangeMapping[] { - const sourceSlice = new Slice(originalLines, diff.seq1Range); - const targetSlice = new Slice(modifiedLines, diff.seq2Range); + private refineDiff(originalLines: string[], modifiedLines: string[], diff: SequenceDiff, timeout: ITimeout, considerWhitespaceChanges: boolean): { mappings: RangeMapping[]; hitTimeout: boolean } { + const sourceSlice = new Slice(originalLines, diff.seq1Range, considerWhitespaceChanges); + const targetSlice = new Slice(modifiedLines, diff.seq2Range, considerWhitespaceChanges); - const originalDiffs = sourceSlice.length + targetSlice.length < 500 - ? this.dynamicProgrammingDiffing.compute(sourceSlice, targetSlice) - : this.myersDiffingAlgorithm.compute(sourceSlice, targetSlice); + const diffResult = sourceSlice.length + targetSlice.length < 500 + ? this.dynamicProgrammingDiffing.compute(sourceSlice, targetSlice, timeout) + : this.myersDiffingAlgorithm.compute(sourceSlice, targetSlice, timeout); - let diffs = optimizeSequenceDiffs(sourceSlice, targetSlice, originalDiffs); + let diffs = diffResult.diffs; + diffs = optimizeSequenceDiffs(sourceSlice, targetSlice, diffs); + diffs = coverFullWords(sourceSlice, targetSlice, diffs); diffs = smoothenSequenceDiffs(sourceSlice, targetSlice, diffs); + const result = diffs.map( (d) => new RangeMapping( - sourceSlice.translateRange(d.seq1Range).delta(diff.seq1Range.start), - targetSlice.translateRange(d.seq2Range).delta(diff.seq2Range.start) + sourceSlice.translateRange(d.seq1Range), + targetSlice.translateRange(d.seq2Range) ) ); - return result; + + // Assert: result applied on original should be the same as diff applied to original + + return { + mappings: result, + hitTimeout: diffResult.hitTimeout, + }; } } -export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[]): LineRangeMapping[] { +function coverFullWords(sequence1: Slice, sequence2: Slice, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { + const additional: SequenceDiff[] = []; + + let lastModifiedWord: { added: number; deleted: number; count: number; s1Range: OffsetRange; s2Range: OffsetRange } | undefined = undefined; + + function maybePushWordToAdditional() { + if (!lastModifiedWord) { + return; + } + + const originalLength1 = lastModifiedWord.s1Range.length - lastModifiedWord.deleted; + const originalLength2 = lastModifiedWord.s2Range.length - lastModifiedWord.added; + if (originalLength1 !== originalLength2) { + // TODO figure out why this happens + } + + if (Math.max(lastModifiedWord.deleted, lastModifiedWord.added) + (lastModifiedWord.count - 1) > originalLength1) { + additional.push(new SequenceDiff(lastModifiedWord.s1Range, lastModifiedWord.s2Range)); + } + + lastModifiedWord = undefined; + } + + for (const s of sequenceDiffs) { + function processWord(s1Range: OffsetRange, s2Range: OffsetRange) { + if (!lastModifiedWord || !lastModifiedWord.s1Range.containsRange(s1Range) || !lastModifiedWord.s2Range.containsRange(s2Range)) { + if (lastModifiedWord && !(lastModifiedWord.s1Range.endExclusive < s1Range.start && lastModifiedWord.s2Range.endExclusive < s2Range.start)) { + const s1Added = OffsetRange.tryCreate(lastModifiedWord.s1Range.endExclusive, s1Range.start); + const s2Added = OffsetRange.tryCreate(lastModifiedWord.s2Range.endExclusive, s2Range.start); + lastModifiedWord.deleted += s1Added?.length ?? 0; + lastModifiedWord.added += s2Added?.length ?? 0; + + lastModifiedWord.s1Range = lastModifiedWord.s1Range.join(s1Range); + lastModifiedWord.s2Range = lastModifiedWord.s2Range.join(s2Range); + } else { + maybePushWordToAdditional(); + lastModifiedWord = { added: 0, deleted: 0, count: 0, s1Range: s1Range, s2Range: s2Range }; + } + } + + const changedS1 = s1Range.intersect(s.seq1Range); + const changedS2 = s2Range.intersect(s.seq2Range); + lastModifiedWord.count++; + lastModifiedWord.deleted += changedS1?.length ?? 0; + lastModifiedWord.added += changedS2?.length ?? 0; + } + + const w1Before = sequence1.findWordContaining(s.seq1Range.start - 1); + const w2Before = sequence2.findWordContaining(s.seq2Range.start - 1); + + const w1After = sequence1.findWordContaining(s.seq1Range.endExclusive); + const w2After = sequence2.findWordContaining(s.seq2Range.endExclusive); + + if (w1Before && w1After && w2Before && w2After && w1Before.equals(w1After) && w2Before.equals(w2After)) { + processWord(w1Before, w2Before); + } else { + if (w1Before && w2Before) { + processWord(w1Before, w2Before); + } + if (w1After && w2After) { + processWord(w1After, w2After); + } + } + } + + maybePushWordToAdditional(); + + const merged = mergeSequenceDiffs(sequenceDiffs, additional); + return merged; +} + +function mergeSequenceDiffs(sequenceDiffs1: SequenceDiff[], sequenceDiffs2: SequenceDiff[]): SequenceDiff[] { + const result: SequenceDiff[] = []; + + while (sequenceDiffs1.length > 0 || sequenceDiffs2.length > 0) { + const sd1 = sequenceDiffs1[0]; + const sd2 = sequenceDiffs2[0]; + + let next: SequenceDiff; + if (sd1 && (!sd2 || sd1.seq1Range.start < sd2.seq1Range.start)) { + next = sequenceDiffs1.shift()!; + } else { + next = sequenceDiffs2.shift()!; + } + + if (result.length > 0 && result[result.length - 1].seq1Range.endExclusive >= next.seq1Range.start) { + result[result.length - 1] = result[result.length - 1].join(next); + } else { + result.push(next); + } + } + + return result; +} + +export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[]): LineRangeMapping[] { const changes: LineRangeMapping[] = []; for (const g of group( - alignments, + alignments.map(a => getLineRangeMapping(a, originalLines, modifiedLines)), (a1, a2) => - (a2.originalRange.startLineNumber - (a1.originalRange.endLineNumber - (a1.originalRange.endColumn > 1 ? 0 : 1)) <= 1) - || (a2.modifiedRange.startLineNumber - (a1.modifiedRange.endLineNumber - (a1.modifiedRange.endColumn > 1 ? 0 : 1)) <= 1) + a1.originalRange.overlapOrTouch(a2.originalRange) + || a1.modifiedRange.overlapOrTouch(a2.modifiedRange) )) { const first = g[0]; const last = g[g.length - 1]; changes.push(new LineRangeMapping( - new LineRange( - first.originalRange.startLineNumber, - last.originalRange.endLineNumber + (last.originalRange.endColumn > 1 || last.modifiedRange.endColumn > 1 ? 1 : 0) - ), - new LineRange( - first.modifiedRange.startLineNumber, - last.modifiedRange.endLineNumber + (last.originalRange.endColumn > 1 || last.modifiedRange.endColumn > 1 ? 1 : 0) - ), - g + first.originalRange.join(last.originalRange), + first.modifiedRange.join(last.modifiedRange), + g.map(a => a.innerChanges![0]), )); } @@ -162,10 +271,42 @@ export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[]): L ); }); - return changes; } +export function getLineRangeMapping(rangeMapping: RangeMapping, originalLines: string[], modifiedLines: string[]): LineRangeMapping { + let lineStartDelta = 0; + let lineEndDelta = 0; + + // rangeMapping describes the edit that replaces `rangeMapping.originalRange` with `newText := getText(modifiedLines, rangeMapping.modifiedRange)`. + + // original: xxx[ \n <- this line is not modified + // modified: xxx[ \n + if (rangeMapping.modifiedRange.startColumn - 1 >= modifiedLines[rangeMapping.modifiedRange.startLineNumber - 1].length + && rangeMapping.originalRange.startColumn - 1 >= originalLines[rangeMapping.originalRange.startLineNumber - 1].length) { + lineStartDelta = 1; // +1 is always possible, as startLineNumber < endLineNumber + 1 + } + + // original: ]xxx \n <- this line is not modified + // modified: ]xx \n + if (rangeMapping.modifiedRange.endColumn === 1 && rangeMapping.originalRange.endColumn === 1 + && rangeMapping.originalRange.startLineNumber + lineStartDelta <= rangeMapping.originalRange.endLineNumber + && rangeMapping.modifiedRange.startLineNumber + lineStartDelta <= rangeMapping.modifiedRange.endLineNumber) { + lineEndDelta = -1; // We can only do this if the range is not empty yet + } + + const originalLineRange = new LineRange( + rangeMapping.originalRange.startLineNumber + lineStartDelta, + rangeMapping.originalRange.endLineNumber + 1 + lineEndDelta + ); + const modifiedLineRange = new LineRange( + rangeMapping.modifiedRange.startLineNumber + lineStartDelta, + rangeMapping.modifiedRange.endLineNumber + 1 + lineEndDelta + ); + + return new LineRangeMapping(originalLineRange, modifiedLineRange, [rangeMapping]); +} + function* group(items: Iterable, shouldBeGrouped: (item1: T, item2: T) => boolean): Iterable { let currentGroup: T[] | undefined; let last: T | undefined; @@ -215,34 +356,56 @@ function getIndentation(str: string): number { } class Slice implements ISequence { - private readonly elements: Int32Array; - private readonly firstCharOnLineOffsets: Int32Array; + private readonly elements: number[] = []; + private readonly firstCharOffsetByLineMinusOne: number[] = []; + public readonly lineRange: OffsetRange; + // To account for trimming + private readonly offsetByLine: number[] = []; - constructor(public readonly lines: string[], public readonly lineRange: OffsetRange) { - let chars = 0; - this.firstCharOnLineOffsets = new Int32Array(lineRange.length); + 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) + // (Unless it covers the entire document, in that case the other slice also has to cover the entire document ands it's okay) - for (let i = lineRange.start; i < lineRange.endExclusive; i++) { - const line = lines[i]; - chars += line.length; - this.firstCharOnLineOffsets[i - lineRange.start] = chars + 1; - chars++; + // If the slice covers the end, but does not start at the beginning, we include just the \n of the previous line. + let trimFirstLineFully = false; + if (lineRange.start > 0 && lineRange.endExclusive >= lines.length) { + lineRange = new OffsetRange(lineRange.start - 1, lineRange.endExclusive); + trimFirstLineFully = true; } - this.elements = new Int32Array(chars); - let offset = 0; - for (let i = lineRange.start; i < lineRange.endExclusive; i++) { - const line = lines[i]; + this.lineRange = lineRange; + + for (let i = this.lineRange.start; i < this.lineRange.endExclusive; i++) { + let line = lines[i]; + let offset = 0; + if (trimFirstLineFully) { + offset = line.length; + line = ''; + trimFirstLineFully = false; + } else if (!considerWhitespaceChanges) { + const trimmedStartLine = line.trimStart(); + offset = line.length - trimmedStartLine.length; + line = trimmedStartLine.trimEnd(); + } + + this.offsetByLine.push(offset); for (let i = 0; i < line.length; i++) { - this.elements[offset + i] = line.charCodeAt(i); + this.elements.push(line.charCodeAt(i)); } - offset += line.length; + + // Don't add an \n that does not exist in the document. if (i < lines.length - 1) { - this.elements[offset] = '\n'.charCodeAt(0); - offset += 1; + this.elements.push('\n'.charCodeAt(0)); + this.firstCharOffsetByLineMinusOne[i - this.lineRange.start] = this.elements.length; } } + // To account for the last line + this.offsetByLine.push(0); + } + + toString() { + return `Slice: "${this.text}"`; } get text(): string { @@ -284,26 +447,62 @@ class Slice implements ISequence { } public translateOffset(offset: number): Position { - // find smallest i, so that lineBreakOffsets[i] > offset using binary search + // find smallest i, so that lineBreakOffsets[i] <= offset using binary search + if (this.lineRange.isEmpty) { + return new Position(this.lineRange.start + 1, 1); + } let i = 0; - let j = this.firstCharOnLineOffsets.length; + let j = this.firstCharOffsetByLineMinusOne.length; while (i < j) { const k = Math.floor((i + j) / 2); - if (this.firstCharOnLineOffsets[k] > offset) { + if (this.firstCharOffsetByLineMinusOne[k] > offset) { j = k; } else { i = k + 1; } } - const offsetOfPrevLineBreak = i === 0 ? 0 : this.firstCharOnLineOffsets[i - 1]; - return new Position(i + 1, offset - offsetOfPrevLineBreak + 1); + const offsetOfPrevLineBreak = i === 0 ? 0 : this.firstCharOffsetByLineMinusOne[i - 1]; + return new Position(this.lineRange.start + i + 1, offset - offsetOfPrevLineBreak + 1 + this.offsetByLine[i]); } public translateRange(range: OffsetRange): Range { return Range.fromPositions(this.translateOffset(range.start), this.translateOffset(range.endExclusive)); } + + /** + * Finds the word that contains the character at the given offset + */ + public findWordContaining(offset: number): OffsetRange | undefined { + if (offset < 0 || offset >= this.elements.length) { + return undefined; + } + + if (!isWordChar(this.elements[offset])) { + return undefined; + } + + // find start + let start = offset; + while (start > 0 && isWordChar(this.elements[start - 1])) { + start--; + } + + // find end + let end = offset; + while (end < this.elements.length && isWordChar(this.elements[end])) { + end++; + } + + return new OffsetRange(start, end); + } +} + +function isWordChar(charCode: number): boolean { + return charCode >= CharCode.a && charCode <= CharCode.z + || charCode >= CharCode.A && charCode <= CharCode.Z + || charCode >= CharCode.Digit0 && charCode <= CharCode.Digit9; } const enum CharBoundaryCategory { diff --git a/src/vs/editor/common/editorAction.ts b/src/vs/editor/common/editorAction.ts index 055a67fbd15..5cf40416a1e 100644 --- a/src/vs/editor/common/editorAction.ts +++ b/src/vs/editor/common/editorAction.ts @@ -13,7 +13,7 @@ export class InternalEditorAction implements IEditorAction { public readonly alias: string; private readonly _precondition: ContextKeyExpression | undefined; - private readonly _run: () => Promise; + private readonly _run: (args: unknown) => Promise; private readonly _contextKeyService: IContextKeyService; constructor( @@ -36,11 +36,11 @@ export class InternalEditorAction implements IEditorAction { return this._contextKeyService.contextMatchesRules(this._precondition); } - public run(): Promise { + public run(args: unknown): Promise { if (!this.isSupported()) { return Promise.resolve(undefined); } - return this._run(); + return this._run(args); } } diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 3b10a9f14d9..0cb62fbcb3c 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -150,7 +150,7 @@ export interface IEditorAction { readonly label: string; readonly alias: string; isSupported(): boolean; - run(): Promise; + run(args?: unknown): Promise; } export type IEditorModel = ITextModel | IDiffEditorModel; diff --git a/src/vs/editor/common/editorContextKeys.ts b/src/vs/editor/common/editorContextKeys.ts index 11c78368665..c4331b97632 100644 --- a/src/vs/editor/common/editorContextKeys.ts +++ b/src/vs/editor/common/editorContextKeys.ts @@ -39,6 +39,10 @@ export namespace EditorContextKeys { export const canRedo = new RawContextKey('canRedo', false, true); export const hoverVisible = new RawContextKey('editorHoverVisible', false, nls.localize('editorHoverVisible', "Whether the editor hover is visible")); + export const hoverFocused = new RawContextKey('editorHoverFocused', false, nls.localize('editorHoverFocused', "Whether the editor hover is focused")); + + export const stickyScrollFocused = new RawContextKey('stickyScrollFocused', false, nls.localize('stickyScrollFocused', "Whether the sticky scroll is focused")); + export const stickyScrollVisible = new RawContextKey('stickyScrollVisible', false, nls.localize('stickyScrollVisible', "Whether the sticky scroll is visible")); /** * A context key that is set when an editor is part of a larger editor, like notebooks or diff --git a/src/vs/editor/common/editorFeatures.ts b/src/vs/editor/common/editorFeatures.ts new file mode 100644 index 00000000000..99d29778303 --- /dev/null +++ b/src/vs/editor/common/editorFeatures.ts @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { BrandedService, IConstructorSignature } from 'vs/platform/instantiation/common/instantiation'; + +/** + * A feature that will be loaded when the first code editor is constructed and disposed when the system shuts down. + */ +export interface IEditorFeature { + // Marker Interface +} + +export type EditorFeatureCtor = IConstructorSignature; + +const editorFeatures: EditorFeatureCtor[] = []; + +/** + * Registers an editor feature. Editor features will be instantiated only once, as soon as + * the first code editor is instantiated. + */ +export function registerEditorFeature(ctor: { new(...services: Services): IEditorFeature }): void { + editorFeatures.push(ctor as EditorFeatureCtor); +} + +export function getEditorFeatures(): Iterable { + return editorFeatures.slice(0); +} diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 724c1538276..9961a324c1c 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -1599,7 +1599,7 @@ export interface CommentThread { extensionId?: string; threadId: string; resource: string | null; - range: T; + range: T | undefined; label: string | undefined; contextValue: string | undefined; comments: Comment[] | undefined; @@ -1611,7 +1611,7 @@ export interface CommentThread { canReply: boolean; input?: CommentInput; onDidChangeInput: Event; - onDidChangeRange: Event; + onDidChangeRange: Event; onDidChangeLabel: Event; onDidChangeCollapsibleState: Event; onDidChangeState: Event; @@ -1627,6 +1627,7 @@ export interface CommentThread { export interface CommentingRanges { readonly resource: URI; ranges: IRange[]; + fileComments: boolean; } /** @@ -1663,6 +1664,14 @@ export enum CommentMode { Preview = 1 } +/** + * @internal + */ +export enum CommentState { + Published = 0, + Draft = 1 +} + /** * @internal */ @@ -1670,7 +1679,7 @@ export interface Comment { readonly uniqueIdInThread: number; readonly body: string | IMarkdownString; readonly userName: string; - readonly userIconPath?: string; + readonly userIconPath?: UriComponents; readonly contextValue?: string; readonly commentReactions?: CommentReaction[]; readonly label?: string; @@ -1795,8 +1804,35 @@ export interface ITokenizationSupportChangedEvent { /** * @internal */ -export interface ITokenizationSupportFactory { - createTokenizationSupport(): ProviderResult; +export interface ILazyTokenizationSupport { + get tokenizationSupport(): Promise; +} + +/** + * @internal + */ +export class LazyTokenizationSupport implements IDisposable, ILazyTokenizationSupport { + private _tokenizationSupport: Promise | null = null; + + constructor(private readonly createSupport: () => Promise) { + } + + dispose(): void { + if (this._tokenizationSupport) { + this._tokenizationSupport.then((support) => { + if (support) { + support.dispose(); + } + }); + } + } + + get tokenizationSupport(): Promise { + if (!this._tokenizationSupport) { + this._tokenizationSupport = this.createSupport(); + } + return this._tokenizationSupport; + } } /** @@ -1815,7 +1851,7 @@ export interface ITokenizationRegistry { * Fire a change event for a language. * This is useful for languages that embed other languages. */ - fire(languageIds: string[]): void; + handleChange(languageIds: string[]): void; /** * Register a tokenization support. @@ -1825,7 +1861,7 @@ export interface ITokenizationRegistry { /** * Register a tokenization support factory. */ - registerFactory(languageId: string, factory: ITokenizationSupportFactory): IDisposable; + registerFactory(languageId: string, factory: ILazyTokenizationSupport): IDisposable; /** * Get or create the tokenization support for a language. diff --git a/src/vs/editor/common/languages/language.ts b/src/vs/editor/common/languages/language.ts index a6c22e78ae2..f0be928ea73 100644 --- a/src/vs/editor/common/languages/language.ts +++ b/src/vs/editor/common/languages/language.ts @@ -50,9 +50,23 @@ export interface ILanguageService { readonly languageIdCodec: ILanguageIdCodec; /** - * An event emitted when a language is needed for the first time. + * An event emitted when basic language features are requested for the first time. + * This event is emitted when embedded languages are encountered (e.g. JS code block inside Markdown) + * or when a language is associated to a text model. + * + * **Note**: Basic language features refers to language configuration related features. + * **Note**: This event is a superset of `onDidRequestRichLanguageFeatures` */ - onDidEncounterLanguage: Event; + onDidRequestBasicLanguageFeatures: Event; + + /** + * An event emitted when rich language features are requested for the first time. + * This event is emitted when a language is associated to a text model. + * + * **Note**: Rich language features refers to tokenizers, language features based on providers, etc. + * **Note**: This event is a subset of `onDidRequestRichLanguageFeatures` + */ + onDidRequestRichLanguageFeatures: Event; /** * An event emitted when languages have changed. @@ -140,4 +154,15 @@ export interface ILanguageService { * Will fall back to 'plaintext' if the `languageId` cannot be determined. */ createByFilepathOrFirstLine(resource: URI | null, firstLine?: string): ILanguageSelection; + + /** + * Request basic language features for a language. + */ + requestBasicLanguageFeatures(languageId: string): void; + + /** + * Request rich language features for a language. + */ + requestRichLanguageFeatures(languageId: string): void; + } diff --git a/src/vs/editor/common/languages/linkComputer.ts b/src/vs/editor/common/languages/linkComputer.ts index d80b29c6501..52f4eaee2fb 100644 --- a/src/vs/editor/common/languages/linkComputer.ts +++ b/src/vs/editor/common/languages/linkComputer.ts @@ -155,12 +155,12 @@ function getClassifier(): CharacterClassifier { _classifier = new CharacterClassifier(CharacterClass.None); // allow-any-unicode-next-line - const FORCE_TERMINATION_CHARACTERS = ', \t<>\'\"ã€ã€‚。、,.:;‘〈「『〔([{「」ï½ï¼½ï¼‰ã€•ã€ã€ã€‰â€™ï½€ï½žâ€¦'; + const FORCE_TERMINATION_CHARACTERS = ' \t<>\'\"ã€ã€‚。、,.:;‘〈「『〔([{「」ï½ï¼½ï¼‰ã€•ã€ã€ã€‰â€™ï½€ï½žâ€¦'; for (let i = 0; i < FORCE_TERMINATION_CHARACTERS.length; i++) { _classifier.set(FORCE_TERMINATION_CHARACTERS.charCodeAt(i), CharacterClass.ForceTermination); } - const CANNOT_END_WITH_CHARACTERS = '.;:'; + const CANNOT_END_WITH_CHARACTERS = '.,;:'; for (let i = 0; i < CANNOT_END_WITH_CHARACTERS.length; i++) { _classifier.set(CANNOT_END_WITH_CHARACTERS.charCodeAt(i), CharacterClass.CannotEndIn); } diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index 0df35045e97..d856441c0d9 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -22,6 +22,7 @@ import { IGuidesTextModelPart } from 'vs/editor/common/textModelGuides'; import { ITokenizationTextModelPart } from 'vs/editor/common/tokenizationTextModelPart'; import { ThemeColor } from 'vs/base/common/themables'; import { UndoRedoGroup } from 'vs/platform/undoRedo/common/undoRedo'; +import { ILanguageSelection } from 'vs/editor/common/languages/language'; /** * Vertical Lane in the overview ruler of the editor. @@ -98,6 +99,9 @@ export interface IModelDecorationOptions { * In this case, the range must be empty and set to the last line. */ blockIsAfterEnd?: boolean | null; + blockDoesNotCollapse?: boolean | null; + blockPadding?: [top: number, right: number, bottom: number, left: number] | null; + /** * Message to be rendered when hovering over the glyph margin decoration. */ @@ -871,7 +875,15 @@ export interface ITextModel { * @param source The source of the call that set the language. * @internal */ - setMode(languageId: string, source?: string): void; + setLanguage(languageId: string, source?: string): void; + + /** + * Set the current language mode associated with the model. + * @param languageSelection The new language selection. + * @param source The source of the call that set the language. + * @internal + */ + setLanguage(languageSelection: ILanguageSelection, source?: string): void; /** * Returns the real (inner-most) language mode at a given position. diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/ast.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/ast.ts index cbabd157db0..e304dd1faa9 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/ast.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/ast.ts @@ -388,7 +388,7 @@ class TwoThreeListAstNode extends ListAstNode { } throw new Error('Invalid child index'); } - public setChild(idx: number, node: AstNode): void { + protected setChild(idx: number, node: AstNode): void { switch (idx) { case 0: this._item1 = node; return; case 1: this._item2 = node; return; @@ -506,7 +506,7 @@ class ArrayListAstNode extends ListAstNode { getChild(idx: number): AstNode | null { return this._children[idx]; } - setChild(idx: number, child: AstNode): void { + protected setChild(idx: number, child: AstNode): void { this._children[idx] = child; } get children(): readonly AstNode[] { diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper.ts index 162509bed20..a985d961511 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper.ts @@ -12,6 +12,10 @@ export class TextEditInfo { public readonly newLength: Length ) { } + + toString(): string { + return `[${lengthToObj(this.startOffset)}...${lengthToObj(this.endOffset)}) -> ${lengthToObj(this.newLength)}`; + } } export class BeforeEditPositionMapper { diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos.ts index 218ff36b6a3..29cf5a65271 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos.ts @@ -5,92 +5,53 @@ import { ArrayQueue } from 'vs/base/common/arrays'; import { TextEditInfo } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper'; -import { Length, lengthAdd, lengthDiffNonNegative, lengthEquals, lengthIsZero, lengthLessThanEqual, lengthZero, sumLengths } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length'; +import { Length, lengthAdd, lengthDiffNonNegative, lengthEquals, lengthIsZero, lengthToObj, lengthZero, sumLengths } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length'; export function combineTextEditInfos(textEditInfoFirst: TextEditInfo[], textEditInfoSecond: TextEditInfo[]): TextEditInfo[] { if (textEditInfoFirst.length === 0) { return textEditInfoSecond; } + if (textEditInfoSecond.length === 0) { + return textEditInfoFirst; + } // s0: State before any edits - const firstMap = new ArrayQueue(toTextMap(textEditInfoFirst)); + const s0ToS1Map = new ArrayQueue(toLengthMapping(textEditInfoFirst)); // s1: State after first edit, but before second edit - const secondMap = toTextMap(textEditInfoSecond); + const s1ToS2Map = toLengthMapping(textEditInfoSecond) as (LengthMapping | { lengthBefore: undefined; lengthAfter: undefined; modified: false })[]; + s1ToS2Map.push({ modified: false, lengthBefore: undefined, lengthAfter: undefined }); // Copy everything from old to new // s2: State after both edits - // If set, we are in an edit - let remainingS0Length: Length | undefined = undefined; - let remainingS1Length: Length = lengthZero; + let curItem: LengthMapping | undefined = s0ToS1Map.dequeue(); /** * @param s1Length Use undefined for length "infinity" */ - function readPartialS0Map(s1Length: Length | undefined): TextMapping[] { - const result: TextMapping[] = []; - - while (true) { - if ((remainingS0Length !== undefined && !lengthIsZero(remainingS0Length)) || !lengthIsZero(remainingS1Length)) { - let readS1Length: Length; - if (s1Length !== undefined && lengthLessThanEqual(s1Length, remainingS1Length)) { - // remaining satisfies request - readS1Length = s1Length; - remainingS1Length = lengthDiffNonNegative(s1Length, remainingS1Length); - s1Length = lengthZero; - } else { - // Read all of remaining, potentially even more - readS1Length = remainingS1Length; - if (s1Length !== undefined) { - s1Length = lengthDiffNonNegative(remainingS1Length, s1Length); - } - remainingS1Length = lengthZero; - } - - if (remainingS0Length === undefined) { - // unchanged area - result.push({ - oldLength: readS1Length, - newLength: undefined - }); - } else { - // We eagerly consume all of the old length, even if - // we are in an edit and only consume it partially. - result.push({ - oldLength: remainingS0Length, - newLength: readS1Length - }); - remainingS0Length = lengthZero; - } - } - - if (s1Length !== undefined && lengthIsZero(s1Length)) { - break; - } - - const item = firstMap.dequeue(); - if (!item) { - if (s1Length !== undefined) { - result.push({ - oldLength: s1Length, - newLength: undefined, - }); - } - break; - } - if (item.newLength === undefined) { - remainingS1Length = item.oldLength; - remainingS0Length = undefined; - } else { - remainingS0Length = item.oldLength; - remainingS1Length = item.newLength; + function nextS0ToS1MapWithS1LengthOf(s1Length: Length | undefined): LengthMapping[] { + if (s1Length === undefined) { + const arr = s0ToS1Map.takeWhile(v => true) || []; + if (curItem) { + arr.unshift(curItem); } + return arr; } + const result: LengthMapping[] = []; + while (curItem && !lengthIsZero(s1Length)) { + const [item, remainingItem] = curItem.splitAt(s1Length); + result.push(item); + s1Length = lengthDiffNonNegative(item.lengthAfter, s1Length); + curItem = remainingItem ?? s0ToS1Map.dequeue(); + } + if (!lengthIsZero(s1Length)) { + result.push(new LengthMapping(false, s1Length, s1Length)); + } return result; } const result: TextEditInfo[] = []; - function push(startOffset: Length, endOffset: Length, newLength: Length) { + function pushEdit(startOffset: Length, endOffset: Length, newLength: Length): void { if (result.length > 0 && lengthEquals(result[result.length - 1].endOffset, startOffset)) { const lastResult = result[result.length - 1]; result[result.length - 1] = new TextEditInfo(lastResult.startOffset, endOffset, lengthAdd(lastResult.newLength, newLength)); @@ -100,61 +61,71 @@ export function combineTextEditInfos(textEditInfoFirst: TextEditInfo[], textEdit } let s0offset = lengthZero; - for (const s2 of secondMap) { - const s0ToS1Map = readPartialS0Map(s2.oldLength); - if (s2.newLength !== undefined) { - // This is an edit - const s0Length = sumLengths(s0ToS1Map, s => s.oldLength); + for (const s1ToS2 of s1ToS2Map) { + const s0ToS1Map = nextS0ToS1MapWithS1LengthOf(s1ToS2.lengthBefore); + if (s1ToS2.modified) { + const s0Length = sumLengths(s0ToS1Map, s => s.lengthBefore); const s0EndOffset = lengthAdd(s0offset, s0Length); - push(s0offset, s0EndOffset, s2.newLength); + pushEdit(s0offset, s0EndOffset, s1ToS2.lengthAfter); s0offset = s0EndOffset; } else { - // We are in an unchanged area for (const s1 of s0ToS1Map) { const s0startOffset = s0offset; - s0offset = lengthAdd(s0offset, s1.oldLength); - - if (s1.newLength !== undefined) { - push(s0startOffset, s0offset, s1.newLength); + s0offset = lengthAdd(s0offset, s1.lengthBefore); + if (s1.modified) { + pushEdit(s0startOffset, s0offset, s1.lengthAfter); } } } } - const s0ToS1Map = readPartialS0Map(undefined); - for (const s1 of s0ToS1Map) { - const s0startOffset = s0offset; - s0offset = lengthAdd(s0offset, s1.oldLength); - - if (s1.newLength !== undefined) { - push(s0startOffset, s0offset, s1.newLength); - } - } - return result; } -interface TextMapping { - oldLength: Length; +class LengthMapping { + constructor( + /** + * If false, length before and length after equal. + */ + public readonly modified: boolean, + public readonly lengthBefore: Length, + public readonly lengthAfter: Length, + ) { + } - /** - * If set, this mapping represents an edit. - * If not set, this mapping represents an unchanged region (for which the new length equals the old length). - */ - newLength?: Length; + splitAt(lengthAfter: Length): [LengthMapping, LengthMapping | undefined] { + const remainingLengthAfter = lengthDiffNonNegative(lengthAfter, this.lengthAfter); + if (lengthEquals(remainingLengthAfter, lengthZero)) { + return [this, undefined]; + } else if (this.modified) { + return [ + new LengthMapping(this.modified, this.lengthBefore, lengthAfter), + new LengthMapping(this.modified, lengthZero, remainingLengthAfter) + ]; + } else { + return [ + new LengthMapping(this.modified, lengthAfter, lengthAfter), + new LengthMapping(this.modified, remainingLengthAfter, remainingLengthAfter) + ]; + } + } + + toString(): string { + return `${this.modified ? 'M' : 'U'}:${lengthToObj(this.lengthBefore)} -> ${lengthToObj(this.lengthAfter)}`; + } } -function toTextMap(textEditInfos: TextEditInfo[]): TextMapping[] { - const result: TextMapping[] = []; +function toLengthMapping(textEditInfos: TextEditInfo[]): LengthMapping[] { + const result: LengthMapping[] = []; let lastOffset = lengthZero; for (const textEditInfo of textEditInfos) { const spaceLength = lengthDiffNonNegative(lastOffset, textEditInfo.startOffset); if (!lengthIsZero(spaceLength)) { - result.push({ oldLength: spaceLength }); + result.push(new LengthMapping(false, spaceLength, spaceLength)); } - const oldLength = lengthDiffNonNegative(textEditInfo.startOffset, textEditInfo.endOffset); - result.push({ oldLength, newLength: textEditInfo.newLength }); + const lengthBefore = lengthDiffNonNegative(textEditInfo.startOffset, textEditInfo.endOffset); + result.push(new LengthMapping(true, lengthBefore, textEditInfo.newLength)); lastOffset = textEditInfo.endOffset; } return result; diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length.ts index 0b72d9dbf31..564cd5ab4b7 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length.ts @@ -238,3 +238,7 @@ export function lengthOfStringObj(str: string): LengthObj { export function lengthHash(length: Length): number { return length as any; } + +export function lengthMax(length1: Length, length2: Length): Length { + return length1 > length2 ? length1 : length2; +} diff --git a/src/vs/editor/common/model/fixedArray.ts b/src/vs/editor/common/model/fixedArray.ts new file mode 100644 index 00000000000..1d57ce2914b --- /dev/null +++ b/src/vs/editor/common/model/fixedArray.ts @@ -0,0 +1,77 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { arrayInsert } from 'vs/base/common/arrays'; + +/** + * An array that avoids being sparse by always + * filling up unused indices with a default value. + */ +export class FixedArray { + private _store: T[] = []; + + constructor( + private readonly _default: T + ) { } + + public get(index: number): T { + if (index < this._store.length) { + return this._store[index]; + } + return this._default; + } + + public set(index: number, value: T): void { + while (index >= this._store.length) { + this._store[this._store.length] = this._default; + } + this._store[index] = value; + } + + public replace(index: number, oldLength: number, newLength: number): void { + if (index >= this._store.length) { + return; + } + + if (oldLength === 0) { + this.insert(index, newLength); + return; + } else if (newLength === 0) { + this.delete(index, oldLength); + return; + } + + const before = this._store.slice(0, index); + const after = this._store.slice(index + oldLength); + const insertArr = arrayFill(newLength, this._default); + this._store = before.concat(insertArr, after); + } + + public delete(deleteIndex: number, deleteCount: number): void { + if (deleteCount === 0 || deleteIndex >= this._store.length) { + return; + } + this._store.splice(deleteIndex, deleteCount); + } + + public insert(insertIndex: number, insertCount: number): void { + if (insertCount === 0 || insertIndex >= this._store.length) { + return; + } + const arr: T[] = []; + for (let i = 0; i < insertCount; i++) { + arr[i] = this._default; + } + this._store = arrayInsert(this._store, insertIndex, arr); + } +} + +function arrayFill(length: number, value: T): T[] { + const arr: T[] = []; + for (let i = 0; i < length; i++) { + arr[i] = value; + } + return arr; +} diff --git a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts index 6afe8339c96..824a5674a32 100644 --- a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts +++ b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts @@ -141,16 +141,15 @@ export class PieceTreeTextBufferBuilder implements ITextBufferBuilder { this.lf += lineStarts.lf; this.crlf += lineStarts.crlf; - if (this.isBasicASCII) { - this.isBasicASCII = lineStarts.isBasicASCII; - } - if (!this.isBasicASCII && !this.containsRTL) { - // No need to check if it is basic ASCII - this.containsRTL = strings.containsRTL(chunk); - } - if (!this.isBasicASCII && !this.containsUnusualLineTerminators) { - // No need to check if it is basic ASCII - this.containsUnusualLineTerminators = strings.containsUnusualLineTerminators(chunk); + if (!lineStarts.isBasicASCII) { + // this chunk contains non basic ASCII characters + this.isBasicASCII = false; + if (!this.containsRTL) { + this.containsRTL = strings.containsRTL(chunk); + } + if (!this.containsUnusualLineTerminators) { + this.containsUnusualLineTerminators = strings.containsUnusualLineTerminators(chunk); + } } } diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index ac1a9821eb4..117837f855e 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -9,7 +9,7 @@ import { Color } from 'vs/base/common/color'; import { illegalArgument, onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { IMarkdownString } from 'vs/base/common/htmlContent'; -import { combinedDisposable, Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { combinedDisposable, Disposable, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { listenStream } from 'vs/base/common/stream'; import * as strings from 'vs/base/common/strings'; import { Constants } from 'vs/base/common/uint'; @@ -24,7 +24,7 @@ import { TextChange } from 'vs/editor/common/core/textChange'; import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/core/textModelDefaults'; import { IWordAtPosition } from 'vs/editor/common/core/wordHelper'; import { FormattingOptions } from 'vs/editor/common/languages'; -import { ILanguageService } from 'vs/editor/common/languages/language'; +import { ILanguageSelection, ILanguageService } from 'vs/editor/common/languages/language'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import * as model from 'vs/editor/common/model'; import { BracketPairsTextModelPart } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl'; @@ -243,6 +243,7 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati private _buffer: model.ITextBuffer; private _bufferDisposable: IDisposable; private _options: model.TextModelResolvedOptions; + private _languageSelectionListener = this._register(new MutableDisposable()); private _isDisposed: boolean; private __isDisposing: boolean; @@ -287,7 +288,7 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati constructor( source: string | model.ITextBufferFactory, - languageId: string, + languageIdOrSelection: string | ILanguageSelection, creationOptions: model.ITextModelCreationOptions, associatedResource: URI | null = null, @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, @@ -313,6 +314,11 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati this._options = TextModel.resolveOptions(this._buffer, creationOptions); + const languageId = (typeof languageIdOrSelection === 'string' ? languageIdOrSelection : languageIdOrSelection.languageId); + if (typeof languageIdOrSelection !== 'string') { + this._languageSelectionListener.value = languageIdOrSelection.onDidChange(() => this._setLanguage(languageIdOrSelection.languageId)); + } + this._bracketPairs = this._register(new BracketPairsTextModelPart(this, this._languageConfigurationService)); this._guidesTextModelPart = this._register(new GuidesTextModelPart(this, this._languageConfigurationService)); this._decorationProvider = this._register(new ColorizedBracketPairsDecorationProvider(this)); @@ -364,6 +370,8 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati this._onDidChangeDecorations.fire(); this._onDidChangeDecorations.endDeferredEmit(); })); + + this._languageService.requestRichLanguageFeatures(languageId); } public override dispose(): void { @@ -1905,8 +1913,19 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati return this.tokenization.getLanguageId(); } - public setMode(languageId: string, source?: string): void { + public setLanguage(languageIdOrSelection: string | ILanguageSelection, source?: string): void { + if (typeof languageIdOrSelection === 'string') { + this._languageSelectionListener.clear(); + this._setLanguage(languageIdOrSelection, source); + } else { + this._languageSelectionListener.value = languageIdOrSelection.onDidChange(() => this._setLanguage(languageIdOrSelection.languageId, source)); + this._setLanguage(languageIdOrSelection.languageId, source); + } + } + + private _setLanguage(languageId: string, source?: string): void { this.tokenization.setLanguageId(languageId, source); + this._languageService.requestRichLanguageFeatures(languageId); } public getLanguageIdAtPosition(lineNumber: number, column: number): string { @@ -2226,10 +2245,11 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions { public static createDynamic(options: model.IModelDecorationOptions): ModelDecorationOptions { return new ModelDecorationOptions(options); } - readonly description: string; readonly blockClassName: string | null; readonly blockIsAfterEnd: boolean | null; + readonly blockDoesNotCollapse?: boolean | null; + readonly blockPadding: [top: number, right: number, bottom: number, left: number] | null; readonly stickiness: model.TrackedRangeStickiness; readonly zIndex: number; readonly className: string | null; @@ -2253,11 +2273,12 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions { readonly hideInCommentTokens: boolean | null; readonly hideInStringTokens: boolean | null; - private constructor(options: model.IModelDecorationOptions) { this.description = options.description; this.blockClassName = options.blockClassName ? cleanClassName(options.blockClassName) : null; + this.blockDoesNotCollapse = options.blockDoesNotCollapse ?? null; this.blockIsAfterEnd = options.blockIsAfterEnd ?? null; + this.blockPadding = options.blockPadding ?? null; this.stickiness = options.stickiness || model.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges; this.zIndex = options.zIndex || 0; this.className = options.className ? cleanClassName(options.className) : null; diff --git a/src/vs/editor/common/model/textModelTokens.ts b/src/vs/editor/common/model/textModelTokens.ts index ebee591a042..1965a9a191d 100644 --- a/src/vs/editor/common/model/textModelTokens.ts +++ b/src/vs/editor/common/model/textModelTokens.ts @@ -3,22 +3,23 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as arrays from 'vs/base/common/arrays'; import { IdleDeadline, runWhenIdle } from 'vs/base/common/async'; import { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { setTimeout0 } from 'vs/base/common/platform'; import { StopWatch } from 'vs/base/common/stopwatch'; import { countEOL } from 'vs/editor/common/core/eolCounter'; +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 { IRange } from 'vs/editor/common/core/range'; import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; import { EncodedTokenizationResult, IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/languages'; import { nullTokenizeEncoded } from 'vs/editor/common/languages/nullTokenize'; import { ITextModel } from 'vs/editor/common/model'; +import { FixedArray } from 'vs/editor/common/model/fixedArray'; import { TextModel } from 'vs/editor/common/model/textModel'; import { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart'; -import { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents'; +import { IModelContentChange, IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents'; import { ContiguousMultilineTokensBuilder } from 'vs/editor/common/tokens/contiguousMultilineTokensBuilder'; import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; @@ -26,164 +27,8 @@ const enum Constants { CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048 } -/** - * An array that avoids being sparse by always - * filling up unused indices with a default value. - */ -class ContiguousGrowingArray { - - private _store: T[] = []; - - constructor( - private readonly _default: T - ) { } - - public get(index: number): T { - if (index < this._store.length) { - return this._store[index]; - } - return this._default; - } - - public set(index: number, value: T): void { - while (index >= this._store.length) { - this._store[this._store.length] = this._default; - } - this._store[index] = value; - } - - // TODO have `replace` instead of `delete` and `insert` - public delete(deleteIndex: number, deleteCount: number): void { - if (deleteCount === 0 || deleteIndex >= this._store.length) { - return; - } - this._store.splice(deleteIndex, deleteCount); - } - - public insert(insertIndex: number, insertCount: number): void { - if (insertCount === 0 || insertIndex >= this._store.length) { - return; - } - const arr: T[] = []; - for (let i = 0; i < insertCount; i++) { - arr[i] = this._default; - } - this._store = arrays.arrayInsert(this._store, insertIndex, arr); - } -} - -/** - * Stores the states at the start of each line and keeps track of which lines - * must be re-tokenized. Also uses state equality to quickly validate lines - * that don't need to be re-tokenized. - * - * For example, when typing on a line, the line gets marked as needing to be tokenized. - * Once the line is tokenized, the end state is checked for equality against the begin - * state of the next line. If the states are equal, tokenization doesn't need to run - * again over the rest of the file. If the states are not equal, the next line gets marked - * as needing to be tokenized. - */ -export class TokenizationStateStore { - - /** - * `lineBeginState[i]` contains the begin state used to tokenize line number `i + 1`. - */ - private readonly _lineBeginState = new ContiguousGrowingArray(null); - /** - * `lineNeedsTokenization[i]` describes if line number `i + 1` needs to be tokenized. - */ - private readonly _lineNeedsTokenization = new ContiguousGrowingArray(true); - /** - * `invalidLineStartIndex` indicates that line number `invalidLineStartIndex + 1` - * is the first one that needs to be re-tokenized. - */ - private _firstLineNeedsTokenization: number; - - public get invalidLineStartIndex() { - return this._firstLineNeedsTokenization; - } - - constructor( - public readonly tokenizationSupport: ITokenizationSupport, - public readonly initialState: IState - ) { - this._firstLineNeedsTokenization = 0; - this._lineBeginState.set(0, this.initialState); - } - - public markMustBeTokenized(lineIndex: number): void { - this._lineNeedsTokenization.set(lineIndex, true); - this._firstLineNeedsTokenization = Math.min(this._firstLineNeedsTokenization, lineIndex); - } - - public getBeginState(lineIndex: number): IState | null { - return this._lineBeginState.get(lineIndex); - } - - public setEndState(linesLength: number, lineIndex: number, endState: IState): boolean { - this._lineNeedsTokenization.set(lineIndex, false); - this._firstLineNeedsTokenization = lineIndex + 1; - - // Check if this was the last line - if (lineIndex === linesLength - 1) { - return false; - } - - // Check if the end state has changed - const previousEndState = this._lineBeginState.get(lineIndex + 1); - if (previousEndState === null || !endState.equals(previousEndState)) { - this._lineBeginState.set(lineIndex + 1, endState); - this.markMustBeTokenized(lineIndex + 1); - return true; - } - - // Perhaps we can skip tokenizing some lines... - let i = lineIndex + 1; - while (i < linesLength) { - if (this._lineNeedsTokenization.get(i)) { - break; - } - i++; - } - this._firstLineNeedsTokenization = i; - return false; - } - - public applyEdits(range: IRange, eolCount: number): void { - this.markMustBeTokenized(range.startLineNumber - 1); - - this._lineBeginState.delete(range.startLineNumber, range.endLineNumber - range.startLineNumber); - this._lineNeedsTokenization.delete(range.startLineNumber, range.endLineNumber - range.startLineNumber); - - this._lineBeginState.insert(range.startLineNumber, eolCount); - this._lineNeedsTokenization.insert(range.startLineNumber, eolCount); - } - - public updateTokensUntilLine(textModel: ITextModel, languageIdCodec: ILanguageIdCodec, builder: ContiguousMultilineTokensBuilder, lineNumber: number): void { - const languageId = textModel.getLanguageId(); - const linesLength = textModel.getLineCount(); - const endLineIndex = lineNumber - 1; - - // Validate all states up to and including endLineIndex - for (let lineIndex = this.invalidLineStartIndex; lineIndex <= endLineIndex; lineIndex++) { - const text = textModel.getLineContent(lineIndex + 1); - const lineStartState = this.getBeginState(lineIndex); - - const r = safeTokenize(languageIdCodec, languageId, this.tokenizationSupport, text, true, lineStartState!); - builder.add(lineIndex + 1, r.tokens); - this.setEndState(linesLength, lineIndex, r.endState); - lineIndex = this.invalidLineStartIndex - 1; // -1 because the outer loop increments it - } - } - - isTokenizationComplete(textModel: ITextModel): boolean { - return this.invalidLineStartIndex >= textModel.getLineCount(); - } -} - export class TextModelTokenization extends Disposable { - - private _tokenizationStateStore: TokenizationStateStore | null = null; + private _tokenizationStateStore: TokenizerWithStateStore | null = null; private _defaultBackgroundTokenizer: DefaultBackgroundTokenizer | null = null; private readonly backgroundTokenizer = this._register(new MutableDisposable()); @@ -214,11 +59,7 @@ export class TextModelTokenization extends Disposable { return; } if (this._tokenizationStateStore) { - for (let i = 0, len = e.changes.length; i < len; i++) { - const change = e.changes[i]; - const [eolCount] = countEOL(change.text); - this._tokenizationStateStore.applyEdits(change.range, eolCount); - } + this._tokenizationStateStore.store.acceptChanges(e.changes); } this._defaultBackgroundTokenizer?.handleChanges(); @@ -236,7 +77,7 @@ export class TextModelTokenization extends Disposable { private _resetTokenizationState(): void { const [tokenizationSupport, initialState] = initializeTokenization(this._textModel, this._tokenizationPart); if (tokenizationSupport && initialState) { - this._tokenizationStateStore = new TokenizationStateStore(tokenizationSupport, initialState); + this._tokenizationStateStore = new TokenizerWithStateStore(this._textModel.getLineCount(), tokenizationSupport); } else { this._tokenizationStateStore = null; } @@ -256,10 +97,10 @@ export class TextModelTokenization extends Disposable { if (!state) { throw new BugIndicatingError(); } - const invalidLineStartIndex = this._tokenizationStateStore?.invalidLineStartIndex; - if (invalidLineStartIndex !== undefined && lineNumber - 1 >= invalidLineStartIndex) { + const firstInvalidEndStateLineNumber = this._tokenizationStateStore?.store.getFirstInvalidEndStateLineNumber() ?? undefined; + if (firstInvalidEndStateLineNumber !== undefined && lineNumber >= firstInvalidEndStateLineNumber) { // Don't accept states for definitely valid states - this._tokenizationStateStore?.setEndState(this._textModel.getLineCount(), lineNumber - 1, state); + this._tokenizationStateStore?.store.setEndState(lineNumber, state); } }, }; @@ -305,7 +146,7 @@ export class TextModelTokenization extends Disposable { } this.forceTokenization(position.lineNumber); - const lineStartState = this._tokenizationStateStore.getBeginState(position.lineNumber - 1); + const lineStartState = this._tokenizationStateStore.getStartState(position.lineNumber); if (!lineStartState) { return StandardTokenType.Other; } @@ -339,7 +180,7 @@ export class TextModelTokenization extends Disposable { } this.forceTokenization(lineNumber); - const lineStartState = this._tokenizationStateStore.getBeginState(lineNumber - 1); + const lineStartState = this._tokenizationStateStore.getStartState(lineNumber); if (!lineStartState) { return null; } @@ -367,16 +208,12 @@ export class TextModelTokenization extends Disposable { return true; } - const firstInvalidLineNumber = this._tokenizationStateStore.invalidLineStartIndex + 1; - if (lineNumber > firstInvalidLineNumber) { - return false; - } - + const firstInvalidLineNumber = this._tokenizationStateStore.store.getFirstInvalidEndStateLineNumberOrMax(); if (lineNumber < firstInvalidLineNumber) { return true; } - - if (this._textModel.getLineLength(lineNumber) < Constants.CHEAP_TOKENIZATION_LENGTH_LIMIT) { + if (lineNumber === firstInvalidLineNumber + && this._textModel.getLineLength(lineNumber) < Constants.CHEAP_TOKENIZATION_LENGTH_LIMIT) { return true; } @@ -391,12 +228,12 @@ export class TextModelTokenization extends Disposable { // nothing to do return; } - if (endLineNumber <= this._tokenizationStateStore.invalidLineStartIndex) { + if (endLineNumber <= this._tokenizationStateStore.store.getFirstInvalidEndStateLineNumberOrMax()) { // nothing to do return; } - if (startLineNumber <= this._tokenizationStateStore.invalidLineStartIndex) { + if (startLineNumber <= this._tokenizationStateStore.store.getFirstInvalidEndStateLineNumberOrMax()) { // tokenization has reached the viewport start... this._tokenizationStateStore.updateTokensUntilLine(this._textModel, this._languageIdCodec, builder, endLineNumber); return; @@ -429,7 +266,7 @@ export class TextModelTokenization extends Disposable { if (newNonWhitespaceIndex < nonWhitespaceColumn) { likelyRelevantLines.push(this._textModel.getLineContent(i)); nonWhitespaceColumn = newNonWhitespaceIndex; - initialState = this._tokenizationStateStore!.getBeginState(i - 1); + initialState = this._tokenizationStateStore!.getStartState(i); if (initialState) { break; } @@ -437,7 +274,7 @@ export class TextModelTokenization extends Disposable { } if (!initialState) { - initialState = this._tokenizationStateStore!.initialState; + initialState = this._tokenizationStateStore!.tokenizationSupport.getInitialState(); } likelyRelevantLines.reverse(); @@ -451,6 +288,220 @@ export class TextModelTokenization extends Disposable { } } +export class TokenizerWithStateStore { + private readonly initialState = this.tokenizationSupport.getInitialState(); + + public readonly store: TrackingTokenizationStateStore; + + constructor( + lineCount: number, + public readonly tokenizationSupport: ITokenizationSupport + ) { + this.store = new TrackingTokenizationStateStore(lineCount); + } + + public getStartState(lineNumber: number): TState | null { + if (lineNumber === 1) { + return this.initialState as TState; + } + return this.store.getEndState(lineNumber - 1); + } + + public updateTokensUntilLine(textModel: ITextModel, languageIdCodec: ILanguageIdCodec, builder: ContiguousMultilineTokensBuilder, lineNumber: number): void { + const languageId = textModel.getLanguageId(); + + while (true) { + const nextLineNumber = this.store.getFirstInvalidEndStateLineNumber(); + if (!nextLineNumber || nextLineNumber > lineNumber) { + break; + } + + const text = textModel.getLineContent(nextLineNumber); + const lineStartState = this.getStartState(nextLineNumber); + + const r = safeTokenize(languageIdCodec, languageId, this.tokenizationSupport, text, true, lineStartState!); + builder.add(nextLineNumber, r.tokens); + this.store.setEndState(nextLineNumber, r.endState as TState); + } + } +} + +export class TrackingTokenizationStateStore { + private readonly tokenizationStateStore = new TokenizationStateStore(); + private readonly _invalidEndStatesLineNumbers = new RangePriorityQueueImpl(); + + constructor(private lineCount: number) { + this._invalidEndStatesLineNumbers.addRange(new OffsetRange(1, lineCount + 1)); + } + + public getEndState(lineNumber: number): TState | null { + return this.tokenizationStateStore.getEndState(lineNumber); + } + + public setEndState(lineNumber: number, state: TState): boolean { + while (true) { + const min = this._invalidEndStatesLineNumbers.min; + if (min !== null && min <= lineNumber) { + this._invalidEndStatesLineNumbers.removeMin(); + } else { + break; + } + } + + const r = this.tokenizationStateStore.setEndState(lineNumber, state); + if (r && lineNumber < this.lineCount) { + // because the state changed, we cannot trust the next state anymore and have to invalidate it. + this._invalidEndStatesLineNumbers.addRange(new OffsetRange(lineNumber + 1, lineNumber + 2)); + } + + return r; + } + + public acceptChange(range: LineRange, newLineCount: number): void { + this.lineCount += newLineCount - range.length; + this.tokenizationStateStore.acceptChange(range, newLineCount); + this._invalidEndStatesLineNumbers.addRangeAndResize(new OffsetRange(range.startLineNumber, range.endLineNumberExclusive), newLineCount); + } + + public acceptChanges(changes: IModelContentChange[]) { + for (const c of changes) { + const [eolCount] = countEOL(c.text); + this.acceptChange(new LineRange(c.range.startLineNumber, c.range.endLineNumber + 1), eolCount + 1); + } + } + + public invalidateEndStateRange(range: LineRange): void { + this._invalidEndStatesLineNumbers.addRange(new OffsetRange(range.startLineNumber, range.endLineNumberExclusive)); + } + + public getFirstInvalidEndStateLineNumber(): number | null { + return this._invalidEndStatesLineNumbers.min; + } + + public getFirstInvalidEndStateLineNumberOrMax(): number { + return this._invalidEndStatesLineNumbers.min || Number.MAX_SAFE_INTEGER; + } + + public isTokenizationComplete(): boolean { + return this._invalidEndStatesLineNumbers.min === null; + } +} + +export class TokenizationStateStore { + private readonly _lineEndStates = new FixedArray(null); + + public getEndState(lineNumber: number): TState | null { + return this._lineEndStates.get(lineNumber); + } + + public setEndState(lineNumber: number, state: TState): boolean { + const oldState = this._lineEndStates.get(lineNumber); + if (oldState && oldState.equals(state)) { + return false; + } + + this._lineEndStates.set(lineNumber, state); + return true; + } + + public acceptChange(range: LineRange, newLineCount: number): void { + let length = range.length; + if (newLineCount > 0 && length > 0) { + // Keep the last state, even though it is unrelated. + // But if the new state happens to agree with this last state, then we know we can stop tokenizing. + length--; + newLineCount--; + } + + this._lineEndStates.replace(range.startLineNumber, length, newLineCount); + } + + public acceptChanges(changes: IModelContentChange[]) { + for (const c of changes) { + const [eolCount] = countEOL(c.text); + this.acceptChange(new LineRange(c.range.startLineNumber, c.range.endLineNumber + 1), eolCount + 1); + } + } +} + +interface RangePriorityQueue { + get min(): number | null; + removeMin(): number | null; + + addRange(range: OffsetRange): void; + + addRangeAndResize(range: OffsetRange, newLength: number): void; +} + +export class RangePriorityQueueImpl implements RangePriorityQueue { + private readonly _ranges: OffsetRange[] = []; + + public getRanges(): OffsetRange[] { + return this._ranges; + } + + public get min(): number | null { + if (this._ranges.length === 0) { + return null; + } + return this._ranges[0].start; + } + + public removeMin(): number | null { + if (this._ranges.length === 0) { + return null; + } + const range = this._ranges[0]; + if (range.start + 1 === range.endExclusive) { + this._ranges.shift(); + } else { + this._ranges[0] = new OffsetRange(range.start + 1, range.endExclusive); + } + return range.start; + } + + public addRange(range: OffsetRange): void { + OffsetRange.addRange(range, this._ranges); + } + + public addRangeAndResize(range: OffsetRange, newLength: number): void { + let idxFirstMightBeIntersecting = 0; + while (!(idxFirstMightBeIntersecting >= this._ranges.length || range.start <= this._ranges[idxFirstMightBeIntersecting].endExclusive)) { + idxFirstMightBeIntersecting++; + } + let idxFirstIsAfter = idxFirstMightBeIntersecting; + while (!(idxFirstIsAfter >= this._ranges.length || range.endExclusive < this._ranges[idxFirstIsAfter].start)) { + idxFirstIsAfter++; + } + const delta = newLength - range.length; + + for (let i = idxFirstIsAfter; i < this._ranges.length; i++) { + this._ranges[i] = this._ranges[i].delta(delta); + } + + if (idxFirstMightBeIntersecting === idxFirstIsAfter) { + const newRange = new OffsetRange(range.start, range.start + newLength); + if (!newRange.isEmpty) { + this._ranges.splice(idxFirstMightBeIntersecting, 0, newRange); + } + } else { + const start = Math.min(range.start, this._ranges[idxFirstMightBeIntersecting].start); + const endEx = Math.max(range.endExclusive, this._ranges[idxFirstIsAfter - 1].endExclusive); + + const newRange = new OffsetRange(start, endEx + delta); + if (!newRange.isEmpty) { + this._ranges.splice(idxFirstMightBeIntersecting, idxFirstIsAfter - idxFirstMightBeIntersecting, newRange); + } else { + this._ranges.splice(idxFirstMightBeIntersecting, idxFirstIsAfter - idxFirstMightBeIntersecting); + } + } + } + + toString() { + return this._ranges.map(r => r.toString()).join(' + '); + } +} + function initializeTokenization(textModel: TextModel, tokenizationPart: TokenizationTextModelPart): [ITokenizationSupport, IState] | [null, null] { if (textModel.isTooLargeForTokenization()) { return [null, null]; @@ -493,7 +544,7 @@ class DefaultBackgroundTokenizer implements IBackgroundTokenizer { constructor( private readonly _textModel: ITextModel, - private readonly _stateStore: TokenizationStateStore, + private readonly _tokenizerWithStateStore: TokenizerWithStateStore, private readonly _backgroundTokenStore: IBackgroundTokenizationStore, private readonly _languageIdCodec: ILanguageIdCodec, ) { @@ -577,18 +628,18 @@ class DefaultBackgroundTokenizer implements IBackgroundTokenizer { } private _hasLinesToTokenize(): boolean { - if (!this._stateStore) { + if (!this._tokenizerWithStateStore) { return false; } - return this._stateStore.invalidLineStartIndex < this._textModel.getLineCount(); + return !this._tokenizerWithStateStore.store.isTokenizationComplete(); } private _tokenizeOneInvalidLine(builder: ContiguousMultilineTokensBuilder): number { - if (!this._stateStore || !this._hasLinesToTokenize()) { + if (!this._tokenizerWithStateStore || !this._hasLinesToTokenize()) { return this._textModel.getLineCount() + 1; } - const lineNumber = this._stateStore.invalidLineStartIndex + 1; - this._stateStore.updateTokensUntilLine(this._textModel, this._languageIdCodec, builder, lineNumber); + const lineNumber = this._tokenizerWithStateStore.store.getFirstInvalidEndStateLineNumber()!; + this._tokenizerWithStateStore.updateTokensUntilLine(this._textModel, this._languageIdCodec, builder, lineNumber); return lineNumber; } @@ -596,14 +647,12 @@ class DefaultBackgroundTokenizer implements IBackgroundTokenizer { if (this._isDisposed) { return; } - if (this._stateStore.isTokenizationComplete(this._textModel)) { + if (this._tokenizerWithStateStore.store.isTokenizationComplete()) { this._backgroundTokenStore.backgroundTokenizationFinished(); } } requestTokens(startLineNumber: number, endLineNumberExclusive: number): void { - for (let lineNumber = startLineNumber; lineNumber < endLineNumberExclusive; lineNumber++) { - this._stateStore.markMustBeTokenized(lineNumber - 1); - } + this._tokenizerWithStateStore.store.invalidateEndStateRange(new LineRange(startLineNumber, endLineNumberExclusive)); } } diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index 8864a766527..3dad1494c13 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -5,7 +5,6 @@ import { stringDiff } from 'vs/base/common/diff/diff'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { globals } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { IRequestHandler } from 'vs/base/common/worker/simpleWorker'; import { IPosition, Position } from 'vs/editor/common/core/position'; @@ -22,10 +21,11 @@ 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 { ILinesDiffComputer } from 'vs/editor/common/diff/linesDiffComputer'; +import { ILinesDiffComputer, ILinesDiffComputerOptions } from 'vs/editor/common/diff/linesDiffComputer'; import { linesDiffComputers } from 'vs/editor/common/diff/linesDiffComputers'; import { createProxyObject, getAllMethodNames } from 'vs/base/common/objects'; import { IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; +import { BugIndicatingError } from 'vs/base/common/errors'; export interface IMirrorModel extends IMirrorTextModel { readonly uri: URI; @@ -406,7 +406,7 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable { return { identical, - quitEarly: result.quitEarly, + quitEarly: result.hitTimeout, changes: result.changes.map(m => ([m.originalRange.startLineNumber, m.originalRange.endLineNumberExclusive, m.modifiedRange.startLineNumber, m.modifiedRange.endLineNumberExclusive, m.innerChanges?.map(m => [ m.originalRange.startLineNumber, m.originalRange.startColumn, @@ -462,7 +462,7 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable { private static readonly _diffLimit = 100000; - public async computeMoreMinimalEdits(modelUrl: string, edits: TextEdit[]): Promise { + public async computeMoreMinimalEdits(modelUrl: string, edits: TextEdit[], pretty: boolean): Promise { const model = this._getModel(modelUrl); if (!model) { return edits; @@ -507,7 +507,7 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable { } // compute diff between original and edit.text - const changes = stringDiff(original, text, false); + const changes = stringDiff(original, text, pretty); const editOffset = model.offsetAt(Range.lift(range).getStartPosition()); for (const change of changes) { @@ -531,6 +531,104 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable { return result; } + public async computeHumanReadableDiff(modelUrl: string, edits: TextEdit[], options: ILinesDiffComputerOptions): Promise { + const model = this._getModel(modelUrl); + if (!model) { + return edits; + } + + const result: TextEdit[] = []; + let lastEol: EndOfLineSequence | undefined = undefined; + + edits = edits.slice(0).sort((a, b) => { + if (a.range && b.range) { + return Range.compareRangesUsingStarts(a.range, b.range); + } + // eol only changes should go to the end + const aRng = a.range ? 0 : 1; + const bRng = b.range ? 0 : 1; + return aRng - bRng; + }); + + for (let { range, text, eol } of edits) { + + if (typeof eol === 'number') { + lastEol = eol; + } + + if (Range.isEmpty(range) && !text) { + // empty change + continue; + } + + const original = model.getValueInRange(range); + text = text.replace(/\r\n|\n|\r/g, model.eol); + + if (original === text) { + // noop + continue; + } + + // make sure diff won't take too long + if (Math.max(text.length, original.length) > EditorSimpleWorker._diffLimit) { + result.push({ range, text }); + continue; + } + + // compute diff between original and edit.text + + const originalLines = original.split(/\r\n|\n|\r/); + const modifiedLines = text.split(/\r\n|\n|\r/); + + const diff = linesDiffComputers.experimental.computeDiff(originalLines, modifiedLines, options); + + const start = Range.lift(range).getStartPosition(); + + function addPositions(pos1: Position, pos2: Position): Position { + return new Position(pos1.lineNumber + pos2.lineNumber - 1, pos2.lineNumber === 1 ? pos1.column + pos2.column - 1 : pos2.column); + } + + function getText(lines: string[], range: Range): string[] { + const result: string[] = []; + for (let i = range.startLineNumber; i <= range.endLineNumber; i++) { + const line = lines[i - 1]; + if (i === range.startLineNumber && i === range.endLineNumber) { + result.push(line.substring(range.startColumn - 1, range.endColumn - 1)); + } else if (i === range.startLineNumber) { + result.push(line.substring(range.startColumn - 1)); + } else if (i === range.endLineNumber) { + result.push(line.substring(0, range.endColumn - 1)); + } else { + result.push(line); + } + } + return result; + } + + for (const c of diff.changes) { + if (c.innerChanges) { + for (const x of c.innerChanges) { + result.push({ + range: Range.fromPositions( + addPositions(start, x.originalRange.getStartPosition()), + addPositions(start, x.originalRange.getEndPosition()) + ), + text: getText(modifiedLines, x.modifiedRange).join(model.eol) + }); + } + } else { + throw new BugIndicatingError('The experimental diff algorithm always produces inner changes'); + } + } + } + + if (typeof lastEol === 'number') { + result.push({ eol: lastEol, text: '', range: { startLineNumber: 0, startColumn: 0, endLineNumber: 0, endColumn: 0 } }); + } + + return result; + } + // ---- END minimal edits --------------------------------------------------------------- public async computeLinks(modelUrl: string): Promise { @@ -702,5 +800,5 @@ declare function importScripts(...urls: string[]): void; if (typeof importScripts === 'function') { // Running in a web worker - globals.monaco = createMonacoBaseAPI(); + globalThis.monaco = createMonacoBaseAPI(); } diff --git a/src/vs/editor/common/services/editorWorker.ts b/src/vs/editor/common/services/editorWorker.ts index 8f5129b9751..b30b6f0b60b 100644 --- a/src/vs/editor/common/services/editorWorker.ts +++ b/src/vs/editor/common/services/editorWorker.ts @@ -28,7 +28,8 @@ export interface IEditorWorkerService { canComputeDirtyDiff(original: URI, modified: URI): boolean; computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise; - computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise; + computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined, pretty?: boolean): Promise; + computeHumanReadableDiff(resource: URI, edits: TextEdit[] | null | undefined): Promise; canComputeWordRanges(resource: URI): boolean; computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] } | null>; diff --git a/src/vs/editor/common/services/languageService.ts b/src/vs/editor/common/services/languageService.ts index 19aed4cd838..6d96f2a2502 100644 --- a/src/vs/editor/common/services/languageService.ts +++ b/src/vs/editor/common/services/languageService.ts @@ -17,20 +17,24 @@ export class LanguageService extends Disposable implements ILanguageService { static instanceCount = 0; - private readonly _encounteredLanguages: Set; - protected readonly _registry: LanguagesRegistry; - public readonly languageIdCodec: ILanguageIdCodec; + private readonly _onDidRequestBasicLanguageFeatures = this._register(new Emitter()); + public readonly onDidRequestBasicLanguageFeatures = this._onDidRequestBasicLanguageFeatures.event; - private readonly _onDidEncounterLanguage = this._register(new Emitter()); - public readonly onDidEncounterLanguage: Event = this._onDidEncounterLanguage.event; + private readonly _onDidRequestRichLanguageFeatures = this._register(new Emitter()); + public readonly onDidRequestRichLanguageFeatures = this._onDidRequestRichLanguageFeatures.event; protected readonly _onDidChange = this._register(new Emitter({ leakWarningThreshold: 200 /* https://github.com/microsoft/vscode/issues/119968 */ })); public readonly onDidChange: Event = this._onDidChange.event; + private readonly _requestedBasicLanguages = new Set(); + private readonly _requestedRichLanguages = new Set(); + + protected readonly _registry: LanguagesRegistry; + public readonly languageIdCodec: ILanguageIdCodec; + constructor(warnOnOverwrite = false) { super(); LanguageService.instanceCount++; - this._encounteredLanguages = new Set(); this._registry = this._register(new LanguagesRegistry(true, warnOnOverwrite)); this.languageIdCodec = this._registry.languageIdCodec; this._register(this._registry.onDidChange(() => this._onDidChange.fire())); @@ -120,17 +124,28 @@ export class LanguageService extends Disposable implements ILanguageService { languageId = PLAINTEXT_LANGUAGE_ID; } - if (!this._encounteredLanguages.has(languageId)) { - this._encounteredLanguages.add(languageId); + return languageId; + } + + public requestBasicLanguageFeatures(languageId: string): void { + if (!this._requestedBasicLanguages.has(languageId)) { + this._requestedBasicLanguages.add(languageId); + this._onDidRequestBasicLanguageFeatures.fire(languageId); + } + } + + public requestRichLanguageFeatures(languageId: string): void { + if (!this._requestedRichLanguages.has(languageId)) { + this._requestedRichLanguages.add(languageId); + + // Ensure basic features are requested + this.requestBasicLanguageFeatures(languageId); // Ensure tokenizers are created TokenizationRegistry.getOrCreate(languageId); - // Fire event - this._onDidEncounterLanguage.fire(languageId); + this._onDidRequestRichLanguageFeatures.fire(languageId); } - - return languageId; } } diff --git a/src/vs/editor/common/services/model.ts b/src/vs/editor/common/services/model.ts index 88cc4606c7e..17355399606 100644 --- a/src/vs/editor/common/services/model.ts +++ b/src/vs/editor/common/services/model.ts @@ -9,7 +9,6 @@ import { ITextBufferFactory, ITextModel, ITextModelCreationOptions } from 'vs/ed import { ILanguageSelection } from 'vs/editor/common/languages/language'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { DocumentSemanticTokensProvider, DocumentRangeSemanticTokensProvider } from 'vs/editor/common/languages'; -import { SemanticTokensProviderStyling } from 'vs/editor/common/services/semanticTokensProviderStyling'; export const IModelService = createDecorator('modelService'); @@ -22,8 +21,6 @@ export interface IModelService { updateModel(model: ITextModel, value: string | ITextBufferFactory): void; - setMode(model: ITextModel, languageSelection: ILanguageSelection, source?: string): void; - destroyModel(resource: URI): void; getModels(): ITextModel[]; @@ -32,8 +29,6 @@ export interface IModelService { getModel(resource: URI): ITextModel | null; - getSemanticTokensProviderStyling(provider: DocumentTokensProvider): SemanticTokensProviderStyling; - onModelAdded: Event; onModelRemoved: Event; diff --git a/src/vs/editor/common/services/modelService.ts b/src/vs/editor/common/services/modelService.ts index fd8618a7de9..4de8d88004d 100644 --- a/src/vs/editor/common/services/modelService.ts +++ b/src/vs/editor/common/services/modelService.ts @@ -4,42 +4,26 @@ *--------------------------------------------------------------------------------------------*/ import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, IDisposable, DisposableStore, dispose } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; -import * as errors from 'vs/base/common/errors'; import { URI } from 'vs/base/common/uri'; import { EditOperation, ISingleEditOperation } from 'vs/editor/common/core/editOperation'; import { Range } from 'vs/editor/common/core/range'; import { DefaultEndOfLine, EndOfLinePreference, EndOfLineSequence, ITextBuffer, ITextBufferFactory, ITextModel, ITextModelCreationOptions } from 'vs/editor/common/model'; import { TextModel, createTextBuffer } from 'vs/editor/common/model/textModel'; import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/core/textModelDefaults'; -import { IModelLanguageChangedEvent, IModelContentChangedEvent } from 'vs/editor/common/textModelEvents'; -import { DocumentSemanticTokensProvider, SemanticTokens, SemanticTokensEdits } from 'vs/editor/common/languages'; +import { IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents'; import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; import { ILanguageSelection, ILanguageService } from 'vs/editor/common/languages/language'; -import { IModelService, DocumentTokensProvider } from 'vs/editor/common/services/model'; +import { IModelService } from 'vs/editor/common/services/model'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfiguration'; import { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { RunOnceScheduler } from 'vs/base/common/async'; -import { CancellationTokenSource } from 'vs/base/common/cancellation'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ILogService } from 'vs/platform/log/common/log'; import { IUndoRedoService, ResourceEditStackSnapshot } from 'vs/platform/undoRedo/common/undoRedo'; import { StringSHA1 } from 'vs/base/common/hash'; import { isEditStackElement } from 'vs/editor/common/model/editStack'; import { Schemas } from 'vs/base/common/network'; -import { SemanticTokensProviderStyling, toMultilineTokens2 } from 'vs/editor/common/services/semanticTokensProviderStyling'; -import { getDocumentSemanticTokens, hasDocumentSemanticTokensProvider, isSemanticTokens, isSemanticTokensEdits } from 'vs/editor/common/services/getSemanticTokens'; import { equals } from 'vs/base/common/objects'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; -import { IFeatureDebounceInformation, ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; -import { StopWatch } from 'vs/base/common/stopwatch'; -import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; - -export interface IEditorSemanticHighlightingOptions { - enabled: true | false | 'configuredByTheme'; -} function MODEL_ID(resource: URI): string { return resource.toString(); @@ -56,46 +40,22 @@ function computeModelSha1(model: ITextModel): string { return shaComputer.digest(); } - class ModelData implements IDisposable { - public readonly model: TextModel; - - private _languageSelection: ILanguageSelection | null; - private _languageSelectionListener: IDisposable | null; private readonly _modelEventListeners = new DisposableStore(); constructor( - model: TextModel, + public readonly model: TextModel, onWillDispose: (model: ITextModel) => void, onDidChangeLanguage: (model: ITextModel, e: IModelLanguageChangedEvent) => void ) { this.model = model; - - this._languageSelection = null; - this._languageSelectionListener = null; - this._modelEventListeners.add(model.onWillDispose(() => onWillDispose(model))); this._modelEventListeners.add(model.onDidChangeLanguage((e) => onDidChangeLanguage(model, e))); } - private _disposeLanguageSelection(): void { - if (this._languageSelectionListener) { - this._languageSelectionListener.dispose(); - this._languageSelectionListener = null; - } - } - public dispose(): void { this._modelEventListeners.dispose(); - this._disposeLanguageSelection(); - } - - public setLanguage(languageSelection: ILanguageSelection, source?: string): void { - this._disposeLanguageSelection(); - this._languageSelection = languageSelection; - this._languageSelectionListener = this._languageSelection.onDidChange(() => this.model.setMode(languageSelection.languageId, source)); - this.model.setMode(languageSelection.languageId, source); } } @@ -153,30 +113,22 @@ export class ModelService extends Disposable implements IModelService { private readonly _models: { [modelId: string]: ModelData }; private readonly _disposedModels: Map; private _disposedModelsHeapSize: number; - private readonly _semanticStyling: SemanticStyling; constructor( @IConfigurationService private readonly _configurationService: IConfigurationService, @ITextResourcePropertiesService private readonly _resourcePropertiesService: ITextResourcePropertiesService, - @IThemeService private readonly _themeService: IThemeService, - @ILogService private readonly _logService: ILogService, @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, @ILanguageService private readonly _languageService: ILanguageService, @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, - @ILanguageFeatureDebounceService private readonly _languageFeatureDebounceService: ILanguageFeatureDebounceService, - @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, ) { super(); this._modelCreationOptionsByLanguageAndResource = Object.create(null); this._models = {}; this._disposedModels = new Map(); this._disposedModelsHeapSize = 0; - this._semanticStyling = this._register(new SemanticStyling(this._themeService, this._languageService, this._logService)); this._register(this._configurationService.onDidChangeConfiguration(e => this._updateModelOptions(e))); this._updateModelOptions(undefined); - - this._register(new SemanticColoringFeature(this._semanticStyling, this, this._themeService, this._configurationService, this._languageFeatureDebounceService, languageFeaturesService)); } private static _readModelOptions(config: IRawConfig, isForSimpleWidget: boolean): ITextModelCreationOptions { @@ -266,7 +218,8 @@ export class ModelService extends Disposable implements IModelService { return true; } - public getCreationOptions(language: string, resource: URI | undefined, isForSimpleWidget: boolean): ITextModelCreationOptions { + public getCreationOptions(languageIdOrSelection: string | ILanguageSelection, resource: URI | undefined, isForSimpleWidget: boolean): ITextModelCreationOptions { + const language = (typeof languageIdOrSelection === 'string' ? languageIdOrSelection : languageIdOrSelection.languageId); let creationOptions = this._modelCreationOptionsByLanguageAndResource[language + resource]; if (!creationOptions) { const editor = this._configurationService.getValue('editor', { overrideIdentifier: language, resource }); @@ -369,12 +322,12 @@ export class ModelService extends Disposable implements IModelService { } } - private _createModelData(value: string | ITextBufferFactory, languageId: string, resource: URI | undefined, isForSimpleWidget: boolean): ModelData { + private _createModelData(value: string | ITextBufferFactory, languageIdOrSelection: string | ILanguageSelection, resource: URI | undefined, isForSimpleWidget: boolean): ModelData { // create & save the model - const options = this.getCreationOptions(languageId, resource, isForSimpleWidget); + const options = this.getCreationOptions(languageIdOrSelection, resource, isForSimpleWidget); const model: TextModel = new TextModel( value, - languageId, + languageIdOrSelection, options, resource, this._undoRedoService, @@ -502,8 +455,7 @@ export class ModelService extends Disposable implements IModelService { let modelData: ModelData; if (languageSelection) { - modelData = this._createModelData(value, languageSelection.languageId, resource, isForSimpleWidget); - this.setMode(modelData.model, languageSelection); + modelData = this._createModelData(value, languageSelection, resource, isForSimpleWidget); } else { modelData = this._createModelData(value, PLAINTEXT_LANGUAGE_ID, resource, isForSimpleWidget); } @@ -513,17 +465,6 @@ export class ModelService extends Disposable implements IModelService { return modelData.model; } - public setMode(model: ITextModel, languageSelection: ILanguageSelection, source?: string): void { - if (!languageSelection) { - return; - } - const modelData = this._models[MODEL_ID(model.uri)]; - if (!modelData) { - return; - } - modelData.setLanguage(languageSelection, source); - } - public destroyModel(resource: URI): void { // We need to support that not all models get disposed through this service (i.e. model.dispose() should work!) const modelData = this._models[MODEL_ID(resource)]; @@ -554,10 +495,6 @@ export class ModelService extends Disposable implements IModelService { return modelData.model; } - public getSemanticTokensProviderStyling(provider: DocumentTokensProvider): SemanticTokensProviderStyling { - return this._semanticStyling.get(provider); - } - // --- end IModelService protected _schemaShouldMaintainUndoRedoElements(resource: URI) { @@ -636,401 +573,3 @@ export class ModelService extends Disposable implements IModelService { this._onModelModeChanged.fire({ model, oldLanguageId: oldLanguageId }); } } - -export const SEMANTIC_HIGHLIGHTING_SETTING_ID = 'editor.semanticHighlighting'; - -export function isSemanticColoringEnabled(model: ITextModel, themeService: IThemeService, configurationService: IConfigurationService): boolean { - const setting = configurationService.getValue(SEMANTIC_HIGHLIGHTING_SETTING_ID, { overrideIdentifier: model.getLanguageId(), resource: model.uri })?.enabled; - if (typeof setting === 'boolean') { - return setting; - } - return themeService.getColorTheme().semanticHighlighting; -} - -class SemanticColoringFeature extends Disposable { - - private readonly _watchers: Record; - private readonly _semanticStyling: SemanticStyling; - - constructor( - semanticStyling: SemanticStyling, - @IModelService modelService: IModelService, - @IThemeService themeService: IThemeService, - @IConfigurationService configurationService: IConfigurationService, - @ILanguageFeatureDebounceService languageFeatureDebounceService: ILanguageFeatureDebounceService, - @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, - ) { - super(); - this._watchers = Object.create(null); - this._semanticStyling = semanticStyling; - - const register = (model: ITextModel) => { - this._watchers[model.uri.toString()] = new ModelSemanticColoring(model, this._semanticStyling, themeService, languageFeatureDebounceService, languageFeaturesService); - }; - const deregister = (model: ITextModel, modelSemanticColoring: ModelSemanticColoring) => { - modelSemanticColoring.dispose(); - delete this._watchers[model.uri.toString()]; - }; - const handleSettingOrThemeChange = () => { - for (const model of modelService.getModels()) { - const curr = this._watchers[model.uri.toString()]; - if (isSemanticColoringEnabled(model, themeService, configurationService)) { - if (!curr) { - register(model); - } - } else { - if (curr) { - deregister(model, curr); - } - } - } - }; - this._register(modelService.onModelAdded((model) => { - if (isSemanticColoringEnabled(model, themeService, configurationService)) { - register(model); - } - })); - this._register(modelService.onModelRemoved((model) => { - const curr = this._watchers[model.uri.toString()]; - if (curr) { - deregister(model, curr); - } - })); - this._register(configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration(SEMANTIC_HIGHLIGHTING_SETTING_ID)) { - handleSettingOrThemeChange(); - } - })); - this._register(themeService.onDidColorThemeChange(handleSettingOrThemeChange)); - } - - override dispose(): void { - // Dispose all watchers - for (const watcher of Object.values(this._watchers)) { - watcher.dispose(); - } - super.dispose(); - } -} - -class SemanticStyling extends Disposable { - - private _caches: WeakMap; - - constructor( - private readonly _themeService: IThemeService, - private readonly _languageService: ILanguageService, - private readonly _logService: ILogService - ) { - super(); - this._caches = new WeakMap(); - this._register(this._themeService.onDidColorThemeChange(() => { - this._caches = new WeakMap(); - })); - } - - public get(provider: DocumentTokensProvider): SemanticTokensProviderStyling { - if (!this._caches.has(provider)) { - this._caches.set(provider, new SemanticTokensProviderStyling(provider.getLegend(), this._themeService, this._languageService, this._logService)); - } - return this._caches.get(provider)!; - } -} - -class SemanticTokensResponse { - constructor( - public readonly provider: DocumentSemanticTokensProvider, - public readonly resultId: string | undefined, - public readonly data: Uint32Array - ) { } - - public dispose(): void { - this.provider.releaseDocumentSemanticTokens(this.resultId); - } -} - -class ModelSemanticColoring extends Disposable { - - public static REQUEST_MIN_DELAY = 300; - public static REQUEST_MAX_DELAY = 2000; - - private _isDisposed: boolean; - private readonly _model: ITextModel; - private readonly _semanticStyling: SemanticStyling; - private readonly _provider: LanguageFeatureRegistry; - private readonly _debounceInformation: IFeatureDebounceInformation; - private readonly _fetchDocumentSemanticTokens: RunOnceScheduler; - private _currentDocumentResponse: SemanticTokensResponse | null; - private _currentDocumentRequestCancellationTokenSource: CancellationTokenSource | null; - private _documentProvidersChangeListeners: IDisposable[]; - private _providersChangedDuringRequest: boolean; - - constructor( - model: ITextModel, - stylingProvider: SemanticStyling, - @IThemeService themeService: IThemeService, - @ILanguageFeatureDebounceService languageFeatureDebounceService: ILanguageFeatureDebounceService, - @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, - ) { - super(); - - this._isDisposed = false; - this._model = model; - this._semanticStyling = stylingProvider; - this._provider = languageFeaturesService.documentSemanticTokensProvider; - this._debounceInformation = languageFeatureDebounceService.for(this._provider, 'DocumentSemanticTokens', { min: ModelSemanticColoring.REQUEST_MIN_DELAY, max: ModelSemanticColoring.REQUEST_MAX_DELAY }); - this._fetchDocumentSemanticTokens = this._register(new RunOnceScheduler(() => this._fetchDocumentSemanticTokensNow(), ModelSemanticColoring.REQUEST_MIN_DELAY)); - this._currentDocumentResponse = null; - this._currentDocumentRequestCancellationTokenSource = null; - this._documentProvidersChangeListeners = []; - this._providersChangedDuringRequest = false; - - this._register(this._model.onDidChangeContent(() => { - if (!this._fetchDocumentSemanticTokens.isScheduled()) { - this._fetchDocumentSemanticTokens.schedule(this._debounceInformation.get(this._model)); - } - })); - this._register(this._model.onDidChangeLanguage(() => { - // clear any outstanding state - if (this._currentDocumentResponse) { - this._currentDocumentResponse.dispose(); - this._currentDocumentResponse = null; - } - if (this._currentDocumentRequestCancellationTokenSource) { - this._currentDocumentRequestCancellationTokenSource.cancel(); - this._currentDocumentRequestCancellationTokenSource = null; - } - this._setDocumentSemanticTokens(null, null, null, []); - this._fetchDocumentSemanticTokens.schedule(0); - })); - - const bindDocumentChangeListeners = () => { - dispose(this._documentProvidersChangeListeners); - this._documentProvidersChangeListeners = []; - for (const provider of this._provider.all(model)) { - if (typeof provider.onDidChange === 'function') { - this._documentProvidersChangeListeners.push(provider.onDidChange(() => { - if (this._currentDocumentRequestCancellationTokenSource) { - // there is already a request running, - this._providersChangedDuringRequest = true; - return; - } - this._fetchDocumentSemanticTokens.schedule(0); - })); - } - } - }; - bindDocumentChangeListeners(); - this._register(this._provider.onDidChange(() => { - bindDocumentChangeListeners(); - this._fetchDocumentSemanticTokens.schedule(this._debounceInformation.get(this._model)); - })); - - this._register(themeService.onDidColorThemeChange(_ => { - // clear out existing tokens - this._setDocumentSemanticTokens(null, null, null, []); - this._fetchDocumentSemanticTokens.schedule(this._debounceInformation.get(this._model)); - })); - - this._fetchDocumentSemanticTokens.schedule(0); - } - - public override dispose(): void { - if (this._currentDocumentResponse) { - this._currentDocumentResponse.dispose(); - this._currentDocumentResponse = null; - } - if (this._currentDocumentRequestCancellationTokenSource) { - this._currentDocumentRequestCancellationTokenSource.cancel(); - this._currentDocumentRequestCancellationTokenSource = null; - } - this._setDocumentSemanticTokens(null, null, null, []); - this._isDisposed = true; - - super.dispose(); - } - - private _fetchDocumentSemanticTokensNow(): void { - if (this._currentDocumentRequestCancellationTokenSource) { - // there is already a request running, let it finish... - return; - } - - if (!hasDocumentSemanticTokensProvider(this._provider, this._model)) { - // there is no provider - if (this._currentDocumentResponse) { - // there are semantic tokens set - this._model.tokenization.setSemanticTokens(null, false); - } - return; - } - - const cancellationTokenSource = new CancellationTokenSource(); - const lastProvider = this._currentDocumentResponse ? this._currentDocumentResponse.provider : null; - const lastResultId = this._currentDocumentResponse ? this._currentDocumentResponse.resultId || null : null; - const request = getDocumentSemanticTokens(this._provider, this._model, lastProvider, lastResultId, cancellationTokenSource.token); - this._currentDocumentRequestCancellationTokenSource = cancellationTokenSource; - this._providersChangedDuringRequest = false; - - const pendingChanges: IModelContentChangedEvent[] = []; - const contentChangeListener = this._model.onDidChangeContent((e) => { - pendingChanges.push(e); - }); - - const sw = new StopWatch(false); - request.then((res) => { - this._debounceInformation.update(this._model, sw.elapsed()); - this._currentDocumentRequestCancellationTokenSource = null; - contentChangeListener.dispose(); - - if (!res) { - this._setDocumentSemanticTokens(null, null, null, pendingChanges); - } else { - const { provider, tokens } = res; - const styling = this._semanticStyling.get(provider); - this._setDocumentSemanticTokens(provider, tokens || null, styling, pendingChanges); - } - }, (err) => { - const isExpectedError = err && (errors.isCancellationError(err) || (typeof err.message === 'string' && err.message.indexOf('busy') !== -1)); - if (!isExpectedError) { - errors.onUnexpectedError(err); - } - - // Semantic tokens eats up all errors and considers errors to mean that the result is temporarily not available - // The API does not have a special error kind to express this... - this._currentDocumentRequestCancellationTokenSource = null; - contentChangeListener.dispose(); - - if (pendingChanges.length > 0 || this._providersChangedDuringRequest) { - // More changes occurred while the request was running - if (!this._fetchDocumentSemanticTokens.isScheduled()) { - this._fetchDocumentSemanticTokens.schedule(this._debounceInformation.get(this._model)); - } - } - }); - } - - private static _copy(src: Uint32Array, srcOffset: number, dest: Uint32Array, destOffset: number, length: number): void { - // protect against overflows - length = Math.min(length, dest.length - destOffset, src.length - srcOffset); - for (let i = 0; i < length; i++) { - dest[destOffset + i] = src[srcOffset + i]; - } - } - - private _setDocumentSemanticTokens(provider: DocumentSemanticTokensProvider | null, tokens: SemanticTokens | SemanticTokensEdits | null, styling: SemanticTokensProviderStyling | null, pendingChanges: IModelContentChangedEvent[]): void { - const currentResponse = this._currentDocumentResponse; - const rescheduleIfNeeded = () => { - if ((pendingChanges.length > 0 || this._providersChangedDuringRequest) && !this._fetchDocumentSemanticTokens.isScheduled()) { - this._fetchDocumentSemanticTokens.schedule(this._debounceInformation.get(this._model)); - } - }; - - if (this._currentDocumentResponse) { - this._currentDocumentResponse.dispose(); - this._currentDocumentResponse = null; - } - if (this._isDisposed) { - // disposed! - if (provider && tokens) { - provider.releaseDocumentSemanticTokens(tokens.resultId); - } - return; - } - if (!provider || !styling) { - this._model.tokenization.setSemanticTokens(null, false); - return; - } - if (!tokens) { - this._model.tokenization.setSemanticTokens(null, true); - rescheduleIfNeeded(); - return; - } - - if (isSemanticTokensEdits(tokens)) { - if (!currentResponse) { - // not possible! - this._model.tokenization.setSemanticTokens(null, true); - return; - } - if (tokens.edits.length === 0) { - // nothing to do! - tokens = { - resultId: tokens.resultId, - data: currentResponse.data - }; - } else { - let deltaLength = 0; - for (const edit of tokens.edits) { - deltaLength += (edit.data ? edit.data.length : 0) - edit.deleteCount; - } - - const srcData = currentResponse.data; - const destData = new Uint32Array(srcData.length + deltaLength); - - let srcLastStart = srcData.length; - let destLastStart = destData.length; - for (let i = tokens.edits.length - 1; i >= 0; i--) { - const edit = tokens.edits[i]; - - if (edit.start > srcData.length) { - styling.warnInvalidEditStart(currentResponse.resultId, tokens.resultId, i, edit.start, srcData.length); - // The edits are invalid and there's no way to recover - this._model.tokenization.setSemanticTokens(null, true); - return; - } - - const copyCount = srcLastStart - (edit.start + edit.deleteCount); - if (copyCount > 0) { - ModelSemanticColoring._copy(srcData, srcLastStart - copyCount, destData, destLastStart - copyCount, copyCount); - destLastStart -= copyCount; - } - - if (edit.data) { - ModelSemanticColoring._copy(edit.data, 0, destData, destLastStart - edit.data.length, edit.data.length); - destLastStart -= edit.data.length; - } - - srcLastStart = edit.start; - } - - if (srcLastStart > 0) { - ModelSemanticColoring._copy(srcData, 0, destData, 0, srcLastStart); - } - - tokens = { - resultId: tokens.resultId, - data: destData - }; - } - } - - if (isSemanticTokens(tokens)) { - - this._currentDocumentResponse = new SemanticTokensResponse(provider, tokens.resultId, tokens.data); - - const result = toMultilineTokens2(tokens, styling, this._model.getLanguageId()); - - // Adjust incoming semantic tokens - if (pendingChanges.length > 0) { - // More changes occurred while the request was running - // We need to: - // 1. Adjust incoming semantic tokens - // 2. Request them again - for (const change of pendingChanges) { - for (const area of result) { - for (const singleChange of change.changes) { - area.applyEdit(singleChange.range, singleChange.text); - } - } - } - } - - this._model.tokenization.setSemanticTokens(result, true); - } else { - this._model.tokenization.setSemanticTokens(null, true); - } - - rescheduleIfNeeded(); - } -} diff --git a/src/vs/editor/common/services/semanticTokensStyling.ts b/src/vs/editor/common/services/semanticTokensStyling.ts new file mode 100644 index 00000000000..935c9aed528 --- /dev/null +++ b/src/vs/editor/common/services/semanticTokensStyling.ts @@ -0,0 +1,18 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { DocumentSemanticTokensProvider, DocumentRangeSemanticTokensProvider } from 'vs/editor/common/languages'; +import { SemanticTokensProviderStyling } from 'vs/editor/common/services/semanticTokensProviderStyling'; + +export const ISemanticTokensStylingService = createDecorator('semanticTokensStylingService'); + +export type DocumentTokensProvider = DocumentSemanticTokensProvider | DocumentRangeSemanticTokensProvider; + +export interface ISemanticTokensStylingService { + readonly _serviceBrand: undefined; + + getStyling(provider: DocumentTokensProvider): SemanticTokensProviderStyling; +} diff --git a/src/vs/editor/common/services/semanticTokensStylingService.ts b/src/vs/editor/common/services/semanticTokensStylingService.ts new file mode 100644 index 00000000000..8aba1f0a601 --- /dev/null +++ b/src/vs/editor/common/services/semanticTokensStylingService.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 { Disposable } from 'vs/base/common/lifecycle'; +import { ILanguageService } from 'vs/editor/common/languages/language'; +import { DocumentTokensProvider } from 'vs/editor/common/services/model'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { ILogService } from 'vs/platform/log/common/log'; +import { SemanticTokensProviderStyling } from 'vs/editor/common/services/semanticTokensProviderStyling'; +import { ISemanticTokensStylingService } from 'vs/editor/common/services/semanticTokensStyling'; +import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; + +export class SemanticTokensStylingService extends Disposable implements ISemanticTokensStylingService { + + public _serviceBrand: undefined; + + private _caches: WeakMap; + + constructor( + @IThemeService private readonly _themeService: IThemeService, + @ILogService private readonly _logService: ILogService, + @ILanguageService private readonly _languageService: ILanguageService, + ) { + super(); + this._caches = new WeakMap(); + this._register(this._themeService.onDidColorThemeChange(() => { + this._caches = new WeakMap(); + })); + } + + public getStyling(provider: DocumentTokensProvider): SemanticTokensProviderStyling { + if (!this._caches.has(provider)) { + this._caches.set(provider, new SemanticTokensProviderStyling(provider.getLegend(), this._themeService, this._languageService, this._logService)); + } + return this._caches.get(provider)!; + } +} + +registerSingleton(ISemanticTokensStylingService, SemanticTokensStylingService, InstantiationType.Delayed); diff --git a/src/vs/editor/common/services/treeViewsDnd.ts b/src/vs/editor/common/services/treeViewsDnd.ts new file mode 100644 index 00000000000..f2614172ff4 --- /dev/null +++ b/src/vs/editor/common/services/treeViewsDnd.ts @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export interface ITreeViewsDnDService { + readonly _serviceBrand: undefined; + + removeDragOperationTransfer(uuid: string | undefined): Promise | undefined; + addDragOperationTransfer(uuid: string, transferPromise: Promise): void; +} + +export class TreeViewsDnDService implements ITreeViewsDnDService { + _serviceBrand: undefined; + private _dragOperations: Map> = new Map(); + + removeDragOperationTransfer(uuid: string | undefined): Promise | undefined { + if ((uuid && this._dragOperations.has(uuid))) { + const operation = this._dragOperations.get(uuid); + this._dragOperations.delete(uuid); + return operation; + } + return undefined; + } + + addDragOperationTransfer(uuid: string, transferPromise: Promise): void { + this._dragOperations.set(uuid, transferPromise); + } +} diff --git a/src/vs/editor/common/services/treeViewsDndService.ts b/src/vs/editor/common/services/treeViewsDndService.ts new file mode 100644 index 00000000000..6130072bfb0 --- /dev/null +++ b/src/vs/editor/common/services/treeViewsDndService.ts @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { VSDataTransfer } from 'vs/base/common/dataTransfer'; +import { ITreeViewsDnDService as ITreeViewsDnDServiceCommon, TreeViewsDnDService } from 'vs/editor/common/services/treeViewsDnd'; + +export interface ITreeViewsDnDService extends ITreeViewsDnDServiceCommon { } +export const ITreeViewsDnDService = createDecorator('treeViewsDndService'); +registerSingleton(ITreeViewsDnDService, TreeViewsDnDService, InstantiationType.Delayed); diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index d15fc2e84d2..29fe6e67584 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -179,140 +179,141 @@ export enum EditorOption { accessibilityPageSize = 3, ariaLabel = 4, autoClosingBrackets = 5, - autoClosingDelete = 6, - autoClosingOvertype = 7, - autoClosingQuotes = 8, - autoIndent = 9, - automaticLayout = 10, - autoSurround = 11, - bracketPairColorization = 12, - guides = 13, - codeLens = 14, - codeLensFontFamily = 15, - codeLensFontSize = 16, - colorDecorators = 17, - colorDecoratorsLimit = 18, - columnSelection = 19, - comments = 20, - contextmenu = 21, - copyWithSyntaxHighlighting = 22, - cursorBlinking = 23, - cursorSmoothCaretAnimation = 24, - cursorStyle = 25, - cursorSurroundingLines = 26, - cursorSurroundingLinesStyle = 27, - cursorWidth = 28, - disableLayerHinting = 29, - disableMonospaceOptimizations = 30, - domReadOnly = 31, - dragAndDrop = 32, - dropIntoEditor = 33, - emptySelectionClipboard = 34, - experimentalWhitespaceRendering = 35, - extraEditorClassName = 36, - fastScrollSensitivity = 37, - find = 38, - fixedOverflowWidgets = 39, - folding = 40, - foldingStrategy = 41, - foldingHighlight = 42, - foldingImportsByDefault = 43, - foldingMaximumRegions = 44, - unfoldOnClickAfterEndOfLine = 45, - fontFamily = 46, - fontInfo = 47, - fontLigatures = 48, - fontSize = 49, - fontWeight = 50, - fontVariations = 51, - formatOnPaste = 52, - formatOnType = 53, - glyphMargin = 54, - gotoLocation = 55, - hideCursorInOverviewRuler = 56, - hover = 57, - inDiffEditor = 58, - inlineSuggest = 59, - letterSpacing = 60, - lightbulb = 61, - lineDecorationsWidth = 62, - lineHeight = 63, - lineNumbers = 64, - lineNumbersMinChars = 65, - linkedEditing = 66, - links = 67, - matchBrackets = 68, - minimap = 69, - mouseStyle = 70, - mouseWheelScrollSensitivity = 71, - mouseWheelZoom = 72, - multiCursorMergeOverlapping = 73, - multiCursorModifier = 74, - multiCursorPaste = 75, - multiCursorLimit = 76, - occurrencesHighlight = 77, - overviewRulerBorder = 78, - overviewRulerLanes = 79, - padding = 80, - parameterHints = 81, - peekWidgetDefaultFocus = 82, - definitionLinkOpensInPeek = 83, - quickSuggestions = 84, - quickSuggestionsDelay = 85, - readOnly = 86, - renameOnType = 87, - renderControlCharacters = 88, - renderFinalNewline = 89, - renderLineHighlight = 90, - renderLineHighlightOnlyWhenFocus = 91, - renderValidationDecorations = 92, - renderWhitespace = 93, - revealHorizontalRightPadding = 94, - roundedSelection = 95, - rulers = 96, - scrollbar = 97, - scrollBeyondLastColumn = 98, - scrollBeyondLastLine = 99, - scrollPredominantAxis = 100, - selectionClipboard = 101, - selectionHighlight = 102, - selectOnLineNumbers = 103, - showFoldingControls = 104, - showUnused = 105, - snippetSuggestions = 106, - smartSelect = 107, - smoothScrolling = 108, - stickyScroll = 109, - stickyTabStops = 110, - stopRenderingLineAfter = 111, - suggest = 112, - suggestFontSize = 113, - suggestLineHeight = 114, - suggestOnTriggerCharacters = 115, - suggestSelection = 116, - tabCompletion = 117, - tabIndex = 118, - unicodeHighlighting = 119, - unusualLineTerminators = 120, - useShadowDOM = 121, - useTabStops = 122, - wordBreak = 123, - wordSeparators = 124, - wordWrap = 125, - wordWrapBreakAfterCharacters = 126, - wordWrapBreakBeforeCharacters = 127, - wordWrapColumn = 128, - wordWrapOverride1 = 129, - wordWrapOverride2 = 130, - wrappingIndent = 131, - wrappingStrategy = 132, - showDeprecated = 133, - inlayHints = 134, - editorClassName = 135, - pixelRatio = 136, - tabFocusMode = 137, - layoutInfo = 138, - wrappingInfo = 139 + screenReaderAnnounceInlineSuggestion = 6, + autoClosingDelete = 7, + autoClosingOvertype = 8, + autoClosingQuotes = 9, + autoIndent = 10, + automaticLayout = 11, + autoSurround = 12, + bracketPairColorization = 13, + guides = 14, + codeLens = 15, + codeLensFontFamily = 16, + codeLensFontSize = 17, + colorDecorators = 18, + colorDecoratorsLimit = 19, + columnSelection = 20, + comments = 21, + contextmenu = 22, + copyWithSyntaxHighlighting = 23, + cursorBlinking = 24, + cursorSmoothCaretAnimation = 25, + cursorStyle = 26, + cursorSurroundingLines = 27, + cursorSurroundingLinesStyle = 28, + cursorWidth = 29, + disableLayerHinting = 30, + disableMonospaceOptimizations = 31, + domReadOnly = 32, + dragAndDrop = 33, + dropIntoEditor = 34, + emptySelectionClipboard = 35, + experimentalWhitespaceRendering = 36, + extraEditorClassName = 37, + fastScrollSensitivity = 38, + find = 39, + fixedOverflowWidgets = 40, + folding = 41, + foldingStrategy = 42, + foldingHighlight = 43, + foldingImportsByDefault = 44, + foldingMaximumRegions = 45, + unfoldOnClickAfterEndOfLine = 46, + fontFamily = 47, + fontInfo = 48, + fontLigatures = 49, + fontSize = 50, + fontWeight = 51, + fontVariations = 52, + formatOnPaste = 53, + formatOnType = 54, + glyphMargin = 55, + gotoLocation = 56, + hideCursorInOverviewRuler = 57, + hover = 58, + inDiffEditor = 59, + inlineSuggest = 60, + letterSpacing = 61, + lightbulb = 62, + lineDecorationsWidth = 63, + lineHeight = 64, + lineNumbers = 65, + lineNumbersMinChars = 66, + linkedEditing = 67, + links = 68, + matchBrackets = 69, + minimap = 70, + mouseStyle = 71, + mouseWheelScrollSensitivity = 72, + mouseWheelZoom = 73, + multiCursorMergeOverlapping = 74, + multiCursorModifier = 75, + multiCursorPaste = 76, + multiCursorLimit = 77, + occurrencesHighlight = 78, + overviewRulerBorder = 79, + overviewRulerLanes = 80, + padding = 81, + parameterHints = 82, + peekWidgetDefaultFocus = 83, + definitionLinkOpensInPeek = 84, + quickSuggestions = 85, + quickSuggestionsDelay = 86, + readOnly = 87, + renameOnType = 88, + renderControlCharacters = 89, + renderFinalNewline = 90, + renderLineHighlight = 91, + renderLineHighlightOnlyWhenFocus = 92, + renderValidationDecorations = 93, + renderWhitespace = 94, + revealHorizontalRightPadding = 95, + roundedSelection = 96, + rulers = 97, + scrollbar = 98, + scrollBeyondLastColumn = 99, + scrollBeyondLastLine = 100, + scrollPredominantAxis = 101, + selectionClipboard = 102, + selectionHighlight = 103, + selectOnLineNumbers = 104, + showFoldingControls = 105, + showUnused = 106, + snippetSuggestions = 107, + smartSelect = 108, + smoothScrolling = 109, + stickyScroll = 110, + stickyTabStops = 111, + stopRenderingLineAfter = 112, + suggest = 113, + suggestFontSize = 114, + suggestLineHeight = 115, + suggestOnTriggerCharacters = 116, + suggestSelection = 117, + tabCompletion = 118, + tabIndex = 119, + unicodeHighlighting = 120, + unusualLineTerminators = 121, + useShadowDOM = 122, + useTabStops = 123, + wordBreak = 124, + wordSeparators = 125, + wordWrap = 126, + wordWrapBreakAfterCharacters = 127, + wordWrapBreakBeforeCharacters = 128, + wordWrapColumn = 129, + wordWrapOverride1 = 130, + wordWrapOverride2 = 131, + wrappingIndent = 132, + wrappingStrategy = 133, + showDeprecated = 134, + inlayHints = 135, + editorClassName = 136, + pixelRatio = 137, + tabFocusMode = 138, + layoutInfo = 139, + wrappingInfo = 140 } /** diff --git a/src/vs/editor/common/tokenizationRegistry.ts b/src/vs/editor/common/tokenizationRegistry.ts index 4f1876bbb9a..2d5ab7781a5 100644 --- a/src/vs/editor/common/tokenizationRegistry.ts +++ b/src/vs/editor/common/tokenizationRegistry.ts @@ -6,12 +6,12 @@ import { Color } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { ITokenizationRegistry, ITokenizationSupport, ITokenizationSupportChangedEvent, ITokenizationSupportFactory } from 'vs/editor/common/languages'; +import { ITokenizationRegistry, ITokenizationSupport, ITokenizationSupportChangedEvent, ILazyTokenizationSupport } from 'vs/editor/common/languages'; import { ColorId } from 'vs/editor/common/encodedTokenAttributes'; export class TokenizationRegistry implements ITokenizationRegistry { - private readonly _map = new Map(); + private readonly _tokenizationSupports = new Map(); private readonly _factories = new Map(); private readonly _onDidChange = new Emitter(); @@ -23,26 +23,30 @@ export class TokenizationRegistry implements ITokenizationRegistry { this._colorMap = null; } - public fire(languages: string[]): void { + public handleChange(languageIds: string[]): void { this._onDidChange.fire({ - changedLanguages: languages, + changedLanguages: languageIds, changedColorMap: false }); } - public register(language: string, support: ITokenizationSupport) { - this._map.set(language, support); - this.fire([language]); + public register(languageId: string, support: ITokenizationSupport): IDisposable { + this._tokenizationSupports.set(languageId, support); + this.handleChange([languageId]); return toDisposable(() => { - if (this._map.get(language) !== support) { + if (this._tokenizationSupports.get(languageId) !== support) { return; } - this._map.delete(language); - this.fire([language]); + this._tokenizationSupports.delete(languageId); + this.handleChange([languageId]); }); } - public registerFactory(languageId: string, factory: ITokenizationSupportFactory): IDisposable { + public get(languageId: string): ITokenizationSupport | null { + return this._tokenizationSupports.get(languageId) || null; + } + + public registerFactory(languageId: string, factory: ILazyTokenizationSupport): IDisposable { this._factories.get(languageId)?.dispose(); const myData = new TokenizationSupportFactoryData(this, languageId, factory); this._factories.set(languageId, myData); @@ -74,9 +78,7 @@ export class TokenizationRegistry implements ITokenizationRegistry { return this.get(languageId); } - public get(language: string): ITokenizationSupport | null { - return (this._map.get(language) || null); - } + public isResolved(languageId: string): boolean { const tokenizationSupport = this.get(languageId); @@ -95,7 +97,7 @@ export class TokenizationRegistry implements ITokenizationRegistry { public setColorMap(colorMap: Color[]): void { this._colorMap = colorMap; this._onDidChange.fire({ - changedLanguages: Array.from(this._map.keys()), + changedLanguages: Array.from(this._tokenizationSupports.keys()), changedColorMap: true }); } @@ -125,7 +127,7 @@ class TokenizationSupportFactoryData extends Disposable { constructor( private readonly _registry: TokenizationRegistry, private readonly _languageId: string, - private readonly _factory: ITokenizationSupportFactory, + private readonly _factory: ILazyTokenizationSupport, ) { super(); } @@ -143,7 +145,7 @@ class TokenizationSupportFactoryData extends Disposable { } private async _create(): Promise { - const value = await Promise.resolve(this._factory.createTokenizationSupport()); + const value = await this._factory.tokenizationSupport; this._isResolved = true; if (value && !this._isDisposed) { this._register(this._registry.register(this._languageId, value)); diff --git a/src/vs/editor/common/tokens/contiguousMultilineTokens.ts b/src/vs/editor/common/tokens/contiguousMultilineTokens.ts index a8860866aef..f4d267fba0a 100644 --- a/src/vs/editor/common/tokens/contiguousMultilineTokens.ts +++ b/src/vs/editor/common/tokens/contiguousMultilineTokens.ts @@ -9,12 +9,12 @@ import { Position } from 'vs/editor/common/core/position'; import { IRange } from 'vs/editor/common/core/range'; import { countEOL } from 'vs/editor/common/core/eolCounter'; import { ContiguousTokensEditing } from 'vs/editor/common/tokens/contiguousTokensEditing'; +import { LineRange } from 'vs/editor/common/core/lineRange'; /** * Represents contiguous tokens over a contiguous range of lines. */ export class ContiguousMultilineTokens { - public static deserialize(buff: Uint8Array, offset: number, result: ContiguousMultilineTokens[]): number { const view32 = new Uint32Array(buff.buffer); const startLineNumber = readUInt32BE(buff, offset); offset += 4; @@ -64,6 +64,10 @@ export class ContiguousMultilineTokens { this._tokens = tokens; } + getLineRange(): LineRange { + return new LineRange(this._startLineNumber, this._startLineNumber + this._tokens.length); + } + /** * @see {@link _tokens} */ diff --git a/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts b/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts index 09b0cb279b4..a3b15fd4ae6 100644 --- a/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts +++ b/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts @@ -78,6 +78,25 @@ class SelectToBracketAction extends EditorAction { BracketMatchingController.get(editor)?.selectToBracket(selectBrackets); } } +class RemoveBracketsAction extends EditorAction { + constructor() { + super({ + id: 'editor.action.removeBrackets', + label: nls.localize('smartSelect.removeBrackets', "Remove Brackets"), + alias: 'Remove Brackets', + precondition: undefined, + kbOpts: { + kbExpr: EditorContextKeys.editorTextFocus, + primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Backspace, + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + BracketMatchingController.get(editor)?.removeBrackets(this.id); + } +} type Brackets = [Range, Range]; @@ -251,6 +270,32 @@ export class BracketMatchingController extends Disposable implements IEditorCont this._editor.revealRange(newSelections[0]); } } + public removeBrackets(editSource?: string): void { + if (!this._editor.hasModel()) { + return; + } + + const model = this._editor.getModel(); + this._editor.getSelections().forEach((selection) => { + const position = selection.getPosition(); + + let brackets = model.bracketPairs.matchBracket(position); + if (!brackets) { + brackets = model.bracketPairs.findEnclosingBrackets(position); + } + if (brackets) { + this._editor.pushUndoStop(); + this._editor.executeEdits( + editSource, + [ + { range: brackets[0], text: '' }, + { range: brackets[1], text: '' } + ] + ); + this._editor.pushUndoStop(); + } + }); + } private static readonly _DECORATION_OPTIONS_WITH_OVERVIEW_RULER = ModelDecorationOptions.register({ description: 'bracket-match-overview', @@ -359,6 +404,7 @@ export class BracketMatchingController extends Disposable implements IEditorCont registerEditorContribution(BracketMatchingController.ID, BracketMatchingController, EditorContributionInstantiation.AfterFirstRender); registerEditorAction(SelectToBracketAction); registerEditorAction(JumpToBracketAction); +registerEditorAction(RemoveBracketsAction); // Go to menu MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { diff --git a/src/vs/editor/contrib/bracketMatching/test/browser/bracketMatching.test.ts b/src/vs/editor/contrib/bracketMatching/test/browser/bracketMatching.test.ts index c2e738046d3..c16f4d7e9af 100644 --- a/src/vs/editor/contrib/bracketMatching/test/browser/bracketMatching.test.ts +++ b/src/vs/editor/contrib/bracketMatching/test/browser/bracketMatching.test.ts @@ -209,4 +209,27 @@ suite('bracket matching', () => { new Selection(1, 19, 1, 16) ]); }); + + test('Removes brackets', () => { + const editor = createCodeEditorWithBrackets('var x = (3 + (5-7)); y();'); + const bracketMatchingController = disposables.add(editor.registerAndInstantiateContribution(BracketMatchingController.ID, BracketMatchingController)); + function removeBrackets() { + bracketMatchingController.removeBrackets(); + } + + // position before the bracket + editor.setPosition(new Position(1, 9)); + removeBrackets(); + assert.deepStrictEqual(editor.getModel().getValue(), 'var x = 3 + (5-7); y();'); + editor.getModel().setValue('var x = (3 + (5-7)); y();'); + + // position between brackets + editor.setPosition(new Position(1, 16)); + removeBrackets(); + assert.deepStrictEqual(editor.getModel().getValue(), 'var x = (3 + 5-7); y();'); + removeBrackets(); + assert.deepStrictEqual(editor.getModel().getValue(), 'var x = 3 + 5-7; y();'); + removeBrackets(); + assert.deepStrictEqual(editor.getModel().getValue(), 'var x = 3 + 5-7; y();'); + }); }); diff --git a/src/vs/editor/contrib/clipboard/browser/clipboard.ts b/src/vs/editor/contrib/clipboard/browser/clipboard.ts index 488fc8a6056..420abfa16a4 100644 --- a/src/vs/editor/contrib/clipboard/browser/clipboard.ts +++ b/src/vs/editor/contrib/clipboard/browser/clipboard.ts @@ -16,6 +16,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import * as nls from 'vs/nls'; import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; @@ -107,7 +108,9 @@ export const CopyAction = supportsCopy ? registerCommand(new MultiCommand({ MenuRegistry.appendMenuItem(MenuId.MenubarEditMenu, { submenu: MenuId.MenubarCopy, title: { value: nls.localize('copy as', "Copy As"), original: 'Copy As', }, group: '2_ccp', order: 3 }); MenuRegistry.appendMenuItem(MenuId.EditorContext, { submenu: MenuId.EditorContextCopy, title: { value: nls.localize('copy as', "Copy As"), original: 'Copy As', }, group: CLIPBOARD_CONTEXT_MENU_GROUP, order: 3 }); -MenuRegistry.appendMenuItem(MenuId.EditorContext, { submenu: MenuId.EditorContextShare, title: { value: nls.localize('share', "Share"), original: 'Share', }, group: '11_share', order: -1 }); +MenuRegistry.appendMenuItem(MenuId.EditorContext, { submenu: MenuId.EditorContextShare, title: { value: nls.localize('share', "Share"), original: 'Share', }, group: '11_share', order: -1, when: ContextKeyExpr.and(ContextKeyExpr.notEquals('resourceScheme', 'output'), EditorContextKeys.editorTextFocus) }); +MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { submenu: MenuId.EditorTitleContextShare, title: { value: nls.localize('share', "Share"), original: 'Share', }, group: '11_share', order: -1 }); +MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { submenu: MenuId.ExplorerContextShare, title: { value: nls.localize('share', "Share"), original: 'Share', }, group: '11_share', order: -1 }); export const PasteAction = supportsPaste ? registerCommand(new MultiCommand({ id: 'editor.action.clipboardPasteAction', diff --git a/src/vs/editor/contrib/codeAction/browser/codeAction.ts b/src/vs/editor/contrib/codeAction/browser/codeAction.ts index da54b65ee99..9ce2ced9889 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeAction.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeAction.ts @@ -27,6 +27,8 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { CodeActionFilter, CodeActionItem, CodeActionKind, CodeActionSet, CodeActionTrigger, CodeActionTriggerSource, filtersAction, mayIncludeActionsOfKind } from '../common/types'; export const codeActionCommandId = 'editor.action.codeAction'; +export const quickFixCommandId = 'editor.action.quickFix'; +export const autoFixCommandId = 'editor.action.autoFix'; export const refactorCommandId = 'editor.action.refactor'; export const refactorPreviewCommandId = 'editor.action.refactor.preview'; export const sourceActionCommandId = 'editor.action.sourceAction'; @@ -231,7 +233,7 @@ export async function applyCodeAction( accessor: ServicesAccessor, item: CodeActionItem, codeActionReason: ApplyCodeActionReason, - options?: { preview?: boolean; editor?: ICodeEditor }, + options?: { readonly preview?: boolean; readonly editor?: ICodeEditor }, token: CancellationToken = CancellationToken.None, ): Promise { const bulkEditService = accessor.get(IBulkEditService); diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts b/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts index 3a03f4bdeab..d23a95b304b 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts @@ -3,30 +3,19 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { Lazy } from 'vs/base/common/lazy'; -import { Disposable } from 'vs/base/common/lifecycle'; import { escapeRegExpCharacters } from 'vs/base/common/strings'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, EditorCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; -import { IPosition } from 'vs/editor/common/core/position'; -import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; -import { CodeActionTriggerType } from 'vs/editor/common/languages'; -import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { applyCodeAction, ApplyCodeActionReason, codeActionCommandId, fixAllCommandId, organizeImportsCommandId, refactorCommandId, refactorPreviewCommandId, sourceActionCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction'; -import { CodeActionUi } from 'vs/editor/contrib/codeAction/browser/codeActionUi'; -import { MessageController } from 'vs/editor/contrib/message/browser/messageController'; +import { autoFixCommandId, codeActionCommandId, fixAllCommandId, organizeImportsCommandId, quickFixCommandId, refactorCommandId, sourceActionCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction'; import * as nls from 'vs/nls'; -import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { IMarkerService } from 'vs/platform/markers/common/markers'; -import { IEditorProgressService } from 'vs/platform/progress/common/progress'; -import { CodeActionModel, CodeActionsState, SUPPORTED_CODE_ACTIONS } from './codeActionModel'; -import { CodeActionAutoApply, CodeActionCommandArgs, CodeActionFilter, CodeActionItem, CodeActionKind, CodeActionSet, CodeActionTrigger, CodeActionTriggerSource } from '../common/types'; +import { CodeActionAutoApply, CodeActionCommandArgs, CodeActionFilter, CodeActionKind, CodeActionTriggerSource } from '../common/types'; +import { CodeActionController } from './codeActionController'; +import { SUPPORTED_CODE_ACTIONS } from './codeActionModel'; function contextKeyForSupportedActions(kind: CodeActionKind) { return ContextKeyExpr.regex( @@ -34,26 +23,6 @@ function contextKeyForSupportedActions(kind: CodeActionKind) { new RegExp('(\\s|^)' + escapeRegExpCharacters(kind.value) + '\\b')); } -function refactorTrigger(editor: ICodeEditor, userArgs: any, preview: boolean, codeActionFrom: CodeActionTriggerSource) { - const args = CodeActionCommandArgs.fromUser(userArgs, { - kind: CodeActionKind.Refactor, - apply: CodeActionAutoApply.Never - }); - return triggerCodeActionsForEditorSelection(editor, - typeof userArgs?.kind === 'string' - ? args.preferred - ? nls.localize('editor.action.refactor.noneMessage.preferred.kind', "No preferred refactorings for '{0}' available", userArgs.kind) - : nls.localize('editor.action.refactor.noneMessage.kind', "No refactorings for '{0}' available", userArgs.kind) - : args.preferred - ? nls.localize('editor.action.refactor.noneMessage.preferred', "No preferred refactorings available") - : nls.localize('editor.action.refactor.noneMessage', "No refactorings available"), - { - include: CodeActionKind.Refactor.contains(args.kind) ? args.kind : CodeActionKind.None, - onlyIncludePreferredActions: args.preferred - }, - args.apply, preview, codeActionFrom); -} - const argsSchema: IJSONSchema = { type: 'object', defaultSnippets: [{ body: { kind: '' } }], @@ -81,103 +50,24 @@ const argsSchema: IJSONSchema = { } }; -export class CodeActionController extends Disposable implements IEditorContribution { - - public static readonly ID = 'editor.contrib.codeActionController'; - - public static get(editor: ICodeEditor): CodeActionController | null { - return editor.getContribution(CodeActionController.ID); - } - - private readonly _editor: ICodeEditor; - private readonly _model: CodeActionModel; - private readonly _ui: Lazy; - - constructor( - editor: ICodeEditor, - @IMarkerService markerService: IMarkerService, - @IContextKeyService contextKeyService: IContextKeyService, - @IEditorProgressService progressService: IEditorProgressService, - @IInstantiationService private readonly _instantiationService: IInstantiationService, - @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService - ) { - super(); - - this._editor = editor; - - this._model = this._register(new CodeActionModel(this._editor, languageFeaturesService.codeActionProvider, markerService, contextKeyService, progressService)); - - this._register(this._model.onDidChangeState(newState => this.update(newState))); - - this._ui = new Lazy(() => - this._register(_instantiationService.createInstance(CodeActionUi, editor, QuickFixAction.Id, AutoFixAction.Id, { - applyCodeAction: async (action, retrigger, preview) => { - try { - await this._applyCodeAction(action, preview); - } finally { - if (retrigger) { - this._trigger({ type: CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.QuickFix, filter: {} }); - } - } - } - })) - ); - } - - private update(newState: CodeActionsState.State): void { - this._ui.value.update(newState); - } - - public showCodeActions(_trigger: CodeActionTrigger, actions: CodeActionSet, at: IAnchor | IPosition) { - return this._ui.value.showCodeActionList(actions, at, { includeDisabledActions: false, fromLightbulb: false }); - } - - public manualTriggerAtCurrentPosition( - notAvailableMessage: string, - triggerAction: CodeActionTriggerSource, - filter?: CodeActionFilter, - autoApply?: CodeActionAutoApply, - preview?: boolean, - ): void { - if (!this._editor.hasModel()) { - return; - } - - MessageController.get(this._editor)?.closeMessage(); - const triggerPosition = this._editor.getPosition(); - this._trigger({ type: CodeActionTriggerType.Invoke, triggerAction, filter, autoApply, context: { notAvailableMessage, position: triggerPosition }, preview }); - } - - private _trigger(trigger: CodeActionTrigger) { - return this._model.trigger(trigger); - } - - private _applyCodeAction(action: CodeActionItem, preview: boolean): Promise { - return this._instantiationService.invokeFunction(applyCodeAction, action, ApplyCodeActionReason.FromCodeActions, { preview, editor: this._editor }); - } -} - function triggerCodeActionsForEditorSelection( editor: ICodeEditor, notAvailableMessage: string, filter: CodeActionFilter | undefined, autoApply: CodeActionAutoApply | undefined, - preview: boolean = false, triggerAction: CodeActionTriggerSource = CodeActionTriggerSource.Default ): void { if (editor.hasModel()) { const controller = CodeActionController.get(editor); - controller?.manualTriggerAtCurrentPosition(notAvailableMessage, triggerAction, filter, autoApply, preview); + controller?.manualTriggerAtCurrentPosition(notAvailableMessage, triggerAction, filter, autoApply); } } export class QuickFixAction extends EditorAction { - static readonly Id = 'editor.action.quickFix'; - constructor() { super({ - id: QuickFixAction.Id, + id: quickFixCommandId, label: nls.localize('quickfix.trigger.label', "Quick Fix..."), alias: 'Quick Fix...', precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasCodeActionsProvider), @@ -190,7 +80,7 @@ export class QuickFixAction extends EditorAction { } public run(_accessor: ServicesAccessor, editor: ICodeEditor): void { - return triggerCodeActionsForEditorSelection(editor, nls.localize('editor.action.quickFix.noneMessage', "No code actions available"), undefined, undefined, false, CodeActionTriggerSource.QuickFix); + return triggerCodeActionsForEditorSelection(editor, nls.localize('editor.action.quickFix.noneMessage', "No code actions available"), undefined, undefined, CodeActionTriggerSource.QuickFix); } } @@ -261,27 +151,23 @@ export class RefactorAction extends EditorAction { } public run(_accessor: ServicesAccessor, editor: ICodeEditor, userArgs: any): void { - return refactorTrigger(editor, userArgs, false, CodeActionTriggerSource.Refactor); - } -} - -export class RefactorPreview extends EditorAction { - - constructor() { - super({ - id: refactorPreviewCommandId, - label: nls.localize('refactor.preview.label', "Refactor with Preview..."), - alias: 'Refactor Preview...', - precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasCodeActionsProvider), - description: { - description: 'Refactor Preview...', - args: [{ name: 'args', schema: argsSchema }] - } + const args = CodeActionCommandArgs.fromUser(userArgs, { + kind: CodeActionKind.Refactor, + apply: CodeActionAutoApply.Never }); - } - - public run(_accessor: ServicesAccessor, editor: ICodeEditor, userArgs: any): void { - return refactorTrigger(editor, userArgs, true, CodeActionTriggerSource.RefactorPreview); + return triggerCodeActionsForEditorSelection(editor, + typeof userArgs?.kind === 'string' + ? args.preferred + ? nls.localize('editor.action.refactor.noneMessage.preferred.kind', "No preferred refactorings for '{0}' available", userArgs.kind) + : nls.localize('editor.action.refactor.noneMessage.kind', "No refactorings for '{0}' available", userArgs.kind) + : args.preferred + ? nls.localize('editor.action.refactor.noneMessage.preferred', "No preferred refactorings available") + : nls.localize('editor.action.refactor.noneMessage', "No refactorings available"), + { + include: CodeActionKind.Refactor.contains(args.kind) ? args.kind : CodeActionKind.None, + onlyIncludePreferredActions: args.preferred + }, + args.apply, CodeActionTriggerSource.Refactor); } } @@ -325,7 +211,7 @@ export class SourceAction extends EditorAction { includeSourceActions: true, onlyIncludePreferredActions: args.preferred, }, - args.apply, undefined, CodeActionTriggerSource.SourceAction); + args.apply, CodeActionTriggerSource.SourceAction); } } @@ -351,7 +237,7 @@ export class OrganizeImportsAction extends EditorAction { return triggerCodeActionsForEditorSelection(editor, nls.localize('editor.action.organize.noneMessage', "No organize imports action available"), { include: CodeActionKind.SourceOrganizeImports, includeSourceActions: true }, - CodeActionAutoApply.IfSingle, undefined, CodeActionTriggerSource.OrganizeImports); + CodeActionAutoApply.IfSingle, CodeActionTriggerSource.OrganizeImports); } } @@ -372,17 +258,15 @@ export class FixAllAction extends EditorAction { return triggerCodeActionsForEditorSelection(editor, nls.localize('fixAll.noneMessage', "No fix all action available"), { include: CodeActionKind.SourceFixAll, includeSourceActions: true }, - CodeActionAutoApply.IfSingle, undefined, CodeActionTriggerSource.FixAll); + CodeActionAutoApply.IfSingle, CodeActionTriggerSource.FixAll); } } export class AutoFixAction extends EditorAction { - static readonly Id = 'editor.action.autoFix'; - constructor() { super({ - id: AutoFixAction.Id, + id: autoFixCommandId, label: nls.localize('autoFix.label', "Auto Fix..."), alias: 'Auto Fix...', precondition: ContextKeyExpr.and( @@ -406,6 +290,6 @@ export class AutoFixAction extends EditorAction { include: CodeActionKind.QuickFix, onlyIncludePreferredActions: true }, - CodeActionAutoApply.IfSingle, undefined, CodeActionTriggerSource.AutoFix); + CodeActionAutoApply.IfSingle, CodeActionTriggerSource.AutoFix); } } diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionContributions.ts b/src/vs/editor/contrib/codeAction/browser/codeActionContributions.ts index 8629326b68e..313859f2026 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionContributions.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionContributions.ts @@ -5,7 +5,8 @@ import { EditorContributionInstantiation, registerEditorAction, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { editorConfigurationBaseNode } from 'vs/editor/common/config/editorConfigurationSchema'; -import { AutoFixAction, CodeActionCommand, CodeActionController, FixAllAction, OrganizeImportsAction, QuickFixAction, RefactorAction, RefactorPreview, SourceAction } from 'vs/editor/contrib/codeAction/browser/codeActionCommands'; +import { AutoFixAction, CodeActionCommand, FixAllAction, OrganizeImportsAction, QuickFixAction, RefactorAction, SourceAction } from 'vs/editor/contrib/codeAction/browser/codeActionCommands'; +import { CodeActionController } from 'vs/editor/contrib/codeAction/browser/codeActionController'; import * as nls from 'vs/nls'; import { ConfigurationScope, Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -13,7 +14,6 @@ import { Registry } from 'vs/platform/registry/common/platform'; registerEditorContribution(CodeActionController.ID, CodeActionController, EditorContributionInstantiation.Eventually); registerEditorAction(QuickFixAction); registerEditorAction(RefactorAction); -registerEditorAction(RefactorPreview); registerEditorAction(SourceAction); registerEditorAction(OrganizeImportsAction); registerEditorAction(AutoFixAction); diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionController.ts b/src/vs/editor/contrib/codeAction/browser/codeActionController.ts new file mode 100644 index 00000000000..252360cc64b --- /dev/null +++ b/src/vs/editor/contrib/codeAction/browser/codeActionController.ts @@ -0,0 +1,93 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; +import { Lazy } from 'vs/base/common/lazy'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { IPosition } from 'vs/editor/common/core/position'; +import { IEditorContribution } from 'vs/editor/common/editorCommon'; +import { CodeActionTriggerType } from 'vs/editor/common/languages'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { applyCodeAction, ApplyCodeActionReason } from 'vs/editor/contrib/codeAction/browser/codeAction'; +import { CodeActionUi } from 'vs/editor/contrib/codeAction/browser/codeActionUi'; +import { MessageController } from 'vs/editor/contrib/message/browser/messageController'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IMarkerService } from 'vs/platform/markers/common/markers'; +import { IEditorProgressService } from 'vs/platform/progress/common/progress'; +import { CodeActionAutoApply, CodeActionFilter, CodeActionItem, CodeActionSet, CodeActionTrigger, CodeActionTriggerSource } from '../common/types'; +import { CodeActionModel } from './codeActionModel'; + + +export class CodeActionController extends Disposable implements IEditorContribution { + + public static readonly ID = 'editor.contrib.codeActionController'; + + public static get(editor: ICodeEditor): CodeActionController | null { + return editor.getContribution(CodeActionController.ID); + } + + private readonly _editor: ICodeEditor; + private readonly _model: CodeActionModel; + private readonly _ui: Lazy; + + constructor( + editor: ICodeEditor, + @IMarkerService markerService: IMarkerService, + @IContextKeyService contextKeyService: IContextKeyService, + @IEditorProgressService progressService: IEditorProgressService, + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService + ) { + super(); + + this._editor = editor; + + this._model = this._register(new CodeActionModel(this._editor, languageFeaturesService.codeActionProvider, markerService, contextKeyService, progressService)); + + this._register(this._model.onDidChangeState(newState => this._ui.value.update(newState))); + + this._ui = new Lazy(() => this._register(_instantiationService.createInstance(CodeActionUi, editor, { + applyCodeAction: async (action, retrigger, preview) => { + try { + await this._applyCodeAction(action, preview); + } finally { + if (retrigger) { + this._trigger({ type: CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.QuickFix, filter: {} }); + } + } + } + })) + ); + } + + public showCodeActions(_trigger: CodeActionTrigger, actions: CodeActionSet, at: IAnchor | IPosition) { + return this._ui.value.showCodeActionList(actions, at, { includeDisabledActions: false, fromLightbulb: false }); + } + + public manualTriggerAtCurrentPosition( + notAvailableMessage: string, + triggerAction: CodeActionTriggerSource, + filter?: CodeActionFilter, + autoApply?: CodeActionAutoApply, + ): void { + if (!this._editor.hasModel()) { + return; + } + + MessageController.get(this._editor)?.closeMessage(); + const triggerPosition = this._editor.getPosition(); + this._trigger({ type: CodeActionTriggerType.Invoke, triggerAction, filter, autoApply, context: { notAvailableMessage, position: triggerPosition } }); + } + + private _trigger(trigger: CodeActionTrigger) { + return this._model.trigger(trigger); + } + + private _applyCodeAction(action: CodeActionItem, preview: boolean): Promise { + return this._instantiationService.invokeFunction(applyCodeAction, action, ApplyCodeActionReason.FromCodeActions, { preview, editor: this._editor }); + } +} diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index 214d23cb989..0f645908a5f 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -11,7 +11,7 @@ import { CodeAction } from 'vs/editor/common/languages'; import { CodeActionItem, CodeActionKind } from 'vs/editor/contrib/codeAction/common/types'; import 'vs/editor/contrib/symbolIcons/browser/symbolIcons'; // The codicon symbol colors are defined here and must be loaded to get colors import { localize } from 'vs/nls'; -import { ActionListItemKind, IListMenuItem } from 'vs/platform/actionWidget/browser/actionList'; +import { ActionListItemKind, IActionListItem } from 'vs/platform/actionWidget/browser/actionList'; interface ActionGroup { readonly kind: CodeActionKind; @@ -36,9 +36,9 @@ export function toMenuItems( inputCodeActions: readonly CodeActionItem[], showHeaders: boolean, keybindingResolver: (action: CodeAction) => ResolvedKeybinding | undefined -): IListMenuItem[] { +): IActionListItem[] { if (!showHeaders) { - return inputCodeActions.map((action): IListMenuItem => { + return inputCodeActions.map((action): IActionListItem => { return { kind: ActionListItemKind.Action, item: action, @@ -62,7 +62,7 @@ export function toMenuItems( } } - const allMenuItems: IListMenuItem[] = []; + const allMenuItems: IActionListItem[] = []; for (const menuEntry of menuEntries) { if (menuEntry.actions.length) { allMenuItems.push({ kind: ActionListItemKind.Header, group: menuEntry.group }); diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts index 85f4a83cd3f..3979c4e4538 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts @@ -12,22 +12,20 @@ import { URI } from 'vs/base/common/uri'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; -import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; import { CodeActionProvider, CodeActionTriggerType } from 'vs/editor/common/languages'; import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IMarkerService } from 'vs/platform/markers/common/markers'; import { IEditorProgressService, Progress } from 'vs/platform/progress/common/progress'; -import { getCodeActions } from './codeAction'; import { CodeActionSet, CodeActionTrigger, CodeActionTriggerSource } from '../common/types'; +import { getCodeActions } from './codeAction'; export const SUPPORTED_CODE_ACTIONS = new RawContextKey('supportedCodeAction', ''); -type TriggeredCodeAction = undefined | { +type TriggeredCodeAction = { readonly selection: Selection; readonly trigger: CodeActionTrigger; - readonly position: Position; }; class CodeActionOracle extends Disposable { @@ -37,33 +35,27 @@ class CodeActionOracle extends Disposable { constructor( private readonly _editor: ICodeEditor, private readonly _markerService: IMarkerService, - private readonly _signalChange: (triggered: TriggeredCodeAction) => void, + private readonly _signalChange: (triggered: TriggeredCodeAction | undefined) => void, private readonly _delay: number = 250, ) { super(); this._register(this._markerService.onMarkerChanged(e => this._onMarkerChanges(e))); - this._register(this._editor.onDidChangeCursorPosition(() => this._onCursorChange())); + this._register(this._editor.onDidChangeCursorPosition(() => this._tryAutoTrigger())); } - public trigger(trigger: CodeActionTrigger): TriggeredCodeAction { + public trigger(trigger: CodeActionTrigger): void { const selection = this._getRangeOfSelectionUnlessWhitespaceEnclosed(trigger); - return this._createEventAndSignalChange(trigger, selection); + this._signalChange(selection ? { trigger, selection } : undefined); } private _onMarkerChanges(resources: readonly URI[]): void { const model = this._editor.getModel(); - if (!model) { - return; - } - - if (resources.some(resource => isEqual(resource, model.uri))) { - this._autoTriggerTimer.cancelAndSet(() => { - this.trigger({ type: CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default }); - }, this._delay); + if (model && resources.some(resource => isEqual(resource, model.uri))) { + this._tryAutoTrigger(); } } - private _onCursorChange(): void { + private _tryAutoTrigger() { this._autoTriggerTimer.cancelAndSet(() => { this.trigger({ type: CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default }); }, this._delay); @@ -73,6 +65,7 @@ class CodeActionOracle extends Disposable { if (!this._editor.hasModel()) { return undefined; } + const model = this._editor.getModel(); const selection = this._editor.getSelection(); if (selection.isEmpty() && trigger.type === CodeActionTriggerType.Auto) { @@ -100,31 +93,11 @@ class CodeActionOracle extends Disposable { } return selection; } - - private _createEventAndSignalChange(trigger: CodeActionTrigger, selection: Selection | undefined): TriggeredCodeAction { - const model = this._editor.getModel(); - if (!selection || !model) { - // cancel - this._signalChange(undefined); - return undefined; - } - - const e: TriggeredCodeAction = { - trigger, - selection, - position: selection.getStartPosition(), - }; - this._signalChange(e); - return e; - } } export namespace CodeActionsState { - export const enum Type { - Empty, - Triggered, - } + export const enum Type { Empty, Triggered } export const Empty = { type: Type.Empty } as const; @@ -135,7 +108,6 @@ export namespace CodeActionsState { constructor( public readonly trigger: CodeActionTrigger, - public readonly rangeOrSelection: Range | Selection, public readonly position: Position, private readonly _cancellablePromise: CancelablePromise, ) { @@ -155,18 +127,19 @@ export namespace CodeActionsState { export type State = typeof Empty | Triggered; } -const emptyCodeActionSet: CodeActionSet = { +const emptyCodeActionSet = Object.freeze({ allActions: [], validActions: [], dispose: () => { }, documentation: [], hasAutoFix: false -}; +}); export class CodeActionModel extends Disposable { private readonly _codeActionOracle = this._register(new MutableDisposable()); private _state: CodeActionsState.State = CodeActionsState.Empty; + private readonly _supportedCodeActions: IContextKey; private readonly _onDidChangeState = this._register(new Emitter()); @@ -215,13 +188,7 @@ export class CodeActionModel extends Disposable { && this._registry.has(model) && !this._editor.getOption(EditorOption.readOnly) ) { - const supportedActions: string[] = []; - for (const provider of this._registry.all(model)) { - if (Array.isArray(provider.providedCodeActionKinds)) { - supportedActions.push(...provider.providedCodeActionKinds); - } - } - + const supportedActions: string[] = this._registry.all(model).flatMap(provider => provider.providedCodeActionKinds ?? []); this._supportedCodeActions.set(supportedActions.join(' ')); this._codeActionOracle.value = new CodeActionOracle(this._editor, this._markerService, trigger => { @@ -235,8 +202,7 @@ export class CodeActionModel extends Disposable { this._progressService?.showWhile(actions, 250); } - this.setState(new CodeActionsState.Triggered(trigger.trigger, trigger.selection, trigger.position, actions)); - + this.setState(new CodeActionsState.Triggered(trigger.trigger, trigger.selection.getStartPosition(), actions)); }, undefined); this._codeActionOracle.value.trigger({ type: CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default }); } else { diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionUi.ts b/src/vs/editor/contrib/codeAction/browser/codeActionUi.ts index 14bba132c54..5b9b6812064 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionUi.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionUi.ts @@ -17,13 +17,14 @@ import { CodeActionKeybindingResolver } from 'vs/editor/contrib/codeAction/brows import { toMenuItems } from 'vs/editor/contrib/codeAction/browser/codeActionMenu'; import { MessageController } from 'vs/editor/contrib/message/browser/messageController'; import { localize } from 'vs/nls'; -import { IActionWidgetService, IRenderDelegate } from 'vs/platform/actionWidget/browser/actionWidget'; +import { IActionWidgetService } from 'vs/platform/actionWidget/browser/actionWidget'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { CodeActionAutoApply, CodeActionItem, CodeActionSet, CodeActionTrigger } from '../common/types'; import { CodeActionsState } from './codeActionModel'; import { LightBulbWidget } from './lightBulbWidget'; +import { IActionListDelegate } from 'vs/platform/actionWidget/browser/actionList'; export interface IActionShowOptions { readonly includeDisabledActions?: boolean; @@ -43,10 +44,8 @@ export class CodeActionUi extends Disposable { constructor( private readonly _editor: ICodeEditor, - quickFixActionId: string, - preferredFixActionId: string, private readonly delegate: { - applyCodeAction: (action: CodeActionItem, regtriggerAfterApply: boolean, preview: boolean) => Promise; + applyCodeAction: (action: CodeActionItem, retriggerAfterApply: boolean, preview: boolean) => Promise; }, @IInstantiationService instantiationService: IInstantiationService, @IConfigurationService private readonly _configurationService: IConfigurationService, @@ -56,7 +55,7 @@ export class CodeActionUi extends Disposable { super(); this._lightBulbWidget = new Lazy(() => { - const widget = this._register(instantiationService.createInstance(LightBulbWidget, this._editor, quickFixActionId, preferredFixActionId)); + const widget = this._register(instantiationService.createInstance(LightBulbWidget, this._editor)); this._register(widget.onClick(e => this.showCodeActionList(e.actions, e, { includeDisabledActions: false, fromLightbulb: true }))); return widget; }); @@ -181,9 +180,9 @@ export class CodeActionUi extends Disposable { const anchor = Position.isIPosition(at) ? this.toCoords(at) : at; - const delegate: IRenderDelegate = { + const delegate: IActionListDelegate = { onSelect: async (action: CodeActionItem, preview?: boolean) => { - this.delegate.applyCodeAction(action, /* retrigger */ true, !!preview ? preview : false); + this.delegate.applyCodeAction(action, /* retrigger */ true, !!preview); this._actionWidgetService.hide(); }, onHide: () => { @@ -234,7 +233,7 @@ export class CodeActionUi extends Disposable { tooltip: command.tooltip ?? '', class: undefined, enabled: true, - run: () => this._commandService.executeCommand(command.id, ...(command.commandArguments ?? [])), + run: () => this._commandService.executeCommand(command.id, ...(command.arguments ?? [])), })); if (options.includeDisabledActions && actions.validActions.length > 0 && actions.allActions.length !== actions.validActions.length) { diff --git a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts index ff0d6d7864e..8921ee1c4f0 100644 --- a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts +++ b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts @@ -6,15 +6,16 @@ import * as dom from 'vs/base/browser/dom'; import { Gesture } from 'vs/base/browser/touch'; import { Codicon } from 'vs/base/common/codicons'; -import { ThemeIcon } from 'vs/base/common/themables'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; +import { ThemeIcon } from 'vs/base/common/themables'; import { withNullAsUndefined } from 'vs/base/common/types'; import 'vs/css!./lightBulbWidget'; import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { IPosition } from 'vs/editor/common/core/position'; import { computeIndentLevel } from 'vs/editor/common/model/utils'; +import { autoFixCommandId, quickFixCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction'; import type { CodeActionSet, CodeActionTrigger } from 'vs/editor/contrib/codeAction/common/types'; import * as nls from 'vs/nls'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -59,8 +60,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget { constructor( private readonly _editor: ICodeEditor, - quickFixActionId: string, - preferredFixActionId: string, + @IKeybindingService keybindingService: IKeybindingService ) { super(); @@ -122,8 +122,8 @@ export class LightBulbWidget extends Disposable implements IContentWidget { })); this._register(Event.runAndSubscribe(keybindingService.onDidUpdateKeybindings, () => { - this._preferredKbLabel = withNullAsUndefined(keybindingService.lookupKeybinding(preferredFixActionId)?.getLabel()); - this._quickFixKbLabel = withNullAsUndefined(keybindingService.lookupKeybinding(quickFixActionId)?.getLabel()); + this._preferredKbLabel = withNullAsUndefined(keybindingService.lookupKeybinding(autoFixCommandId)?.getLabel()); + this._quickFixKbLabel = withNullAsUndefined(keybindingService.lookupKeybinding(quickFixCommandId)?.getLabel()); this._updateLightBulbTitleAndIcon(); })); diff --git a/src/vs/editor/contrib/codeAction/common/types.ts b/src/vs/editor/contrib/codeAction/common/types.ts index 07f55364a3b..e1e8d835765 100644 --- a/src/vs/editor/contrib/codeAction/common/types.ts +++ b/src/vs/editor/contrib/codeAction/common/types.ts @@ -7,7 +7,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { onUnexpectedExternalError } from 'vs/base/common/errors'; import { Position } from 'vs/editor/common/core/position'; import * as languages from 'vs/editor/common/languages'; -import { ActionSet, IActionItem } from 'vs/platform/actionWidget/common/actionWidget'; +import { ActionSet } from 'vs/platform/actionWidget/common/actionWidget'; export class CodeActionKind { private static readonly sep = '.'; @@ -146,7 +146,6 @@ export interface CodeActionTrigger { readonly notAvailableMessage: string; readonly position: Position; }; - readonly preview?: boolean; } export class CodeActionCommandArgs { @@ -188,7 +187,7 @@ export class CodeActionCommandArgs { ) { } } -export class CodeActionItem implements IActionItem { +export class CodeActionItem { constructor( public readonly action: languages.CodeAction, @@ -215,10 +214,5 @@ export interface CodeActionSet extends ActionSet { readonly validActions: readonly CodeActionItem[]; readonly allActions: readonly CodeActionItem[]; - readonly documentation: readonly { - id: string; - title: string; - tooltip?: string; - commandArguments?: any[]; - }[]; + readonly documentation: readonly languages.Command[]; } diff --git a/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts b/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts index adb039eecf6..cbc1b7ccdb8 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts @@ -46,7 +46,7 @@ export class ColorHover implements IHoverPart { export class ColorHoverParticipant implements IEditorHoverParticipant { - public readonly hoverOrdinal: number = 1; + public readonly hoverOrdinal: number = 2; constructor( private readonly _editor: ICodeEditor, diff --git a/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts b/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts index e087c797b27..4eef122381b 100644 --- a/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts +++ b/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts @@ -26,6 +26,7 @@ import { IContextMenuService, IContextViewService } from 'vs/platform/contextvie import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IWorkspaceContextService, isStandaloneEditorWorkspace } from 'vs/platform/workspace/common/workspace'; export class ContextMenuController implements IEditorContribution { @@ -47,6 +48,7 @@ export class ContextMenuController implements IEditorContribution { @IKeybindingService private readonly _keybindingService: IKeybindingService, @IMenuService private readonly _menuService: IMenuService, @IConfigurationService private readonly _configurationService: IConfigurationService, + @IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService, ) { this._editor = editor; @@ -262,6 +264,11 @@ export class ContextMenuController implements IEditorContribution { return; } + if (isStandaloneEditorWorkspace(this._workspaceContextService.getWorkspace())) { + // can't update the configuration properly in the standalone editor + return; + } + const minimapOptions = this._editor.getOption(EditorOption.minimap); let lastId = 0; diff --git a/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts b/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts index 941c0a0d91e..0b188d354bf 100644 --- a/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts +++ b/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts @@ -104,6 +104,7 @@ export class DropIntoEditorController extends Disposable implements IEditorContr ...(providerEdit.additionalEdit?.edits ?? []) ] }; + editor.focus(); await this._bulkEditService.apply(combinedWorkspaceEdit, { editor }); return; } diff --git a/src/vs/editor/contrib/find/browser/findWidget.ts b/src/vs/editor/contrib/find/browser/findWidget.ts index 0f7c5d9aeae..56c28e740ac 100644 --- a/src/vs/editor/contrib/find/browser/findWidget.ts +++ b/src/vs/editor/contrib/find/browser/findWidget.ts @@ -731,8 +731,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL this._domNode.style.maxWidth = `${editorWidth - 28 - minimapWidth - 15}px`; } + this._findInput.layout({ collapsedFindWidget, narrowFindWidget, reducedFindWidget }); if (this._resized) { - this._findInput.inputBox.layout(); const findInputWidth = this._findInput.inputBox.element.clientWidth; if (findInputWidth > 0) { this._replaceInput.width = findInputWidth; diff --git a/src/vs/editor/contrib/folding/browser/folding.css b/src/vs/editor/contrib/folding/browser/folding.css index 049465c97b7..f973d5f7a30 100644 --- a/src/vs/editor/contrib/folding/browser/folding.css +++ b/src/vs/editor/contrib/folding/browser/folding.css @@ -16,6 +16,13 @@ margin-left: 2px; } +.monaco-workbench.reduce-motion .monaco-editor .margin-view-overlays .codicon-folding-manual-collapsed, +.monaco-workbench.reduce-motion .monaco-editor .margin-view-overlays .codicon-folding-manual-expanded, +.monaco-workbench.reduce-motion .monaco-editor .margin-view-overlays .codicon-folding-expanded, +.monaco-workbench.reduce-motion .monaco-editor .margin-view-overlays .codicon-folding-collapsed { + transition: initial; +} + .monaco-editor .margin-view-overlays:hover .codicon, .monaco-editor .margin-view-overlays .codicon.codicon-folding-collapsed, .monaco-editor .margin-view-overlays .codicon.codicon-folding-manual-collapsed, diff --git a/src/vs/editor/contrib/folding/browser/indentRangeProvider.ts b/src/vs/editor/contrib/folding/browser/indentRangeProvider.ts index e3e83443ec1..de53762d48f 100644 --- a/src/vs/editor/contrib/folding/browser/indentRangeProvider.ts +++ b/src/vs/editor/contrib/folding/browser/indentRangeProvider.ts @@ -35,7 +35,7 @@ export class IndentRangeProvider implements RangeProvider { } // public only for testing -class RangesCollector { +export class RangesCollector { private readonly _startIndexes: number[]; private readonly _endIndexes: number[]; private readonly _indentOccurrences: number[]; diff --git a/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts b/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts index d8215e7aa41..2a063882078 100644 --- a/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts +++ b/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts @@ -6,12 +6,12 @@ import * as assert from 'assert'; import { FoldingMarkers } from 'vs/editor/common/languages/languageConfiguration'; import { MAX_FOLDING_REGIONS, FoldRange, FoldingRegions, FoldSource } from 'vs/editor/contrib/folding/browser/foldingRanges'; -import { computeRanges } from 'vs/editor/contrib/folding/browser/indentRangeProvider'; +import { RangesCollector, computeRanges } from 'vs/editor/contrib/folding/browser/indentRangeProvider'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; const markers: FoldingMarkers = { - start: /^\s*#region\b/, - end: /^\s*#endregion\b/ + start: /^#region$/, + end: /^#endregion$/ }; suite('FoldingRanges', () => { @@ -35,20 +35,17 @@ suite('FoldingRanges', () => { test('test max folding regions', () => { const lines: string[] = []; const nRegions = MAX_FOLDING_REGIONS; + const collector = new RangesCollector({ limit: MAX_FOLDING_REGIONS, update: () => { } }); for (let i = 0; i < nRegions; i++) { + const startLineNumber = lines.length; lines.push('#region'); - } - for (let i = 0; i < nRegions; i++) { + const endLineNumber = lines.length; lines.push('#endregion'); + collector.insertFirst(startLineNumber, endLineNumber, 0); } const model = createTextModel(lines.join('\n')); - const actual = computeRanges(model, false, markers, { limit: MAX_FOLDING_REGIONS, update: () => { } }); + const actual = collector.toIndentRanges(model); assert.strictEqual(actual.length, nRegions, 'len'); - for (let i = 0; i < nRegions; i++) { - assert.strictEqual(actual.getStartLineNumber(i), i + 1, 'start' + i); - assert.strictEqual(actual.getEndLineNumber(i), nRegions * 2 - i, 'end' + i); - assert.strictEqual(actual.getParentIndex(i), i - 1, 'parent' + i); - } model.dispose(); }); diff --git a/src/vs/editor/contrib/format/browser/format.ts b/src/vs/editor/contrib/format/browser/format.ts index e25cf6e1a61..b12c941d375 100644 --- a/src/vs/editor/contrib/format/browser/format.ts +++ b/src/vs/editor/contrib/format/browser/format.ts @@ -27,7 +27,7 @@ import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { FormattingEdit } from 'vs/editor/contrib/format/browser/formattingEdit'; import * as nls from 'vs/nls'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { ExtensionIdentifierSet } from 'vs/platform/extensions/common/extensions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IProgress } from 'vs/platform/progress/common/progress'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; @@ -67,14 +67,14 @@ export function getRealAndSyntheticDocumentFormattersOrdered( model: ITextModel ): DocumentFormattingEditProvider[] { const result: DocumentFormattingEditProvider[] = []; - const seen = new Set(); + const seen = new ExtensionIdentifierSet(); // (1) add all document formatter const docFormatter = documentFormattingEditProvider.ordered(model); for (const formatter of docFormatter) { result.push(formatter); if (formatter.extensionId) { - seen.add(ExtensionIdentifier.toKey(formatter.extensionId)); + seen.add(formatter.extensionId); } } @@ -82,10 +82,10 @@ export function getRealAndSyntheticDocumentFormattersOrdered( const rangeFormatter = documentRangeFormattingEditProvider.ordered(model); for (const formatter of rangeFormatter) { if (formatter.extensionId) { - if (seen.has(ExtensionIdentifier.toKey(formatter.extensionId))) { + if (seen.has(formatter.extensionId)) { continue; } - seen.add(ExtensionIdentifier.toKey(formatter.extensionId)); + seen.add(formatter.extensionId); } result.push({ displayName: formatter.displayName, diff --git a/src/vs/editor/contrib/gotoSymbol/browser/goToCommands.ts b/src/vs/editor/contrib/gotoSymbol/browser/goToCommands.ts index d164b19a607..6c753076a49 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/goToCommands.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/goToCommands.ts @@ -92,7 +92,7 @@ export abstract class SymbolNavigationAction extends EditorAction2 { } } } - return result; + return result; } readonly configuration: SymbolNavigationActionConfig; diff --git a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts index ee7ef53aa64..ca4597bc57e 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts @@ -313,7 +313,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget { enabled: false } }; - this._preview = this._instantiationService.createInstance(EmbeddedCodeEditorWidget, this._previewContainer, options, this.editor); + this._preview = this._instantiationService.createInstance(EmbeddedCodeEditorWidget, this._previewContainer, options, {}, this.editor); dom.hide(this._previewContainer); this._previewNotAvailableMessage = new TextModel(nls.localize('missingPreviewMessage', "no preview available"), PLAINTEXT_LANGUAGE_ID, TextModel.DEFAULT_CREATION_OPTIONS, null, this._undoRedoService, this._languageService, this._languageConfigurationService); diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index d561f70b771..26741f8e033 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -208,6 +208,10 @@ export class ContentHoverController extends Disposable { return this._widget.isVisibleFromKeyboard; } + public isVisible(): boolean { + return this._widget.isVisible; + } + public containsNode(node: Node): boolean { return this._widget.getDomNode().contains(node); } @@ -340,6 +344,46 @@ export class ContentHoverController extends Disposable { highlightRange }; } + + public focus(): void { + this._widget.focus(); + } + + public scrollUp(): void { + this._widget.scrollUp(); + } + + public scrollDown(): void { + this._widget.scrollDown(); + } + + public scrollLeft(): void { + this._widget.scrollLeft(); + } + + public scrollRight(): void { + this._widget.scrollRight(); + } + + public pageUp(): void { + this._widget.pageUp(); + } + + public pageDown(): void { + this._widget.pageDown(); + } + + public goToTop(): void { + this._widget.goToTop(); + } + + public goToBottom(): void { + this._widget.goToBottom(); + } + + public escape(): void { + this._widget.escape(); + } } class HoverResult { @@ -400,8 +444,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public readonly allowEditorOverflow = true; private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); + private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _hover: HoverWidget = this._register(new HoverWidget()); - + private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); + private readonly _horizontalScrollingBy: number = 30; private _visibleData: ContentHoverVisibleData | null = null; /** @@ -419,6 +465,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return (this._visibleData?.source === HoverStartSource.Keyboard); } + public get isVisible(): boolean { + return this._hoverVisibleKey.get() ?? false; + } + constructor( private readonly _editor: ICodeEditor, @IContextKeyService private readonly _contextKeyService: IContextKeyService, @@ -435,6 +485,13 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._setVisibleData(null); this._layout(); this._editor.addContentWidget(this); + + this._register(this._focusTracker.onDidFocus(() => { + this._hoverFocusedKey.set(true); + })); + this._register(this._focusTracker.onDidBlur(() => { + this._hoverFocusedKey.set(false); + })); } public override dispose(): void { @@ -580,6 +637,56 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public clear(): void { this._hover.contentsDomNode.textContent = ''; } + + public focus(): void { + this._hover.containerDomNode.focus(); + } + + public scrollUp(): void { + const scrollTop = this._hover.scrollbar.getScrollPosition().scrollTop; + const fontInfo = this._editor.getOption(EditorOption.fontInfo); + this._hover.scrollbar.setScrollPosition({ scrollTop: scrollTop - fontInfo.lineHeight }); + } + + public scrollDown(): void { + const scrollTop = this._hover.scrollbar.getScrollPosition().scrollTop; + const fontInfo = this._editor.getOption(EditorOption.fontInfo); + this._hover.scrollbar.setScrollPosition({ scrollTop: scrollTop + fontInfo.lineHeight }); + } + + public scrollLeft(): void { + const scrollLeft = this._hover.scrollbar.getScrollPosition().scrollLeft; + this._hover.scrollbar.setScrollPosition({ scrollLeft: scrollLeft - this._horizontalScrollingBy }); + } + + public scrollRight(): void { + const scrollLeft = this._hover.scrollbar.getScrollPosition().scrollLeft; + this._hover.scrollbar.setScrollPosition({ scrollLeft: scrollLeft + this._horizontalScrollingBy }); + } + + public pageUp(): void { + const scrollTop = this._hover.scrollbar.getScrollPosition().scrollTop; + const scrollHeight = this._hover.scrollbar.getScrollDimensions().height; + this._hover.scrollbar.setScrollPosition({ scrollTop: scrollTop - scrollHeight }); + } + + public pageDown(): void { + const scrollTop = this._hover.scrollbar.getScrollPosition().scrollTop; + const scrollHeight = this._hover.scrollbar.getScrollDimensions().height; + this._hover.scrollbar.setScrollPosition({ scrollTop: scrollTop + scrollHeight }); + } + + public goToTop(): void { + this._hover.scrollbar.setScrollPosition({ scrollTop: 0 }); + } + + public goToBottom(): void { + this._hover.scrollbar.setScrollPosition({ scrollTop: this._hover.scrollbar.getScrollDimensions().scrollHeight }); + } + + public escape(): void { + this._editor.focus(); + } } class EditorHoverStatusBar extends Disposable implements IEditorHoverStatusBar { diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index f2fe99c3d93..10df5c93513 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -19,7 +19,6 @@ import { ContentHoverWidget, ContentHoverController } from 'vs/editor/contrib/ho import { MarginHoverWidget } from 'vs/editor/contrib/hover/browser/marginHover'; import * as nls from 'vs/nls'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IOpenerService } from 'vs/platform/opener/common/opener'; @@ -30,6 +29,7 @@ import { MarkdownHoverParticipant } from 'vs/editor/contrib/hover/browser/markdo import { MarkerHoverParticipant } from 'vs/editor/contrib/hover/browser/markerHoverParticipant'; import 'vs/css!./hover'; import { InlineSuggestionHintsContentWidget } from 'vs/editor/contrib/inlineCompletions/browser/inlineSuggestionHintsWidget'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; export class ModesHoverController implements IEditorContribution { @@ -54,7 +54,7 @@ export class ModesHoverController implements IEditorContribution { @IInstantiationService private readonly _instantiationService: IInstantiationService, @IOpenerService private readonly _openerService: IOpenerService, @ILanguageService private readonly _languageService: ILanguageService, - @IContextKeyService _contextKeyService: IContextKeyService + @IKeybindingService private readonly _keybindingService: IKeybindingService ) { this._isMouseDown = false; this._hoverClicked = false; @@ -199,7 +199,16 @@ export class ModesHoverController implements IEditorContribution { } private _onKeyDown(e: IKeyboardEvent): void { - if (e.keyCode !== KeyCode.Ctrl && e.keyCode !== KeyCode.Alt && e.keyCode !== KeyCode.Meta && e.keyCode !== KeyCode.Shift) { + if (!this._editor.hasModel()) { + return; + } + + const resolvedKeyboardEvent = this._keybindingService.softDispatch(e, this._editor.getDomNode()); + // If the beginning of a multi-chord keybinding is pressed, or the command aims to focus the hover, set the variable to true, otherwise false + const mightTriggerFocus = (resolvedKeyboardEvent?.enterMultiChord || (resolvedKeyboardEvent?.commandId === 'editor.action.showHover' && this._contentWidget?.isVisible())); + + if (e.keyCode !== KeyCode.Ctrl && e.keyCode !== KeyCode.Alt && e.keyCode !== KeyCode.Meta && e.keyCode !== KeyCode.Shift + && !mightTriggerFocus) { // Do not hide hover when a modifier key is pressed this._hideWidgets(); } @@ -230,6 +239,50 @@ export class ModesHoverController implements IEditorContribution { this._getOrCreateContentWidget().startShowingAtRange(range, mode, source, focus); } + public focus(): void { + this._contentWidget?.focus(); + } + + public scrollUp(): void { + this._contentWidget?.scrollUp(); + } + + public scrollDown(): void { + this._contentWidget?.scrollDown(); + } + + public scrollLeft(): void { + this._contentWidget?.scrollLeft(); + } + + public scrollRight(): void { + this._contentWidget?.scrollRight(); + } + + public pageUp(): void { + this._contentWidget?.pageUp(); + } + + public pageDown(): void { + this._contentWidget?.pageDown(); + } + + public goToTop(): void { + this._contentWidget?.goToTop(); + } + + public goToBottom(): void { + this._contentWidget?.goToBottom(); + } + + public escape(): void { + this._contentWidget?.escape(); + } + + public isHoverVisible(): boolean | undefined { + return this._contentWidget?.isVisible(); + } + public dispose(): void { this._unhookEvents(); this._toUnhook.dispose(); @@ -239,19 +292,37 @@ export class ModesHoverController implements IEditorContribution { } } -class ShowHoverAction extends EditorAction { +class ShowOrFocusHoverAction extends EditorAction { constructor() { super({ id: 'editor.action.showHover', label: nls.localize({ - key: 'showHover', + key: 'showOrFocusHover', comment: [ - 'Label for action that will trigger the showing of a hover in the editor.', - 'This allows for users to show the hover without using the mouse.' + 'Label for action that will trigger the showing/focusing of a hover in the editor.', + 'If the hover is not visible, it will show the hover.', + 'This allows for users to show the hover without using the mouse.', + 'If the hover is already visible, it will take focus.' ] - }, "Show Hover"), - alias: 'Show Hover', + }, "Show or Focus Hover"), + description: { + description: `Show or Focus Hover`, + args: [{ + name: 'args', + schema: { + type: 'object', + properties: { + 'focus': { + description: 'Controls if when triggered with the keyboard, the hover should take focus immediately.', + type: 'boolean', + default: false + } + }, + } + }] + }, + alias: 'Show or Focus Hover', precondition: undefined, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, @@ -261,7 +332,7 @@ class ShowHoverAction extends EditorAction { }); } - public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + public run(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void { if (!editor.hasModel()) { return; } @@ -271,8 +342,13 @@ class ShowHoverAction extends EditorAction { } const position = editor.getPosition(); const range = new Range(position.lineNumber, position.column, position.lineNumber, position.column); - const focus = editor.getOption(EditorOption.accessibilitySupport) === AccessibilitySupport.Enabled; - controller.showContentHover(range, HoverStartMode.Immediate, HoverStartSource.Keyboard, focus); + const focus = editor.getOption(EditorOption.accessibilitySupport) === AccessibilitySupport.Enabled || !!args?.focus; + + if (controller.isHoverVisible()) { + controller.focus(); + } else { + controller.showContentHover(range, HoverStartMode.Immediate, HoverStartSource.Keyboard, focus); + } } } @@ -316,9 +392,294 @@ class ShowDefinitionPreviewHoverAction extends EditorAction { } } +class ScrollUpHoverAction extends EditorAction { + + constructor() { + super({ + id: 'editor.action.scrollUpHover', + label: nls.localize({ + key: 'scrollUpHover', + comment: [ + 'Action that allows to scroll up in the hover widget with the up arrow when the hover widget is focused.' + ] + }, "Scroll Up Hover"), + alias: 'Scroll Up Hover', + precondition: EditorContextKeys.hoverFocused, + kbOpts: { + kbExpr: EditorContextKeys.hoverFocused, + primary: KeyCode.UpArrow, + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + const controller = ModesHoverController.get(editor); + if (!controller) { + return; + } + controller.scrollUp(); + } +} + +class ScrollDownHoverAction extends EditorAction { + + constructor() { + super({ + id: 'editor.action.scrollDownHover', + label: nls.localize({ + key: 'scrollDownHover', + comment: [ + 'Action that allows to scroll down in the hover widget with the up arrow when the hover widget is focused.' + ] + }, "Scroll Down Hover"), + alias: 'Scroll Down Hover', + precondition: EditorContextKeys.hoverFocused, + kbOpts: { + kbExpr: EditorContextKeys.hoverFocused, + primary: KeyCode.DownArrow, + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + const controller = ModesHoverController.get(editor); + if (!controller) { + return; + } + controller.scrollDown(); + } +} + +class ScrollLeftHoverAction extends EditorAction { + + constructor() { + super({ + id: 'editor.action.scrollLeftHover', + label: nls.localize({ + key: 'scrollLeftHover', + comment: [ + 'Action that allows to scroll left in the hover widget with the left arrow when the hover widget is focused.' + ] + }, "Scroll Left Hover"), + alias: 'Scroll Left Hover', + precondition: EditorContextKeys.hoverFocused, + kbOpts: { + kbExpr: EditorContextKeys.hoverFocused, + primary: KeyCode.LeftArrow, + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + const controller = ModesHoverController.get(editor); + if (!controller) { + return; + } + controller.scrollLeft(); + } +} + +class ScrollRightHoverAction extends EditorAction { + + constructor() { + super({ + id: 'editor.action.scrollRightHover', + label: nls.localize({ + key: 'scrollRightHover', + comment: [ + 'Action that allows to scroll right in the hover widget with the right arrow when the hover widget is focused.' + ] + }, "Scroll Right Hover"), + alias: 'Scroll Right Hover', + precondition: EditorContextKeys.hoverFocused, + kbOpts: { + kbExpr: EditorContextKeys.hoverFocused, + primary: KeyCode.RightArrow, + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + const controller = ModesHoverController.get(editor); + if (!controller) { + return; + } + controller.scrollRight(); + } +} + +class PageUpHoverAction extends EditorAction { + + constructor() { + super({ + id: 'editor.action.pageUpHover', + label: nls.localize({ + key: 'pageUpHover', + comment: [ + 'Action that allows to page up in the hover widget with the page up command when the hover widget is focused.' + ] + }, "Page Up Hover"), + alias: 'Page Up Hover', + precondition: EditorContextKeys.hoverFocused, + kbOpts: { + kbExpr: EditorContextKeys.hoverFocused, + primary: KeyCode.PageUp, + secondary: [KeyMod.Alt | KeyCode.UpArrow], + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + const controller = ModesHoverController.get(editor); + if (!controller) { + return; + } + controller.pageUp(); + } +} + + +class PageDownHoverAction extends EditorAction { + + constructor() { + super({ + id: 'editor.action.pageDownHover', + label: nls.localize({ + key: 'pageDownHover', + comment: [ + 'Action that allows to page down in the hover widget with the page down command when the hover widget is focused.' + ] + }, "Page Down Hover"), + alias: 'Page Down Hover', + precondition: EditorContextKeys.hoverFocused, + kbOpts: { + kbExpr: EditorContextKeys.hoverFocused, + primary: KeyCode.PageDown, + secondary: [KeyMod.Alt | KeyCode.DownArrow], + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + const controller = ModesHoverController.get(editor); + if (!controller) { + return; + } + controller.pageDown(); + } +} + +class GoToTopHoverAction extends EditorAction { + + constructor() { + super({ + id: 'editor.action.goToTopHover', + label: nls.localize({ + key: 'goToTopHover', + comment: [ + 'Action that allows to go to the top of the hover widget with the home command when the hover widget is focused.' + ] + }, "Go To Top Hover"), + alias: 'Go To Bottom Hover', + precondition: EditorContextKeys.hoverFocused, + kbOpts: { + kbExpr: EditorContextKeys.hoverFocused, + primary: KeyCode.Home, + secondary: [KeyMod.CtrlCmd | KeyCode.UpArrow], + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + const controller = ModesHoverController.get(editor); + if (!controller) { + return; + } + controller.goToTop(); + } +} + + +class GoToBottomHoverAction extends EditorAction { + + constructor() { + super({ + id: 'editor.action.goToBottomHover', + label: nls.localize({ + key: 'goToBottomHover', + comment: [ + 'Action that allows to go to the bottom in the hover widget with the end command when the hover widget is focused.' + ] + }, "Go To Bottom Hover"), + alias: 'Go To Bottom Hover', + precondition: EditorContextKeys.hoverFocused, + kbOpts: { + kbExpr: EditorContextKeys.hoverFocused, + primary: KeyCode.End, + secondary: [KeyMod.CtrlCmd | KeyCode.DownArrow], + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + const controller = ModesHoverController.get(editor); + if (!controller) { + return; + } + controller.goToBottom(); + } +} + +class EscapeFocusHoverAction extends EditorAction { + + constructor() { + super({ + id: 'editor.action.escapeFocusHover', + label: nls.localize({ + key: 'escapeFocusHover', + comment: [ + 'Action that allows to escape from the hover widget with the escape command when the hover widget is focused.' + ] + }, "Escape Focus Hover"), + alias: 'Escape Focus Hover', + precondition: EditorContextKeys.hoverFocused, + kbOpts: { + kbExpr: EditorContextKeys.hoverFocused, + primary: KeyCode.Escape, + weight: KeybindingWeight.EditorContrib + } + }); + } + + public run(accessor: ServicesAccessor, editor: ICodeEditor): void { + const controller = ModesHoverController.get(editor); + if (!controller) { + return; + } + controller.escape(); + } +} + registerEditorContribution(ModesHoverController.ID, ModesHoverController, EditorContributionInstantiation.BeforeFirstInteraction); -registerEditorAction(ShowHoverAction); +registerEditorAction(ShowOrFocusHoverAction); registerEditorAction(ShowDefinitionPreviewHoverAction); +registerEditorAction(ScrollUpHoverAction); +registerEditorAction(ScrollDownHoverAction); +registerEditorAction(ScrollLeftHoverAction); +registerEditorAction(ScrollRightHoverAction); +registerEditorAction(PageUpHoverAction); +registerEditorAction(PageDownHoverAction); +registerEditorAction(GoToTopHoverAction); +registerEditorAction(GoToBottomHoverAction); +registerEditorAction(EscapeFocusHoverAction); HoverParticipantRegistry.register(MarkdownHoverParticipant); HoverParticipantRegistry.register(MarkerHoverParticipant); diff --git a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts index 4bee3614c9b..93f4631209b 100644 --- a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts +++ b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts @@ -46,7 +46,7 @@ export class MarkdownHover implements IHoverPart { export class MarkdownHoverParticipant implements IEditorHoverParticipant { - public readonly hoverOrdinal: number = 2; + public readonly hoverOrdinal: number = 3; constructor( protected readonly _editor: ICodeEditor, diff --git a/src/vs/editor/contrib/hover/browser/markerHoverParticipant.ts b/src/vs/editor/contrib/hover/browser/markerHoverParticipant.ts index 30b0a539f1a..01a02e67812 100644 --- a/src/vs/editor/contrib/hover/browser/markerHoverParticipant.ts +++ b/src/vs/editor/contrib/hover/browser/markerHoverParticipant.ts @@ -12,11 +12,12 @@ import { basename } from 'vs/base/common/resources'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { Range } from 'vs/editor/common/core/range'; -import { IModelDecoration } from 'vs/editor/common/model'; import { CodeActionTriggerType } from 'vs/editor/common/languages'; +import { IModelDecoration } from 'vs/editor/common/model'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { IMarkerDecorationsService } from 'vs/editor/common/services/markerDecorations'; -import { getCodeActions } from 'vs/editor/contrib/codeAction/browser/codeAction'; -import { QuickFixAction, CodeActionController } from 'vs/editor/contrib/codeAction/browser/codeActionCommands'; +import { getCodeActions, quickFixCommandId } from 'vs/editor/contrib/codeAction/browser/codeAction'; +import { CodeActionController } from 'vs/editor/contrib/codeAction/browser/codeActionController'; import { CodeActionKind, CodeActionSet, CodeActionTrigger, CodeActionTriggerSource } from 'vs/editor/contrib/codeAction/common/types'; import { MarkerController, NextMarkerAction } from 'vs/editor/contrib/gotoError/browser/gotoError'; import { HoverAnchor, HoverAnchorType, IEditorHoverParticipant, IEditorHoverRenderContext, IHoverPart } from 'vs/editor/contrib/hover/browser/hoverTypes'; @@ -25,7 +26,6 @@ import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { IMarker, IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { Progress } from 'vs/platform/progress/common/progress'; -import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; const $ = dom.$; @@ -54,7 +54,7 @@ const markerCodeActionTrigger: CodeActionTrigger = { export class MarkerHoverParticipant implements IEditorHoverParticipant { - public readonly hoverOrdinal: number = 5; + public readonly hoverOrdinal: number = 1; private recentMarkerCodeActionsInfo: { marker: IMarker; hasCodeActions: boolean } | undefined = undefined; @@ -219,7 +219,7 @@ export class MarkerHoverParticipant implements IEditorHoverParticipant { showing = true; const controller = CodeActionController.get(this._editor); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextController.ts b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextController.ts index 4415eff9d91..7d5ecbfbb34 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextController.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextController.ts @@ -255,7 +255,6 @@ export class ShowNextInlineSuggestionAction extends EditorAction { const controller = GhostTextController.get(editor); if (controller) { controller.showNextInlineCompletion(); - editor.focus(); } } } @@ -279,7 +278,6 @@ export class ShowPreviousInlineSuggestionAction extends EditorAction { const controller = GhostTextController.get(editor); if (controller) { controller.showPreviousInlineCompletion(); - editor.focus(); } } } diff --git a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextHoverParticipant.ts b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextHoverParticipant.ts index 2c36f88c3d1..d6eac9d12e9 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextHoverParticipant.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextHoverParticipant.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as dom from 'vs/base/browser/dom'; +import { Event } from 'vs/base/common/event'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; @@ -65,7 +66,7 @@ export class InlineCompletionsHover implements IHoverPart { export class InlineCompletionsHoverParticipant implements IEditorHoverParticipant { - public readonly hoverOrdinal: number = 3; + public readonly hoverOrdinal: number = 4; constructor( private readonly _editor: ICodeEditor, @@ -148,7 +149,7 @@ export class InlineCompletionsHoverParticipant implements IEditorHoverParticipan private renderScreenReaderText(context: IEditorHoverRenderContext, part: InlineCompletionsHover, disposableStore: DisposableStore) { const $ = dom.$; const markdownHoverElement = $('div.hover-row.markdown-hover'); - const hoverContentsElement = dom.append(markdownHoverElement, $('div.hover-contents')); + const hoverContentsElement = dom.append(markdownHoverElement, $('div.hover-contents', { ['aria-live']: 'assertive' })); const renderer = disposableStore.add(new MarkdownRenderer({ editor: this._editor }, this._languageService, this._openerService)); const render = (code: string) => { disposableStore.add(renderer.onDidRenderAsync(() => { @@ -161,11 +162,17 @@ export class InlineCompletionsHoverParticipant implements IEditorHoverParticipan hoverContentsElement.replaceChildren(renderedContents.element); }; - const ghostText = part.controller.activeModel?.inlineCompletionsModel?.ghostText; - if (ghostText) { - const lineText = this._editor.getModel()!.getLineContent(ghostText.lineNumber); - render(ghostText.renderForScreenReader(lineText)); - } + disposableStore.add(Event.runAndSubscribe(e => part.onDidChange(e), () => { + const ghostText = part.controller.activeModel?.inlineCompletionsModel?.ghostText; + if (ghostText) { + const lineText = this._editor.getModel()!.getLineContent(ghostText.lineNumber); + render(ghostText.renderForScreenReader(lineText)); + } else { + dom.reset(hoverContentsElement); + } + })); + + context.fragment.appendChild(markdownHoverElement); } } diff --git a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts index fe1ad377ea0..042a0322ac3 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts @@ -22,6 +22,8 @@ import { RenderLineInput, renderViewLine } from 'vs/editor/common/viewLayout/vie import { InlineDecorationType } from 'vs/editor/common/viewModel'; import { GhostTextReplacement, GhostTextWidgetModel } from 'vs/editor/contrib/inlineCompletions/browser/ghostText'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { alert } from 'vs/base/browser/ui/aria/aria'; +import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; const ttPolicy = window.trustedTypes?.createPolicy('editorGhostText', { createHTML: value => value }); @@ -36,6 +38,7 @@ export class GhostTextWidget extends Disposable { private readonly model: GhostTextWidgetModel, @IInstantiationService private readonly instantiationService: IInstantiationService, @ILanguageService private readonly languageService: ILanguageService, + @IAudioCueService private readonly audioCueService: IAudioCueService ) { super(); @@ -61,10 +64,8 @@ export class GhostTextWidget extends Disposable { this.viewMoreContentWidget = undefined; })); - this._register(model.onDidChange(() => { - this.update(); - })); - this.update(); + this._register(model.onDidChange(() => this.update(true))); + this.update(true); } public shouldShowHoverAtViewZone(viewZoneId: string): boolean { @@ -73,7 +74,7 @@ export class GhostTextWidget extends Disposable { private readonly replacementDecoration = this._register(new DisposableDecorations(this.editor)); - private update(): void { + private update(notifyUser?: boolean): void { const ghostText = this.model.ghostText; if (!this.editor.hasModel() || !ghostText || this.disposed) { @@ -157,6 +158,17 @@ export class GhostTextWidget extends Disposable { hiddenTextStartColumn !== undefined ? { column: hiddenTextStartColumn, length: textBufferLine.length + 1 - hiddenTextStartColumn } : undefined); this.additionalLinesWidget.updateLines(ghostText.lineNumber, additionalLines, ghostText.additionalReservedLineCount); + if (notifyUser) { + this.audioCueService.playAudioCue(AudioCue.inlineSuggestion).then(() => { + if (this.editor.getOption(EditorOption.screenReaderAnnounceInlineSuggestion)) { + const lineText = this.editor.getModel()?.getLineContent(ghostText.lineNumber); + if (lineText) { + alert(ghostText.renderForScreenReader(lineText)); + } + } + }); + } + if (0 < 0) { // Not supported at the moment, condition is always false. this.viewMoreContentWidget = this.renderViewMoreLines( diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index 4e230dc8350..4f79ed9fd6d 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -192,8 +192,10 @@ export class InlineCompletionsModel extends Disposable implements GhostTextWidge } public hide(): void { - this.completionSession.clear(); - this.onDidChangeEmitter.fire(); + if (this.completionSession.value) { + this.completionSession.clear(); + this.onDidChangeEmitter.fire(); + } } public commitCurrentSuggestion(): void { @@ -483,7 +485,9 @@ export class InlineCompletionsSession extends BaseGhostTextWidgetModel { ); const endTime = new Date(); - this.debounce.update(this.editor.getModel(), endTime.getTime() - startTime.getTime()); + if (this.editor.hasModel()) { + this.debounce.update(this.editor.getModel(), endTime.getTime() - startTime.getTime()); + } } catch (e) { onUnexpectedError(e); @@ -710,7 +714,7 @@ export class SynchronizedInlineCompletionsCache extends Disposable { for (const c of this.completions) { const newRange = model.getDecorationRange(c.decorationId); if (!newRange) { - onUnexpectedError(new Error('Decoration has no range')); + // onUnexpectedError(new Error('Decoration has no range')); continue; } if (!c.synchronizedRange.equalsRange(newRange)) { diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineSuggestionHintsWidget.css b/src/vs/editor/contrib/inlineCompletions/browser/inlineSuggestionHintsWidget.css index 108de44c413..642e6c51d7a 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineSuggestionHintsWidget.css +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineSuggestionHintsWidget.css @@ -5,7 +5,7 @@ .monaco-editor .inlineSuggestionsHints.withBorder { z-index: 39; - color: var(--vscode-editor-hoverForeground); + color: var(--vscode-editorHoverWidget-foreground); background-color: var(--vscode-editorHoverWidget-background); border: 1px solid var(--vscode-editorHoverWidget-border); } diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineSuggestionHintsWidget.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineSuggestionHintsWidget.ts index ee1d55d27a6..72a89f2a970 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineSuggestionHintsWidget.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineSuggestionHintsWidget.ts @@ -7,6 +7,7 @@ import { h } from 'vs/base/browser/dom'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; 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'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Codicon } from 'vs/base/common/codicons'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; @@ -36,6 +37,7 @@ export class InlineSuggestionHintsWidget extends Disposable { private readonly widget = this._register(this.instantiationService.createInstance(InlineSuggestionHintsContentWidget, this.editor, true)); private sessionPosition: Position | undefined = undefined; + private isDisposed = false; constructor( private readonly editor: ICodeEditor, @@ -51,7 +53,16 @@ export class InlineSuggestionHintsWidget extends Disposable { this.update(); } + override dispose(): void { + this.isDisposed = true; + super.dispose(); + } + private update(): void { + if (this.isDisposed) { + return; + } + const options = this.editor.getOption(EditorOption.inlineSuggest); if (options.showToolbar !== 'always' || !this.model.ghostText) { this.widget.update(null, 0, undefined, []); @@ -144,6 +155,10 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC this.previousAction.enabled = this.nextAction.enabled = false; }, 100)); + private lastCurrentSuggestionIdx = -1; + private lastSuggestionCount = -1; + private lastCommands: Command[] = []; + constructor( private readonly editor: ICodeEditor, private readonly withBorder: boolean, @@ -176,7 +191,18 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC } public update(position: Position | null, currentSuggestionIdx: number, suggestionCount: number | undefined, extraCommands: Command[]): void { + if (this.position === position + && this.lastCurrentSuggestionIdx === currentSuggestionIdx + && this.lastSuggestionCount === suggestionCount + && equals(this.lastCommands, extraCommands)) { + // nothing to update + return; + } + this.position = position; + this.lastCurrentSuggestionIdx = currentSuggestionIdx; + this.lastSuggestionCount = suggestionCount ?? -1; + this.lastCommands = extraCommands; if (suggestionCount !== undefined && suggestionCount > 1) { this.disableButtonsDebounced.cancel(); @@ -288,6 +314,11 @@ export class CustomizedMenuWorkbenchToolBar extends WorkbenchToolBar { } setAdditionalSecondaryActions(actions: IAction[]): void { + if (equals(this.additionalActions, actions, (a, b) => a === b)) { + // don't update if the actions are the same + return; + } + this.additionalActions = actions; this.updateToolbar(); } diff --git a/src/vs/editor/contrib/inlineCompletions/test/browser/inlineCompletionsProvider.test.ts b/src/vs/editor/contrib/inlineCompletions/test/browser/inlineCompletionsProvider.test.ts index 6c9d94964ea..ac2c4982aec 100644 --- a/src/vs/editor/contrib/inlineCompletions/test/browser/inlineCompletionsProvider.test.ts +++ b/src/vs/editor/contrib/inlineCompletions/test/browser/inlineCompletionsProvider.test.ts @@ -547,7 +547,6 @@ suite('Inline Completions', () => { assert.deepStrictEqual(context.getAndClearViewStates(), [ '', - 'hello\n', 'hello[world]\n', 'hello\n', 'hello\nhello[world]', diff --git a/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts b/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts index 639b238809e..f4404988cdc 100644 --- a/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts +++ b/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts @@ -8,6 +8,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; import { IMarkdownString, MarkdownStringTrustedOptions } from 'vs/base/common/htmlContent'; import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; +import 'vs/css!./renderedMarkdown'; import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; @@ -17,13 +18,13 @@ import { tokenizeToString } from 'vs/editor/common/languages/textToHtmlTokenizer import { IOpenerService } from 'vs/platform/opener/common/opener'; export interface IMarkdownRenderResult extends IDisposable { - element: HTMLElement; + readonly element: HTMLElement; } export interface IMarkdownRendererOptions { - editor?: ICodeEditor; - codeBlockFontFamily?: string; - codeBlockFontSize?: string; + readonly editor?: ICodeEditor; + readonly codeBlockFontFamily?: string; + readonly codeBlockFontSize?: string; } /** @@ -59,6 +60,7 @@ export class MarkdownRenderer { const disposables = new DisposableStore(); const rendered = disposables.add(renderMarkdown(markdown, { ...this._getRenderOptions(markdown, disposables), ...options }, markedOptions)); + rendered.element.classList.add('rendered-markdown'); return { element: rendered.element, dispose: () => disposables.dispose() diff --git a/src/vs/editor/contrib/markdownRenderer/browser/renderedMarkdown.css b/src/vs/editor/contrib/markdownRenderer/browser/renderedMarkdown.css new file mode 100644 index 00000000000..d784524a2f1 --- /dev/null +++ b/src/vs/editor/contrib/markdownRenderer/browser/renderedMarkdown.css @@ -0,0 +1,17 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.monaco-editor .rendered-markdown kbd { + background-color: var(--vscode-keybindingLabel-background); + color: var(--vscode-keybindingLabel-foreground); + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: var(--vscode-keybindingLabel-border); + border-bottom-color: var(--vscode-keybindingLabel-bottomBorder); + box-shadow: inset 0 -1px 0 var(--vscode-widget-shadow); + vertical-align: middle; + padding: 1px 3px; +} diff --git a/src/vs/editor/contrib/parameterHints/browser/parameterHints.css b/src/vs/editor/contrib/parameterHints/browser/parameterHints.css index d6537f63f1c..93758171dac 100644 --- a/src/vs/editor/contrib/parameterHints/browser/parameterHints.css +++ b/src/vs/editor/contrib/parameterHints/browser/parameterHints.css @@ -10,7 +10,7 @@ flex-direction: column; line-height: 1.5em; cursor: default; - color: var(--vscode-editor-hoverForeground); + color: var(--vscode-editorHoverWidget-foreground); background-color: var(--vscode-editorHoverWidget-background); border: 1px solid var(--vscode-editorHoverWidget-border); } diff --git a/src/vs/editor/contrib/peekView/browser/peekView.ts b/src/vs/editor/contrib/peekView/browser/peekView.ts index 49df433bf1a..5c0882b8db4 100644 --- a/src/vs/editor/contrib/peekView/browser/peekView.ts +++ b/src/vs/editor/contrib/peekView/browser/peekView.ts @@ -26,7 +26,7 @@ import { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActio import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { createDecorator, IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { activeContrastBorder, contrastBorder, editorForeground, editorInfoForeground, registerColor, transparent } from 'vs/platform/theme/common/colorRegistry'; +import { activeContrastBorder, contrastBorder, editorForeground, editorInfoForeground, registerColor } from 'vs/platform/theme/common/colorRegistry'; export const IPeekViewService = createDecorator('IPeekViewService'); export interface IPeekViewService { @@ -278,7 +278,7 @@ export abstract class PeekViewWidget extends ZoneWidget { } -export const peekViewTitleBackground = registerColor('peekViewTitle.background', { dark: transparent(editorInfoForeground, .1), light: transparent(editorInfoForeground, .1), hcDark: null, hcLight: null }, nls.localize('peekViewTitleBackground', 'Background color of the peek view title area.')); +export const peekViewTitleBackground = registerColor('peekViewTitle.background', { dark: '#252526', light: '#F3F3F3', hcDark: Color.black, hcLight: Color.white }, nls.localize('peekViewTitleBackground', 'Background color of the peek view title area.')); export const peekViewTitleForeground = registerColor('peekViewTitleLabel.foreground', { dark: Color.white, light: Color.black, hcDark: Color.white, hcLight: editorForeground }, nls.localize('peekViewTitleForeground', 'Color of the peek view title.')); export const peekViewTitleInfoForeground = registerColor('peekViewTitleDescription.foreground', { dark: '#ccccccb3', light: '#616161', hcDark: '#FFFFFF99', hcLight: '#292929' }, nls.localize('peekViewTitleInfoForeground', 'Color of the peek view title info.')); export const peekViewBorder = registerColor('peekView.border', { dark: editorInfoForeground, light: editorInfoForeground, hcDark: contrastBorder, hcLight: contrastBorder }, nls.localize('peekViewBorder', 'Color of the peek view borders and arrow.')); diff --git a/src/vs/editor/contrib/rename/browser/rename.ts b/src/vs/editor/contrib/rename/browser/rename.ts index 6b9f4f50237..d7e8f452cc7 100644 --- a/src/vs/editor/contrib/rename/browser/rename.ts +++ b/src/vs/editor/contrib/rename/browser/rename.ts @@ -191,6 +191,7 @@ class RenameController implements IEditorContribution { } if (this._cts.token.isCancellationRequested) { + this._cts.dispose(); return undefined; } this._cts.dispose(); @@ -330,7 +331,7 @@ registerEditorCommand(new RenameCommand({ handler: x => x.acceptRenameInput(false), kbOpts: { weight: KeybindingWeight.EditorContrib + 99, - kbExpr: EditorContextKeys.focus, + kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, ContextKeyExpr.not('isComposing')), primary: KeyCode.Enter } })); @@ -341,7 +342,7 @@ registerEditorCommand(new RenameCommand({ handler: x => x.acceptRenameInput(true), kbOpts: { weight: KeybindingWeight.EditorContrib + 99, - kbExpr: EditorContextKeys.focus, + kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, ContextKeyExpr.not('isComposing')), primary: KeyMod.Shift + KeyCode.Enter } })); diff --git a/src/vs/editor/contrib/rename/browser/renameInputField.ts b/src/vs/editor/contrib/rename/browser/renameInputField.ts index 9e27efec8b7..2ea6da1d7f8 100644 --- a/src/vs/editor/contrib/rename/browser/renameInputField.ts +++ b/src/vs/editor/contrib/rename/browser/renameInputField.ts @@ -8,6 +8,7 @@ import { DisposableStore } from 'vs/base/common/lifecycle'; import 'vs/css!./renameInputField'; import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; +import { IDimension } from 'vs/editor/common/core/dimension'; import { Position } from 'vs/editor/common/core/position'; import { IRange } from 'vs/editor/common/core/range'; import { ScrollType } from 'vs/editor/common/editorCommon'; @@ -79,13 +80,6 @@ export class RenameInputField implements IContentWidget { this._label = document.createElement('div'); this._label.className = 'rename-label'; this._domNode.appendChild(this._label); - const updateLabel = () => { - const [accept, preview] = this._acceptKeybindings; - this._keybindingService.lookupKeybinding(accept); - this._label!.innerText = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Rename, Shift+F2 to Preview"'] }, "{0} to Rename, {1} to Preview", this._keybindingService.lookupKeybinding(accept)?.getLabel(), this._keybindingService.lookupKeybinding(preview)?.getLabel()); - }; - updateLabel(); - this._disposables.add(this._keybindingService.onDidUpdateKeybindings(updateLabel)); this._updateFont(); this._updateStyles(this._themeService.getColorTheme()); @@ -136,6 +130,12 @@ export class RenameInputField implements IContentWidget { }; } + beforeRender(): IDimension | null { + const [accept, preview] = this._acceptKeybindings; + this._label!.innerText = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Rename, Shift+F2 to Preview"'] }, "{0} to Rename, {1} to Preview", this._keybindingService.lookupKeybinding(accept)?.getLabel(), this._keybindingService.lookupKeybinding(preview)?.getLabel()); + return null; + } + afterRender(position: ContentWidgetPositionPreference | null): void { if (!position) { // cancel rename when input widget isn't rendered anymore diff --git a/src/vs/editor/contrib/semanticTokens/browser/documentSemanticTokens.ts b/src/vs/editor/contrib/semanticTokens/browser/documentSemanticTokens.ts new file mode 100644 index 00000000000..43c004886d0 --- /dev/null +++ b/src/vs/editor/contrib/semanticTokens/browser/documentSemanticTokens.ts @@ -0,0 +1,386 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; +import * as errors from 'vs/base/common/errors'; +import { ITextModel } from 'vs/editor/common/model'; +import { IModelContentChangedEvent } from 'vs/editor/common/textModelEvents'; +import { DocumentSemanticTokensProvider, SemanticTokens, SemanticTokensEdits } from 'vs/editor/common/languages'; +import { IModelService } from 'vs/editor/common/services/model'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { RunOnceScheduler } from 'vs/base/common/async'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { SemanticTokensProviderStyling, toMultilineTokens2 } from 'vs/editor/common/services/semanticTokensProviderStyling'; +import { getDocumentSemanticTokens, hasDocumentSemanticTokensProvider, isSemanticTokens, isSemanticTokensEdits } from 'vs/editor/contrib/semanticTokens/common/getSemanticTokens'; +import { IFeatureDebounceInformation, ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; +import { StopWatch } from 'vs/base/common/stopwatch'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; +import { ISemanticTokensStylingService } from 'vs/editor/common/services/semanticTokensStyling'; +import { registerEditorFeature } from 'vs/editor/common/editorFeatures'; +import { SEMANTIC_HIGHLIGHTING_SETTING_ID, isSemanticColoringEnabled } from 'vs/editor/contrib/semanticTokens/common/semanticTokensConfig'; + +export class DocumentSemanticTokensFeature extends Disposable { + + private readonly _watchers: Record; + + constructor( + @ISemanticTokensStylingService semanticTokensStylingService: ISemanticTokensStylingService, + @IModelService modelService: IModelService, + @IThemeService themeService: IThemeService, + @IConfigurationService configurationService: IConfigurationService, + @ILanguageFeatureDebounceService languageFeatureDebounceService: ILanguageFeatureDebounceService, + @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, + ) { + super(); + this._watchers = Object.create(null); + + const register = (model: ITextModel) => { + this._watchers[model.uri.toString()] = new ModelSemanticColoring(model, semanticTokensStylingService, themeService, languageFeatureDebounceService, languageFeaturesService); + }; + const deregister = (model: ITextModel, modelSemanticColoring: ModelSemanticColoring) => { + modelSemanticColoring.dispose(); + delete this._watchers[model.uri.toString()]; + }; + const handleSettingOrThemeChange = () => { + for (const model of modelService.getModels()) { + const curr = this._watchers[model.uri.toString()]; + if (isSemanticColoringEnabled(model, themeService, configurationService)) { + if (!curr) { + register(model); + } + } else { + if (curr) { + deregister(model, curr); + } + } + } + }; + this._register(modelService.onModelAdded((model) => { + if (isSemanticColoringEnabled(model, themeService, configurationService)) { + register(model); + } + })); + this._register(modelService.onModelRemoved((model) => { + const curr = this._watchers[model.uri.toString()]; + if (curr) { + deregister(model, curr); + } + })); + this._register(configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(SEMANTIC_HIGHLIGHTING_SETTING_ID)) { + handleSettingOrThemeChange(); + } + })); + this._register(themeService.onDidColorThemeChange(handleSettingOrThemeChange)); + } + + override dispose(): void { + // Dispose all watchers + for (const watcher of Object.values(this._watchers)) { + watcher.dispose(); + } + super.dispose(); + } +} + +class ModelSemanticColoring extends Disposable { + + public static REQUEST_MIN_DELAY = 300; + public static REQUEST_MAX_DELAY = 2000; + + private _isDisposed: boolean; + private readonly _model: ITextModel; + private readonly _provider: LanguageFeatureRegistry; + private readonly _debounceInformation: IFeatureDebounceInformation; + private readonly _fetchDocumentSemanticTokens: RunOnceScheduler; + private _currentDocumentResponse: SemanticTokensResponse | null; + private _currentDocumentRequestCancellationTokenSource: CancellationTokenSource | null; + private _documentProvidersChangeListeners: IDisposable[]; + private _providersChangedDuringRequest: boolean; + + constructor( + model: ITextModel, + @ISemanticTokensStylingService private readonly _semanticTokensStylingService: ISemanticTokensStylingService, + @IThemeService themeService: IThemeService, + @ILanguageFeatureDebounceService languageFeatureDebounceService: ILanguageFeatureDebounceService, + @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, + ) { + super(); + + this._isDisposed = false; + this._model = model; + this._provider = languageFeaturesService.documentSemanticTokensProvider; + this._debounceInformation = languageFeatureDebounceService.for(this._provider, 'DocumentSemanticTokens', { min: ModelSemanticColoring.REQUEST_MIN_DELAY, max: ModelSemanticColoring.REQUEST_MAX_DELAY }); + this._fetchDocumentSemanticTokens = this._register(new RunOnceScheduler(() => this._fetchDocumentSemanticTokensNow(), ModelSemanticColoring.REQUEST_MIN_DELAY)); + this._currentDocumentResponse = null; + this._currentDocumentRequestCancellationTokenSource = null; + this._documentProvidersChangeListeners = []; + this._providersChangedDuringRequest = false; + + this._register(this._model.onDidChangeContent(() => { + if (!this._fetchDocumentSemanticTokens.isScheduled()) { + this._fetchDocumentSemanticTokens.schedule(this._debounceInformation.get(this._model)); + } + })); + this._register(this._model.onDidChangeLanguage(() => { + // clear any outstanding state + if (this._currentDocumentResponse) { + this._currentDocumentResponse.dispose(); + this._currentDocumentResponse = null; + } + if (this._currentDocumentRequestCancellationTokenSource) { + this._currentDocumentRequestCancellationTokenSource.cancel(); + this._currentDocumentRequestCancellationTokenSource = null; + } + this._setDocumentSemanticTokens(null, null, null, []); + this._fetchDocumentSemanticTokens.schedule(0); + })); + + const bindDocumentChangeListeners = () => { + dispose(this._documentProvidersChangeListeners); + this._documentProvidersChangeListeners = []; + for (const provider of this._provider.all(model)) { + if (typeof provider.onDidChange === 'function') { + this._documentProvidersChangeListeners.push(provider.onDidChange(() => { + if (this._currentDocumentRequestCancellationTokenSource) { + // there is already a request running, + this._providersChangedDuringRequest = true; + return; + } + this._fetchDocumentSemanticTokens.schedule(0); + })); + } + } + }; + bindDocumentChangeListeners(); + this._register(this._provider.onDidChange(() => { + bindDocumentChangeListeners(); + this._fetchDocumentSemanticTokens.schedule(this._debounceInformation.get(this._model)); + })); + + this._register(themeService.onDidColorThemeChange(_ => { + // clear out existing tokens + this._setDocumentSemanticTokens(null, null, null, []); + this._fetchDocumentSemanticTokens.schedule(this._debounceInformation.get(this._model)); + })); + + this._fetchDocumentSemanticTokens.schedule(0); + } + + public override dispose(): void { + if (this._currentDocumentResponse) { + this._currentDocumentResponse.dispose(); + this._currentDocumentResponse = null; + } + if (this._currentDocumentRequestCancellationTokenSource) { + this._currentDocumentRequestCancellationTokenSource.cancel(); + this._currentDocumentRequestCancellationTokenSource = null; + } + this._setDocumentSemanticTokens(null, null, null, []); + this._isDisposed = true; + + super.dispose(); + } + + private _fetchDocumentSemanticTokensNow(): void { + if (this._currentDocumentRequestCancellationTokenSource) { + // there is already a request running, let it finish... + return; + } + + if (!hasDocumentSemanticTokensProvider(this._provider, this._model)) { + // there is no provider + if (this._currentDocumentResponse) { + // there are semantic tokens set + this._model.tokenization.setSemanticTokens(null, false); + } + return; + } + + const cancellationTokenSource = new CancellationTokenSource(); + const lastProvider = this._currentDocumentResponse ? this._currentDocumentResponse.provider : null; + const lastResultId = this._currentDocumentResponse ? this._currentDocumentResponse.resultId || null : null; + const request = getDocumentSemanticTokens(this._provider, this._model, lastProvider, lastResultId, cancellationTokenSource.token); + this._currentDocumentRequestCancellationTokenSource = cancellationTokenSource; + this._providersChangedDuringRequest = false; + + const pendingChanges: IModelContentChangedEvent[] = []; + const contentChangeListener = this._model.onDidChangeContent((e) => { + pendingChanges.push(e); + }); + + const sw = new StopWatch(false); + request.then((res) => { + this._debounceInformation.update(this._model, sw.elapsed()); + this._currentDocumentRequestCancellationTokenSource = null; + contentChangeListener.dispose(); + + if (!res) { + this._setDocumentSemanticTokens(null, null, null, pendingChanges); + } else { + const { provider, tokens } = res; + const styling = this._semanticTokensStylingService.getStyling(provider); + this._setDocumentSemanticTokens(provider, tokens || null, styling, pendingChanges); + } + }, (err) => { + const isExpectedError = err && (errors.isCancellationError(err) || (typeof err.message === 'string' && err.message.indexOf('busy') !== -1)); + if (!isExpectedError) { + errors.onUnexpectedError(err); + } + + // Semantic tokens eats up all errors and considers errors to mean that the result is temporarily not available + // The API does not have a special error kind to express this... + this._currentDocumentRequestCancellationTokenSource = null; + contentChangeListener.dispose(); + + if (pendingChanges.length > 0 || this._providersChangedDuringRequest) { + // More changes occurred while the request was running + if (!this._fetchDocumentSemanticTokens.isScheduled()) { + this._fetchDocumentSemanticTokens.schedule(this._debounceInformation.get(this._model)); + } + } + }); + } + + private static _copy(src: Uint32Array, srcOffset: number, dest: Uint32Array, destOffset: number, length: number): void { + // protect against overflows + length = Math.min(length, dest.length - destOffset, src.length - srcOffset); + for (let i = 0; i < length; i++) { + dest[destOffset + i] = src[srcOffset + i]; + } + } + + private _setDocumentSemanticTokens(provider: DocumentSemanticTokensProvider | null, tokens: SemanticTokens | SemanticTokensEdits | null, styling: SemanticTokensProviderStyling | null, pendingChanges: IModelContentChangedEvent[]): void { + const currentResponse = this._currentDocumentResponse; + const rescheduleIfNeeded = () => { + if ((pendingChanges.length > 0 || this._providersChangedDuringRequest) && !this._fetchDocumentSemanticTokens.isScheduled()) { + this._fetchDocumentSemanticTokens.schedule(this._debounceInformation.get(this._model)); + } + }; + + if (this._currentDocumentResponse) { + this._currentDocumentResponse.dispose(); + this._currentDocumentResponse = null; + } + if (this._isDisposed) { + // disposed! + if (provider && tokens) { + provider.releaseDocumentSemanticTokens(tokens.resultId); + } + return; + } + if (!provider || !styling) { + this._model.tokenization.setSemanticTokens(null, false); + return; + } + if (!tokens) { + this._model.tokenization.setSemanticTokens(null, true); + rescheduleIfNeeded(); + return; + } + + if (isSemanticTokensEdits(tokens)) { + if (!currentResponse) { + // not possible! + this._model.tokenization.setSemanticTokens(null, true); + return; + } + if (tokens.edits.length === 0) { + // nothing to do! + tokens = { + resultId: tokens.resultId, + data: currentResponse.data + }; + } else { + let deltaLength = 0; + for (const edit of tokens.edits) { + deltaLength += (edit.data ? edit.data.length : 0) - edit.deleteCount; + } + + const srcData = currentResponse.data; + const destData = new Uint32Array(srcData.length + deltaLength); + + let srcLastStart = srcData.length; + let destLastStart = destData.length; + for (let i = tokens.edits.length - 1; i >= 0; i--) { + const edit = tokens.edits[i]; + + if (edit.start > srcData.length) { + styling.warnInvalidEditStart(currentResponse.resultId, tokens.resultId, i, edit.start, srcData.length); + // The edits are invalid and there's no way to recover + this._model.tokenization.setSemanticTokens(null, true); + return; + } + + const copyCount = srcLastStart - (edit.start + edit.deleteCount); + if (copyCount > 0) { + ModelSemanticColoring._copy(srcData, srcLastStart - copyCount, destData, destLastStart - copyCount, copyCount); + destLastStart -= copyCount; + } + + if (edit.data) { + ModelSemanticColoring._copy(edit.data, 0, destData, destLastStart - edit.data.length, edit.data.length); + destLastStart -= edit.data.length; + } + + srcLastStart = edit.start; + } + + if (srcLastStart > 0) { + ModelSemanticColoring._copy(srcData, 0, destData, 0, srcLastStart); + } + + tokens = { + resultId: tokens.resultId, + data: destData + }; + } + } + + if (isSemanticTokens(tokens)) { + + this._currentDocumentResponse = new SemanticTokensResponse(provider, tokens.resultId, tokens.data); + + const result = toMultilineTokens2(tokens, styling, this._model.getLanguageId()); + + // Adjust incoming semantic tokens + if (pendingChanges.length > 0) { + // More changes occurred while the request was running + // We need to: + // 1. Adjust incoming semantic tokens + // 2. Request them again + for (const change of pendingChanges) { + for (const area of result) { + for (const singleChange of change.changes) { + area.applyEdit(singleChange.range, singleChange.text); + } + } + } + } + + this._model.tokenization.setSemanticTokens(result, true); + } else { + this._model.tokenization.setSemanticTokens(null, true); + } + + rescheduleIfNeeded(); + } +} + +class SemanticTokensResponse { + constructor( + public readonly provider: DocumentSemanticTokensProvider, + public readonly resultId: string | undefined, + public readonly data: Uint32Array + ) { } + + public dispose(): void { + this.provider.releaseDocumentSemanticTokens(this.resultId); + } +} + +registerEditorFeature(DocumentSemanticTokensFeature); diff --git a/src/vs/editor/contrib/viewportSemanticTokens/browser/viewportSemanticTokens.ts b/src/vs/editor/contrib/semanticTokens/browser/viewportSemanticTokens.ts similarity index 91% rename from src/vs/editor/contrib/viewportSemanticTokens/browser/viewportSemanticTokens.ts rename to src/vs/editor/contrib/semanticTokens/browser/viewportSemanticTokens.ts index 98842559f70..52a1f9401ac 100644 --- a/src/vs/editor/contrib/viewportSemanticTokens/browser/viewportSemanticTokens.ts +++ b/src/vs/editor/contrib/semanticTokens/browser/viewportSemanticTokens.ts @@ -10,9 +10,8 @@ import { EditorContributionInstantiation, registerEditorContribution } from 'vs/ import { Range } from 'vs/editor/common/core/range'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; -import { getDocumentRangeSemanticTokens, hasDocumentRangeSemanticTokensProvider } from 'vs/editor/common/services/getSemanticTokens'; -import { IModelService } from 'vs/editor/common/services/model'; -import { isSemanticColoringEnabled, SEMANTIC_HIGHLIGHTING_SETTING_ID } from 'vs/editor/common/services/modelService'; +import { getDocumentRangeSemanticTokens, hasDocumentRangeSemanticTokensProvider } from 'vs/editor/contrib/semanticTokens/common/getSemanticTokens'; +import { isSemanticColoringEnabled, SEMANTIC_HIGHLIGHTING_SETTING_ID } from 'vs/editor/contrib/semanticTokens/common/semanticTokensConfig'; import { toMultilineTokens2 } from 'vs/editor/common/services/semanticTokensProviderStyling'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IThemeService } from 'vs/platform/theme/common/themeService'; @@ -21,8 +20,9 @@ import { StopWatch } from 'vs/base/common/stopwatch'; import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; import { DocumentRangeSemanticTokensProvider } from 'vs/editor/common/languages'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { ISemanticTokensStylingService } from 'vs/editor/common/services/semanticTokensStyling'; -class ViewportSemanticTokensContribution extends Disposable implements IEditorContribution { +export class ViewportSemanticTokensContribution extends Disposable implements IEditorContribution { public static readonly ID = 'editor.contrib.viewportSemanticTokens'; @@ -38,7 +38,7 @@ class ViewportSemanticTokensContribution extends Disposable implements IEditorCo constructor( editor: ICodeEditor, - @IModelService private readonly _modelService: IModelService, + @ISemanticTokensStylingService private readonly _semanticTokensStylingService: ISemanticTokensStylingService, @IThemeService private readonly _themeService: IThemeService, @IConfigurationService private readonly _configurationService: IConfigurationService, @ILanguageFeatureDebounceService languageFeatureDebounceService: ILanguageFeatureDebounceService, @@ -134,7 +134,7 @@ class ViewportSemanticTokensContribution extends Disposable implements IEditorCo return; } const { provider, tokens: result } = r; - const styling = this._modelService.getSemanticTokensProviderStyling(provider); + const styling = this._semanticTokensStylingService.getStyling(provider); model.tokenization.setPartialSemanticTokens(range, toMultilineTokens2(result, styling, model.getLanguageId())); }).then(() => this._removeOutstandingRequest(request), () => this._removeOutstandingRequest(request)); return request; diff --git a/src/vs/editor/common/services/getSemanticTokens.ts b/src/vs/editor/contrib/semanticTokens/common/getSemanticTokens.ts similarity index 100% rename from src/vs/editor/common/services/getSemanticTokens.ts rename to src/vs/editor/contrib/semanticTokens/common/getSemanticTokens.ts diff --git a/src/vs/editor/contrib/semanticTokens/common/semanticTokensConfig.ts b/src/vs/editor/contrib/semanticTokens/common/semanticTokensConfig.ts new file mode 100644 index 00000000000..ebf4f3b2932 --- /dev/null +++ b/src/vs/editor/contrib/semanticTokens/common/semanticTokensConfig.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ITextModel } from 'vs/editor/common/model'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; + +export const SEMANTIC_HIGHLIGHTING_SETTING_ID = 'editor.semanticHighlighting'; + +export interface IEditorSemanticHighlightingOptions { + enabled: true | false | 'configuredByTheme'; +} + +export function isSemanticColoringEnabled(model: ITextModel, themeService: IThemeService, configurationService: IConfigurationService): boolean { + const setting = configurationService.getValue(SEMANTIC_HIGHLIGHTING_SETTING_ID, { overrideIdentifier: model.getLanguageId(), resource: model.uri })?.enabled; + if (typeof setting === 'boolean') { + return setting; + } + return themeService.getColorTheme().semanticHighlighting; +} diff --git a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts new file mode 100644 index 00000000000..9a4c4876426 --- /dev/null +++ b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts @@ -0,0 +1,278 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { Emitter, Event } from 'vs/base/common/event'; +import { Range } from 'vs/editor/common/core/range'; +import { ITextModel } from 'vs/editor/common/model'; +import { ModelService } from 'vs/editor/common/services/modelService'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { TestColorTheme, TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; +import { NullLogService } from 'vs/platform/log/common/log'; +import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService'; +import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; +import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { DocumentSemanticTokensProvider, SemanticTokens, SemanticTokensEdits, SemanticTokensLegend } from 'vs/editor/common/languages'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { Barrier, timeout } from 'vs/base/common/async'; +import { LanguageService } from 'vs/editor/common/services/languageService'; +import { ColorScheme } from 'vs/platform/theme/common/theme'; +import { IModelService } from 'vs/editor/common/services/model'; +import { ILanguageService } from 'vs/editor/common/languages/language'; +import { TestTextResourcePropertiesService } from 'vs/editor/test/common/services/testTextResourcePropertiesService'; +import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; +import { getDocumentSemanticTokens, isSemanticTokens } from 'vs/editor/contrib/semanticTokens/common/getSemanticTokens'; +import { LanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; +import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler'; +import { LanguageFeaturesService } from 'vs/editor/common/services/languageFeaturesService'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { SemanticTokensStylingService } from 'vs/editor/common/services/semanticTokensStylingService'; +import { DocumentSemanticTokensFeature } from 'vs/editor/contrib/semanticTokens/browser/documentSemanticTokens'; + +suite('ModelSemanticColoring', () => { + + const disposables = new DisposableStore(); + let modelService: IModelService; + let languageService: ILanguageService; + let languageFeaturesService: ILanguageFeaturesService; + + setup(() => { + const configService = new TestConfigurationService({ editor: { semanticHighlighting: true } }); + const themeService = new TestThemeService(); + themeService.setTheme(new TestColorTheme({}, ColorScheme.DARK, true)); + const logService = new NullLogService(); + languageFeaturesService = new LanguageFeaturesService(); + languageService = disposables.add(new LanguageService(false)); + const semanticTokensStylingService = disposables.add(new SemanticTokensStylingService(themeService, logService, languageService)); + modelService = disposables.add(new ModelService( + configService, + new TestTextResourcePropertiesService(configService), + new UndoRedoService(new TestDialogService(), new TestNotificationService()), + languageService, + new TestLanguageConfigurationService(), + )); + disposables.add(new DocumentSemanticTokensFeature(semanticTokensStylingService, modelService, themeService, configService, new LanguageFeatureDebounceService(logService), languageFeaturesService)); + }); + + teardown(() => { + disposables.clear(); + }); + + test('DocumentSemanticTokens should be fetched when the result is empty if there are pending changes', async () => { + await runWithFakedTimers({}, async () => { + + disposables.add(languageService.registerLanguage({ id: 'testMode' })); + + const inFirstCall = new Barrier(); + const delayFirstResult = new Barrier(); + const secondResultProvided = new Barrier(); + let callCount = 0; + + disposables.add(languageFeaturesService.documentSemanticTokensProvider.register('testMode', new class implements DocumentSemanticTokensProvider { + getLegend(): SemanticTokensLegend { + return { tokenTypes: ['class'], tokenModifiers: [] }; + } + async provideDocumentSemanticTokens(model: ITextModel, lastResultId: string | null, token: CancellationToken): Promise { + callCount++; + if (callCount === 1) { + assert.ok('called once'); + inFirstCall.open(); + await delayFirstResult.wait(); + await timeout(0); // wait for the simple scheduler to fire to check that we do actually get rescheduled + return null; + } + if (callCount === 2) { + assert.ok('called twice'); + secondResultProvided.open(); + return null; + } + assert.fail('Unexpected call'); + } + releaseDocumentSemanticTokens(resultId: string | undefined): void { + } + })); + + const textModel = disposables.add(modelService.createModel('Hello world', languageService.createById('testMode'))); + + // wait for the provider to be called + await inFirstCall.wait(); + + // the provider is now in the provide call + // change the text buffer while the provider is running + textModel.applyEdits([{ range: new Range(1, 1, 1, 1), text: 'x' }]); + + // let the provider finish its first result + delayFirstResult.open(); + + // we need to check that the provider is called again, even if it returns null + await secondResultProvided.wait(); + + // assert that it got called twice + assert.strictEqual(callCount, 2); + }); + }); + + test('issue #149412: VS Code hangs when bad semantic token data is received', async () => { + await runWithFakedTimers({}, async () => { + + disposables.add(languageService.registerLanguage({ id: 'testMode' })); + + let lastResult: SemanticTokens | SemanticTokensEdits | null = null; + + disposables.add(languageFeaturesService.documentSemanticTokensProvider.register('testMode', new class implements DocumentSemanticTokensProvider { + getLegend(): SemanticTokensLegend { + return { tokenTypes: ['class'], tokenModifiers: [] }; + } + async provideDocumentSemanticTokens(model: ITextModel, lastResultId: string | null, token: CancellationToken): Promise { + if (!lastResultId) { + // this is the first call + lastResult = { + resultId: '1', + data: new Uint32Array([4294967293, 0, 7, 16, 0, 1, 4, 3, 11, 1]) + }; + } else { + // this is the second call + lastResult = { + resultId: '2', + edits: [{ + start: 4294967276, + deleteCount: 0, + data: new Uint32Array([2, 0, 3, 11, 0]) + }] + }; + } + return lastResult; + } + releaseDocumentSemanticTokens(resultId: string | undefined): void { + } + })); + + const textModel = disposables.add(modelService.createModel('', languageService.createById('testMode'))); + + // wait for the semantic tokens to be fetched + await Event.toPromise(textModel.onDidChangeTokens); + assert.strictEqual(lastResult!.resultId, '1'); + + // edit the text + textModel.applyEdits([{ range: new Range(1, 1, 1, 1), text: 'foo' }]); + + // wait for the semantic tokens to be fetched again + await Event.toPromise(textModel.onDidChangeTokens); + assert.strictEqual(lastResult!.resultId, '2'); + }); + }); + + test('issue #161573: onDidChangeSemanticTokens doesn\'t consistently trigger provideDocumentSemanticTokens', async () => { + await runWithFakedTimers({}, async () => { + + disposables.add(languageService.registerLanguage({ id: 'testMode' })); + + const emitter = new Emitter(); + let requestCount = 0; + disposables.add(languageFeaturesService.documentSemanticTokensProvider.register('testMode', new class implements DocumentSemanticTokensProvider { + onDidChange = emitter.event; + getLegend(): SemanticTokensLegend { + return { tokenTypes: ['class'], tokenModifiers: [] }; + } + async provideDocumentSemanticTokens(model: ITextModel, lastResultId: string | null, token: CancellationToken): Promise { + requestCount++; + if (requestCount === 1) { + await timeout(1000); + // send a change event + emitter.fire(); + await timeout(1000); + return null; + } + return null; + } + releaseDocumentSemanticTokens(resultId: string | undefined): void { + } + })); + + disposables.add(modelService.createModel('', languageService.createById('testMode'))); + + await timeout(5000); + assert.deepStrictEqual(requestCount, 2); + }); + }); + + test('DocumentSemanticTokens should be pick the token provider with actual items', async () => { + await runWithFakedTimers({}, async () => { + + let callCount = 0; + disposables.add(languageService.registerLanguage({ id: 'testMode2' })); + disposables.add(languageFeaturesService.documentSemanticTokensProvider.register('testMode2', new class implements DocumentSemanticTokensProvider { + getLegend(): SemanticTokensLegend { + return { tokenTypes: ['class1'], tokenModifiers: [] }; + } + async provideDocumentSemanticTokens(model: ITextModel, lastResultId: string | null, token: CancellationToken): Promise { + callCount++; + // For a secondary request return a different value + if (lastResultId) { + return { + data: new Uint32Array([2, 1, 1, 1, 1, 0, 2, 1, 1, 1]) + }; + } + return { + resultId: '1', + data: new Uint32Array([0, 1, 1, 1, 1, 0, 2, 1, 1, 1]) + }; + } + releaseDocumentSemanticTokens(resultId: string | undefined): void { + } + })); + disposables.add(languageFeaturesService.documentSemanticTokensProvider.register('testMode2', new class implements DocumentSemanticTokensProvider { + getLegend(): SemanticTokensLegend { + return { tokenTypes: ['class2'], tokenModifiers: [] }; + } + async provideDocumentSemanticTokens(model: ITextModel, lastResultId: string | null, token: CancellationToken): Promise { + callCount++; + return null; + } + releaseDocumentSemanticTokens(resultId: string | undefined): void { + } + })); + + function toArr(arr: Uint32Array): number[] { + const result: number[] = []; + for (let i = 0; i < arr.length; i++) { + result[i] = arr[i]; + } + return result; + } + + const textModel = modelService.createModel('Hello world 2', languageService.createById('testMode2')); + try { + let result = await getDocumentSemanticTokens(languageFeaturesService.documentSemanticTokensProvider, textModel, null, null, CancellationToken.None); + assert.ok(result, `We should have tokens (1)`); + assert.ok(result.tokens, `Tokens are found from multiple providers (1)`); + assert.ok(isSemanticTokens(result.tokens), `Tokens are full (1)`); + assert.ok(result.tokens.resultId, `Token result id found from multiple providers (1)`); + assert.deepStrictEqual(toArr(result.tokens.data), [0, 1, 1, 1, 1, 0, 2, 1, 1, 1], `Token data returned for multiple providers (1)`); + assert.deepStrictEqual(callCount, 2, `Called both token providers (1)`); + assert.deepStrictEqual(result.provider.getLegend(), { tokenTypes: ['class1'], tokenModifiers: [] }, `Legend matches the tokens (1)`); + + // Make a second request. Make sure we get the secondary value + result = await getDocumentSemanticTokens(languageFeaturesService.documentSemanticTokensProvider, textModel, result.provider, result.tokens.resultId, CancellationToken.None); + assert.ok(result, `We should have tokens (2)`); + assert.ok(result.tokens, `Tokens are found from multiple providers (2)`); + assert.ok(isSemanticTokens(result.tokens), `Tokens are full (2)`); + assert.ok(!result.tokens.resultId, `Token result id found from multiple providers (2)`); + assert.deepStrictEqual(toArr(result.tokens.data), [2, 1, 1, 1, 1, 0, 2, 1, 1, 1], `Token data returned for multiple providers (2)`); + assert.deepStrictEqual(callCount, 4, `Called both token providers (2)`); + assert.deepStrictEqual(result.provider.getLegend(), { tokenTypes: ['class1'], tokenModifiers: [] }, `Legend matches the tokens (2)`); + } finally { + disposables.clear(); + + // Wait for scheduler to finish + await timeout(0); + + // Now dispose the text model + textModel.dispose(); + } + }); + }); +}); diff --git a/src/vs/editor/test/common/services/getSemanticTokens.test.ts b/src/vs/editor/contrib/semanticTokens/test/browser/getSemanticTokens.test.ts similarity index 94% rename from src/vs/editor/test/common/services/getSemanticTokens.test.ts rename to src/vs/editor/contrib/semanticTokens/test/browser/getSemanticTokens.test.ts index aff59d80eea..8cb75776638 100644 --- a/src/vs/editor/test/common/services/getSemanticTokens.test.ts +++ b/src/vs/editor/contrib/semanticTokens/test/browser/getSemanticTokens.test.ts @@ -9,7 +9,7 @@ import { canceled } from 'vs/base/common/errors'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ITextModel } from 'vs/editor/common/model'; import { DocumentSemanticTokensProvider, ProviderResult, SemanticTokens, SemanticTokensEdits, SemanticTokensLegend } from 'vs/editor/common/languages'; -import { getDocumentSemanticTokens } from 'vs/editor/common/services/getSemanticTokens'; +import { getDocumentSemanticTokens } from 'vs/editor/contrib/semanticTokens/common/getSemanticTokens'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; diff --git a/src/vs/editor/contrib/smartSelect/browser/smartSelect.ts b/src/vs/editor/contrib/smartSelect/browser/smartSelect.ts index 662b3dacf90..4464bb9cd54 100644 --- a/src/vs/editor/contrib/smartSelect/browser/smartSelect.ts +++ b/src/vs/editor/contrib/smartSelect/browser/smartSelect.ts @@ -51,7 +51,7 @@ class SelectionRanges { } } -class SmartSelectController implements IEditorContribution { +export class SmartSelectController implements IEditorContribution { static readonly ID = 'editor.contrib.smartSelectController'; diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css index a303d5f4945..757fc92d81d 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css @@ -23,7 +23,7 @@ } .monaco-editor.hc-black .sticky-widget, -.monaco-editor.hc-white .sticky-widget { +.monaco-editor.hc-light .sticky-widget { border-bottom: 1px solid var(--vscode-contrastBorder); } @@ -35,7 +35,7 @@ .monaco-editor .sticky-widget { width: 100%; box-shadow: var(--vscode-scrollbar-shadow) 0 3px 2px -2px; - z-index: 11; + z-index: 4; background-color: var(--vscode-editorStickyScroll-background); } diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts index 7332eb58ad5..3d5b4942690 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts @@ -3,12 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { KeyCode } from 'vs/base/common/keyCodes'; +import { EditorAction2, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; import { Categories } from 'vs/platform/action/common/actionCommonCategories'; import { Action2, MenuId } from 'vs/platform/actions/common/actions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { StickyScrollController } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollController'; export class ToggleStickyScroll extends Action2 { @@ -40,3 +45,112 @@ export class ToggleStickyScroll extends Action2 { return configurationService.updateValue('editor.stickyScroll.enabled', newValue); } } + +const weight = KeybindingWeight.EditorContrib; + +export class FocusStickyScroll extends EditorAction2 { + + constructor() { + super({ + id: 'editor.action.focusStickyScroll', + title: { + value: localize('focusStickyScroll', "Focus Sticky Scroll"), + mnemonicTitle: localize({ key: 'mifocusStickyScroll', comment: ['&& denotes a mnemonic'] }, "&&Focus Sticky Scroll"), + original: 'Focus Sticky Scroll', + }, + precondition: ContextKeyExpr.and(ContextKeyExpr.has('config.editor.stickyScroll.enabled'), EditorContextKeys.stickyScrollVisible), + menu: [ + { id: MenuId.CommandPalette }, + ] + }); + } + + runEditorCommand(_accessor: ServicesAccessor, editor: ICodeEditor) { + StickyScrollController.get(editor)?.focus(); + } +} + +export class SelectNextStickyScrollLine extends EditorAction2 { + constructor() { + super({ + id: 'editor.action.selectNextStickyScrollLine', + title: { + value: localize('selectNextStickyScrollLine.title', "Select next sticky scroll line"), + original: 'Select next sticky scroll line' + }, + precondition: EditorContextKeys.stickyScrollFocused.isEqualTo(true), + keybinding: { + weight, + primary: KeyCode.DownArrow + } + }); + } + + runEditorCommand(_accessor: ServicesAccessor, editor: ICodeEditor) { + StickyScrollController.get(editor)?.focusNext(); + } +} + +export class SelectPreviousStickyScrollLine extends EditorAction2 { + constructor() { + super({ + id: 'editor.action.selectPreviousStickyScrollLine', + title: { + value: localize('selectPreviousStickyScrollLine.title', "Select previous sticky scroll line"), + original: 'Select previous sticky scroll line' + }, + precondition: EditorContextKeys.stickyScrollFocused.isEqualTo(true), + keybinding: { + weight, + primary: KeyCode.UpArrow + } + }); + } + + runEditorCommand(_accessor: ServicesAccessor, editor: ICodeEditor) { + StickyScrollController.get(editor)?.focusPrevious(); + } +} + +export class GoToStickyScrollLine extends EditorAction2 { + constructor() { + super({ + id: 'editor.action.goToFocusedStickyScrollLine', + title: { + value: localize('goToFocusedStickyScrollLine.title', "Go to focused sticky scroll line"), + original: 'Go to focused sticky scroll line' + }, + precondition: EditorContextKeys.stickyScrollFocused.isEqualTo(true), + keybinding: { + weight, + primary: KeyCode.Enter + } + }); + } + + runEditorCommand(_accessor: ServicesAccessor, editor: ICodeEditor) { + StickyScrollController.get(editor)?.goToFocused(); + } +} + +export class SelectEditor extends EditorAction2 { + + constructor() { + super({ + id: 'editor.action.selectEditor', + title: { + value: localize('selectEditor.title', "Select Editor"), + original: 'Select Editor' + }, + precondition: EditorContextKeys.stickyScrollFocused.isEqualTo(true), + keybinding: { + weight, + primary: KeyCode.Escape + } + }); + } + + runEditorCommand(_accessor: ServicesAccessor, editor: ICodeEditor) { + StickyScrollController.get(editor)?.selectEditor(); + } +} diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollContribution.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollContribution.ts index e45781b33f8..e242c05227e 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollContribution.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollContribution.ts @@ -4,9 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import { EditorContributionInstantiation, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; -import { ToggleStickyScroll } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollActions'; +import { ToggleStickyScroll, FocusStickyScroll, SelectEditor, SelectPreviousStickyScrollLine, SelectNextStickyScrollLine, GoToStickyScrollLine } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollActions'; import { StickyScrollController } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollController'; import { registerAction2 } from 'vs/platform/actions/common/actions'; registerEditorContribution(StickyScrollController.ID, StickyScrollController, EditorContributionInstantiation.AfterFirstRender); registerAction2(ToggleStickyScroll); +registerAction2(FocusStickyScroll); +registerAction2(SelectPreviousStickyScrollLine); +registerAction2(SelectNextStickyScrollLine); +registerAction2(GoToStickyScrollLine); +registerAction2(SelectEditor); diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts index 26ff4c2c6ce..fb7adfb064a 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts @@ -3,63 +3,293 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IActiveCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { EditorOption, RenderLineNumbersType } from 'vs/editor/common/config/editorOptions'; import { StickyScrollWidget, StickyScrollWidgetState } from './stickyScrollWidget'; -import { StickyLineCandidateProvider, StickyRange } from './stickyScrollProvider'; +import { IStickyLineCandidateProvider, StickyLineCandidateProvider } from './stickyScrollProvider'; import { IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import * as dom from 'vs/base/browser/dom'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { MenuId } from 'vs/platform/actions/common/actions'; +import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; +import { ClickLinkGesture } from 'vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture'; +import { IRange, Range } from 'vs/editor/common/core/range'; +import { getDefinitionsAtPosition } from 'vs/editor/contrib/gotoSymbol/browser/goToSymbol'; +import { goToDefinitionWithLocation } from 'vs/editor/contrib/inlayHints/browser/inlayHintsLocations'; +import { IPosition, Position } from 'vs/editor/common/core/position'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; +import * as dom from 'vs/base/browser/dom'; +import { StickyRange } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollElement'; -export class StickyScrollController extends Disposable implements IEditorContribution { +interface CustomMouseEvent { + detail: string; + element: HTMLElement; +} + +export interface IStickyScrollController { + get stickyScrollCandidateProvider(): IStickyLineCandidateProvider; + get stickyScrollWidgetState(): StickyScrollWidgetState; + focus(): void; + focusNext(): void; + focusPrevious(): void; + goToFocused(): void; + findScrollWidgetState(): StickyScrollWidgetState; + dispose(): void; + selectEditor(): void; +} + +export class StickyScrollController extends Disposable implements IEditorContribution, IStickyScrollController { static readonly ID = 'store.contrib.stickyScrollController'; private readonly _stickyScrollWidget: StickyScrollWidget; - private readonly _stickyLineCandidateProvider: StickyLineCandidateProvider; + private readonly _stickyLineCandidateProvider: IStickyLineCandidateProvider; private readonly _sessionStore: DisposableStore = new DisposableStore(); private _widgetState: StickyScrollWidgetState; private _maxStickyLines: number = Number.MAX_SAFE_INTEGER; + private _stickyRangeProjectedOnEditor: IRange | undefined; + private _candidateDefinitionsLength: number = -1; + + private _stickyScrollFocusedContextKey: IContextKey; + private _stickyScrollVisibleContextKey: IContextKey; + + private _stickyElements: HTMLCollection | undefined; + private _focusDisposableStore: DisposableStore | undefined; + private _focusedStickyElementIndex: number = -1; + private _enabled = false; + private _focused = false; + private _positionRevealed = false; + private _onMouseDown = false; + constructor( private readonly _editor: ICodeEditor, @IContextMenuService private readonly _contextMenuService: IContextMenuService, - @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, - @IInstantiationService instaService: IInstantiationService, + @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService, + @IInstantiationService private readonly _instaService: IInstantiationService, + @ILanguageConfigurationService _languageConfigurationService: ILanguageConfigurationService, + @ILanguageFeatureDebounceService _languageFeatureDebounceService: ILanguageFeatureDebounceService, + @IContextKeyService private readonly _contextKeyService: IContextKeyService ) { super(); - - this._stickyScrollWidget = new StickyScrollWidget(this._editor, languageFeaturesService, instaService); - this._stickyLineCandidateProvider = new StickyLineCandidateProvider(this._editor, languageFeaturesService); - this._widgetState = new StickyScrollWidgetState([], 0); - + this._stickyScrollWidget = new StickyScrollWidget(this._editor); + this._stickyLineCandidateProvider = new StickyLineCandidateProvider(this._editor, _languageFeaturesService, _languageConfigurationService); this._register(this._stickyScrollWidget); this._register(this._stickyLineCandidateProvider); + + this._widgetState = new StickyScrollWidgetState([], 0); + this._readConfiguration(); this._register(this._editor.onDidChangeConfiguration(e => { if (e.hasChanged(EditorOption.stickyScroll)) { this._readConfiguration(); } })); - this._readConfiguration(); this._register(dom.addDisposableListener(this._stickyScrollWidget.getDomNode(), dom.EventType.CONTEXT_MENU, async (event: MouseEvent) => { this._onContextMenu(event); })); + this._stickyScrollFocusedContextKey = EditorContextKeys.stickyScrollFocused.bindTo(this._contextKeyService); + this._stickyScrollVisibleContextKey = EditorContextKeys.stickyScrollVisible.bindTo(this._contextKeyService); + const focusTracker = this._register(dom.trackFocus(this._stickyScrollWidget.getDomNode())); + this._register(focusTracker.onDidBlur(_ => { + const height = this._stickyScrollWidget.getDomNode().clientHeight; + // Suppose that the blurring is caused by scrolling, then keep the focus on the sticky scroll + // This is determined by the fact that the height of the widget has become zero and there has been no position revealing + if (this._positionRevealed === false && height === 0) { + this._focusedStickyElementIndex = -1; + this.focus(); + + } + // In all other casees, dispose the focus on the sticky scroll + else { + this._disposeFocusStickyScrollStore(); + } + })); + this._register(focusTracker.onDidFocus(_ => { + this.focus(); + })); + this._register(this._createClickLinkGesture()); + // Suppose that mouse down on the sticky scroll, then do not focus on the sticky scroll because this will be followed by the revealing of a position + this._register(dom.addDisposableListener(this._stickyScrollWidget.getDomNode(), dom.EventType.MOUSE_DOWN, (e) => { + this._onMouseDown = true; + })); } - get stickyScrollCandidateProvider() { + get stickyScrollCandidateProvider(): IStickyLineCandidateProvider { return this._stickyLineCandidateProvider; } - get stickyScrollWidgetState() { + get stickyScrollWidgetState(): StickyScrollWidgetState { return this._widgetState; } + public static get(editor: ICodeEditor): IStickyScrollController | null { + return editor.getContribution(StickyScrollController.ID); + } + + private _disposeFocusStickyScrollStore() { + this._stickyScrollFocusedContextKey.set(false); + this._focusDisposableStore?.dispose(); + this._focused = false; + this._positionRevealed = false; + this._onMouseDown = false; + } + + public focus(): void { + // If the mouse is down, do not focus on the sticky scroll + if (this._onMouseDown) { + this._onMouseDown = false; + this._editor.focus(); + return; + } + const focusState = this._stickyScrollFocusedContextKey.get(); + if (focusState === true) { + return; + } + this._focused = true; + this._focusDisposableStore = new DisposableStore(); + this._stickyScrollFocusedContextKey.set(true); + const rootNode = this._stickyScrollWidget.getDomNode(); + (rootNode.lastElementChild! as HTMLDivElement).focus(); + this._stickyElements = rootNode.children; + this._focusedStickyElementIndex = this._stickyScrollWidget.lineNumbers.length - 1; + } + + public focusNext(): void { + if (this._focusedStickyElementIndex < this._stickyElements!.length - 1) { + this._focusNav(true); + } + } + + public focusPrevious(): void { + if (this._focusedStickyElementIndex > 0) { + this._focusNav(false); + } + } + + public selectEditor(): void { + this._editor.focus(); + } + + // True is next, false is previous + private _focusNav(direction: boolean): void { + this._focusedStickyElementIndex = direction ? this._focusedStickyElementIndex + 1 : this._focusedStickyElementIndex - 1; + (this._stickyElements!.item(this._focusedStickyElementIndex) as HTMLDivElement).focus(); + } + + public goToFocused(): void { + const lineNumbers = this._stickyScrollWidget.lineNumbers; + this._disposeFocusStickyScrollStore(); + this._revealPosition({ lineNumber: lineNumbers[this._focusedStickyElementIndex], column: 1 }); + } + + private _revealPosition(position: IPosition): void { + this._positionRevealed = true; + this._editor.revealPosition(position); + this._editor.setSelection(Range.fromPositions(position)); + this._editor.focus(); + } + + private _createClickLinkGesture(): IDisposable { + + const linkGestureStore = new DisposableStore(); + const sessionStore = new DisposableStore(); + linkGestureStore.add(sessionStore); + const gesture = new ClickLinkGesture(this._editor, true); + linkGestureStore.add(gesture); + + linkGestureStore.add(gesture.onMouseMoveOrRelevantKeyDown(([mouseEvent, _keyboardEvent]) => { + if (!this._editor.hasModel() || !mouseEvent.hasTriggerModifier) { + sessionStore.clear(); + return; + } + const targetMouseEvent = mouseEvent.target as unknown as CustomMouseEvent; + if (targetMouseEvent.detail === this._stickyScrollWidget.getId() + && targetMouseEvent.element.innerText === targetMouseEvent.element.innerHTML) { + + const text = targetMouseEvent.element.innerText; + if (this._stickyScrollWidget.hoverOnColumn === -1) { + return; + } + const lineNumber = this._stickyScrollWidget.hoverOnLine; + const column = this._stickyScrollWidget.hoverOnColumn; + + const stickyPositionProjectedOnEditor = new Range(lineNumber, column, lineNumber, column + text.length); + if (!stickyPositionProjectedOnEditor.equalsRange(this._stickyRangeProjectedOnEditor)) { + this._stickyRangeProjectedOnEditor = stickyPositionProjectedOnEditor; + sessionStore.clear(); + } else if (targetMouseEvent.element.style.textDecoration === 'underline') { + return; + } + + const cancellationToken = new CancellationTokenSource(); + sessionStore.add(toDisposable(() => cancellationToken.dispose(true))); + + let currentHTMLChild: HTMLElement; + + getDefinitionsAtPosition(this._languageFeaturesService.definitionProvider, this._editor.getModel(), new Position(lineNumber, column + 1), cancellationToken.token).then((candidateDefinitions => { + if (cancellationToken.token.isCancellationRequested) { + return; + } + if (candidateDefinitions.length !== 0) { + this._candidateDefinitionsLength = candidateDefinitions.length; + const childHTML: HTMLElement = targetMouseEvent.element; + if (currentHTMLChild !== childHTML) { + sessionStore.clear(); + currentHTMLChild = childHTML; + currentHTMLChild.style.textDecoration = 'underline'; + sessionStore.add(toDisposable(() => { + currentHTMLChild.style.textDecoration = 'none'; + })); + } else if (!currentHTMLChild) { + currentHTMLChild = childHTML; + currentHTMLChild.style.textDecoration = 'underline'; + sessionStore.add(toDisposable(() => { + currentHTMLChild.style.textDecoration = 'none'; + })); + } + } else { + sessionStore.clear(); + } + })); + } else { + sessionStore.clear(); + } + })); + linkGestureStore.add(gesture.onCancel(() => { + sessionStore.clear(); + })); + linkGestureStore.add(gesture.onExecute(async e => { + if ((e.target as unknown as CustomMouseEvent).detail !== this._stickyScrollWidget.getId()) { + return; + } + if (e.hasTriggerModifier) { + // Control click + if (this._candidateDefinitionsLength > 1) { + if (this._focused) { + this._disposeFocusStickyScrollStore(); + } + this._revealPosition({ lineNumber: this._stickyScrollWidget.hoverOnLine, column: 1 }); + } + this._instaService.invokeFunction(goToDefinitionWithLocation, e, this._editor as IActiveCodeEditor, { uri: this._editor.getModel()!.uri, range: this._stickyRangeProjectedOnEditor! }); + + } else if (!e.isRightClick) { + // Normal click + if (this._focused) { + this._disposeFocusStickyScrollStore(); + } + this._revealPosition({ lineNumber: this._stickyScrollWidget.hoverOnLine, column: this._stickyScrollWidget.hoverOnColumn }); + } + })); + return linkGestureStore; + } + private _onContextMenu(event: MouseEvent) { this._contextMenuService.showContextMenu({ menuId: MenuId.StickyScrollContext, @@ -69,20 +299,25 @@ 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(); + this._enabled = false; return; - } else { + } else if (options.enabled && !this._enabled) { + // When sticky scroll was just enabled, add the listeners on the sticky scroll this._editor.addOverlayWidget(this._stickyScrollWidget); this._sessionStore.add(this._editor.onDidScrollChange(() => this._renderStickyScroll())); this._sessionStore.add(this._editor.onDidLayoutChange(() => this._onDidResize())); this._sessionStore.add(this._editor.onDidChangeModelTokens((e) => this._onTokensChange(e))); this._sessionStore.add(this._stickyLineCandidateProvider.onDidChangeStickyScroll(() => this._renderStickyScroll())); - const lineNumberOption = this._editor.getOption(EditorOption.lineNumbers); - if (lineNumberOption.renderType === RenderLineNumbersType.Relative) { - this._sessionStore.add(this._editor.onDidChangeCursorPosition(() => this._renderStickyScroll())); - } + this._enabled = true; + } + + const lineNumberOption = this._editor.getOption(EditorOption.lineNumbers); + if (lineNumberOption.renderType === RenderLineNumbersType.Relative) { + this._sessionStore.add(this._editor.onDidChangeCursorPosition(() => this._renderStickyScroll())); } } @@ -108,8 +343,7 @@ export class StickyScrollController extends Disposable implements IEditorContrib const layoutInfo = this._editor.getLayoutInfo(); const width = layoutInfo.width - layoutInfo.minimap.minimapCanvasOuterWidth - layoutInfo.verticalScrollbarWidth; this._stickyScrollWidget.getDomNode().style.width = `${width}px`; - - // make sure sticky scroll doesn't take up more than 25% of the editor + // Make sure sticky scroll doesn't take up more than 25% of the editor const theoreticalLines = layoutInfo.height / this._editor.getOption(EditorOption.lineHeight); this._maxStickyLines = Math.round(theoreticalLines * .25); } @@ -121,12 +355,42 @@ export class StickyScrollController extends Disposable implements IEditorContrib const model = this._editor.getModel(); const stickyLineVersion = this._stickyLineCandidateProvider.getVersionId(); if (stickyLineVersion === undefined || stickyLineVersion === model.getVersionId()) { - this._widgetState = this.getScrollWidgetState(); - this._stickyScrollWidget.setState(this._widgetState); + this._widgetState = this.findScrollWidgetState(); + this._stickyScrollVisibleContextKey.set(!(this._widgetState.lineNumbers.length === 0)); + + if (!this._focused) { + this._stickyScrollWidget.setState(this._widgetState); + } else { + this._stickyElements = this._stickyScrollWidget.getDomNode().children; + // Suppose that previously the sticky scroll widget had height 0, then if there are visible lines, set the last line as focused + if (this._focusedStickyElementIndex === -1) { + this._stickyScrollWidget.setState(this._widgetState); + this._focusedStickyElementIndex = this._stickyElements.length - 1; + if (this._focusedStickyElementIndex !== -1) { + (this._stickyElements.item(this._focusedStickyElementIndex) as HTMLDivElement).focus(); + } + } else { + const focusedStickyElementLineNumber = this._stickyScrollWidget.lineNumbers[this._focusedStickyElementIndex]; + this._stickyScrollWidget.setState(this._widgetState); + // Suppose that after setting the state, there are no sticky lines, set the focused index to -1 + if (this._stickyElements.length === 0) { + this._focusedStickyElementIndex = -1; + } else { + const previousFocusedLineNumberExists = this._stickyScrollWidget.lineNumbers.includes(focusedStickyElementLineNumber); + + // If the line number is still there, do not change anything + // If the line number is not there, set the new focused line to be the last line + if (!previousFocusedLineNumberExists) { + this._focusedStickyElementIndex = this._stickyElements.length - 1; + } + (this._stickyElements.item(this._focusedStickyElementIndex) as HTMLDivElement).focus(); + } + } + } } } - getScrollWidgetState(): StickyScrollWidgetState { + findScrollWidgetState(): StickyScrollWidgetState { const lineHeight: number = this._editor.getOption(EditorOption.lineHeight); const maxNumberStickyLines = Math.min(this._maxStickyLines, this._editor.getOption(EditorOption.stickyScroll).maxLineCount); const scrollTop: number = this._editor.getScrollTop(); diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollElement.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollElement.ts new file mode 100644 index 00000000000..1bbf4f5e5bf --- /dev/null +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollElement.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 { URI } from 'vs/base/common/uri'; + +export class StickyRange { + constructor( + public readonly startLineNumber: number, + public readonly endLineNumber: number + ) { } +} + +export class StickyElement { + + constructor( + /** + * Range of line numbers spanned by the current scope + */ + public readonly range: StickyRange | undefined, + /** + * Must be sorted by start line number + */ + public readonly children: StickyElement[], + /** + * Parent sticky outline element + */ + public readonly parent: StickyElement | undefined + ) { + } +} + +export class StickyModel { + constructor( + readonly uri: URI, + readonly version: number, + readonly element: StickyElement | undefined, + readonly outlineProviderId: string | undefined + ) { } +} diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts new file mode 100644 index 00000000000..17398d89874 --- /dev/null +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts @@ -0,0 +1,424 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { OutlineElement, OutlineGroup, OutlineModel } from 'vs/editor/contrib/documentSymbols/browser/outlineModel'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { CancelablePromise, createCancelablePromise, Delayer } from 'vs/base/common/async'; +import { FoldingController, RangesLimitReporter } from 'vs/editor/contrib/folding/browser/folding'; +import { ITextModel } from 'vs/editor/common/model'; +import { SyntaxRangeProvider } from 'vs/editor/contrib/folding/browser/syntaxRangeProvider'; +import { IndentRangeProvider } from 'vs/editor/contrib/folding/browser/indentRangeProvider'; +import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { FoldingRegions } from 'vs/editor/contrib/folding/browser/foldingRanges'; +import { onUnexpectedError } from 'vs/base/common/errors'; +import { TextModel } from 'vs/editor/common/model/textModel'; +import { StickyElement, StickyModel, StickyRange } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollElement'; +import { Iterable } from 'vs/base/common/iterator'; +import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; + +enum ModelProvider { + OUTLINE_MODEL = 'outlineModel', + FOLDING_PROVIDER_MODEL = 'foldingProviderModel', + INDENTATION_MODEL = 'indentationModel' +} + +enum Status { + VALID, + INVALID, + CANCELED +} + +export interface IStickyModelProvider { + + /** + * Method which updates the sticky model + * @param textModel text-model of the editor + * @param textModelVersionId text-model version ID + * @param token cancellation token + * @returns the sticky model + */ + update(textModel: ITextModel, textModelVersionId: number, token: CancellationToken): Promise; +} + +export class StickyModelProvider implements IStickyModelProvider { + + private _modelProviders: IStickyModelCandidateProvider[] = []; + private _modelPromise: CancelablePromise | null = null; + private _updateScheduler: Delayer = new Delayer(300); + private readonly _store: DisposableStore; + + constructor( + private readonly _editor: ICodeEditor, + @ILanguageConfigurationService readonly _languageConfigurationService: ILanguageConfigurationService, + @ILanguageFeaturesService readonly _languageFeaturesService: ILanguageFeaturesService, + defaultModel: string) { + + const stickyModelFromCandidateOutlineProvider = new StickyModelFromCandidateOutlineProvider(_languageFeaturesService); + const stickyModelFromSyntaxFoldingProvider = new StickyModelFromCandidateSyntaxFoldingProvider(this._editor, _languageFeaturesService); + const stickyModelFromIndentationFoldingProvider = new StickyModelFromCandidateIndentationFoldingProvider(this._editor, _languageConfigurationService); + + switch (defaultModel) { + case ModelProvider.OUTLINE_MODEL: + this._modelProviders.push(stickyModelFromCandidateOutlineProvider); + this._modelProviders.push(stickyModelFromSyntaxFoldingProvider); + this._modelProviders.push(stickyModelFromIndentationFoldingProvider); + break; + case ModelProvider.FOLDING_PROVIDER_MODEL: + this._modelProviders.push(stickyModelFromSyntaxFoldingProvider); + this._modelProviders.push(stickyModelFromIndentationFoldingProvider); + break; + case ModelProvider.INDENTATION_MODEL: + this._modelProviders.push(stickyModelFromIndentationFoldingProvider); + break; + } + + this._store = new DisposableStore(); + } + + private _cancelModelPromise(): void { + if (this._modelPromise) { + this._modelPromise.cancel(); + this._modelPromise = null; + } + } + + public async update(textModel: ITextModel, textModelVersionId: number, token: CancellationToken): Promise { + + this._store.clear(); + this._store.add({ + dispose: () => { + this._cancelModelPromise(); + this._updateScheduler?.cancel(); + } + }); + this._cancelModelPromise(); + + return await this._updateScheduler.trigger(async () => { + + for (const modelProvider of this._modelProviders) { + const { statusPromise, modelPromise } = modelProvider.computeStickyModel( + textModel, + textModelVersionId, + token + ); + this._modelPromise = modelPromise; + const status = await statusPromise; + if (this._modelPromise !== modelPromise) { + return null; + } + switch (status) { + case Status.CANCELED: + this._store.clear(); + return null; + case Status.VALID: + return modelProvider.stickyModel; + } + } + return null; + }); + } +} + +interface IStickyModelCandidateProvider { + get stickyModel(): StickyModel | null; + + get provider(): LanguageFeatureRegistry | null; + + /** + * Method which computes the sticky model and returns a status to signal whether the sticky model has been successfully found + * @param textmodel text-model of the editor + * @param modelVersionId version ID of the text-model + * @param token cancellation token + * @returns a promise of a status indicating whether the sticky model has been successfully found as well as the model promise + */ + computeStickyModel(textmodel: ITextModel, modelVersionId: number, token: CancellationToken): { statusPromise: Promise | Status; modelPromise: CancelablePromise | null }; +} + +abstract class StickyModelCandidateProvider implements IStickyModelCandidateProvider { + + protected _stickyModel: StickyModel | null = null; + + constructor() { } + + get stickyModel(): StickyModel | null { + return this._stickyModel; + } + + private _invalid(): Status { + this._stickyModel = null; + return Status.INVALID; + } + + public abstract get provider(): LanguageFeatureRegistry | null; + + public computeStickyModel(textModel: ITextModel, modelVersionId: number, token: CancellationToken): { statusPromise: Promise | Status; modelPromise: CancelablePromise | null } { + if (!this.isProviderValid(textModel)) { + return { statusPromise: this._invalid(), modelPromise: null }; + } + const providerModelPromise = createCancelablePromise(token => this.createModelFromProvider(textModel, modelVersionId, token)); + + return { + statusPromise: providerModelPromise.then(providerModel => { + if (!this.isModelValid(providerModel)) { + return this._invalid(); + + } + if (token.isCancellationRequested) { + return Status.CANCELED; + } + this._stickyModel = this.createStickyModel(textModel, modelVersionId, token, providerModel); + return Status.VALID; + }).then(undefined, (err) => { + onUnexpectedError(err); + return Status.CANCELED; + }), + modelPromise: providerModelPromise + }; + } + + /** + * Method which checks whether the model returned by the provider is valid and can be used to compute a sticky model. + * This method by default returns true. + * @param model model returned by the provider + * @returns boolean indicating whether the model is valid + */ + protected isModelValid(model: any): boolean { + return true; + } + + /** + * Method which checks whether the provider is valid before applying it to find the provider model. + * This method by default returns true. + * @param textModel text-model of the editor + * @returns boolean indicating whether the provider is valid + */ + protected isProviderValid(textModel: ITextModel): boolean { + return true; + } + + /** + * Abstract method which creates the model from the provider and returns the provider model + * @param textModel text-model of the editor + * @param textModelVersionId text-model version ID + * @param token cancellation token + * @returns the model returned by the provider + */ + protected abstract createModelFromProvider(textModel: ITextModel, textModelVersionId: number, token: CancellationToken): Promise; + + /** + * Abstract method which computes the sticky model from the model returned by the provider and returns the sticky model + * @param textModel text-model of the editor + * @param textModelVersionId text-model version ID + * @param token cancellation token + * @param model model returned by the provider + * @returns the sticky model + */ + protected abstract createStickyModel(textModel: ITextModel, textModelVersionId: number, token: CancellationToken, model: T): StickyModel; +} + +class StickyModelFromCandidateOutlineProvider extends StickyModelCandidateProvider { + + constructor(@ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService) { + super(); + } + + public get provider(): LanguageFeatureRegistry | null { + return this._languageFeaturesService.documentSymbolProvider; + } + + protected createModelFromProvider(textModel: ITextModel, modelVersionId: number, token: CancellationToken): Promise { + return OutlineModel.create(this._languageFeaturesService.documentSymbolProvider, textModel, token); + } + + protected createStickyModel(textModel: TextModel, modelVersionId: number, token: CancellationToken, model: OutlineModel): StickyModel { + const { stickyOutlineElement, providerID } = this._stickyModelFromOutlineModel(model, this._stickyModel?.outlineProviderId); + return new StickyModel(textModel.uri, modelVersionId, stickyOutlineElement, providerID); + } + + protected override isModelValid(model: OutlineModel): boolean { + return model && model.children.size > 0; + } + + private _stickyModelFromOutlineModel(outlineModel: OutlineModel, preferredProvider: string | undefined): { stickyOutlineElement: StickyElement; providerID: string | undefined } { + + let outlineElements: Map; + // When several possible outline providers + if (Iterable.first(outlineModel.children.values()) instanceof OutlineGroup) { + const provider = Iterable.find(outlineModel.children.values(), outlineGroupOfModel => outlineGroupOfModel.id === preferredProvider); + if (provider) { + outlineElements = provider.children; + } else { + let tempID = ''; + let maxTotalSumOfRanges = -1; + let optimalOutlineGroup = undefined; + for (const [_key, outlineGroup] of outlineModel.children.entries()) { + const totalSumRanges = this._findSumOfRangesOfGroup(outlineGroup); + if (totalSumRanges > maxTotalSumOfRanges) { + optimalOutlineGroup = outlineGroup; + maxTotalSumOfRanges = totalSumRanges; + tempID = outlineGroup.id; + } + } + preferredProvider = tempID; + outlineElements = optimalOutlineGroup!.children; + } + } else { + outlineElements = outlineModel.children as Map; + } + const stickyChildren: StickyElement[] = []; + const outlineElementsArray = Array.from(outlineElements.values()).sort((element1, element2) => { + const range1: StickyRange = new StickyRange(element1.symbol.range.startLineNumber, element1.symbol.range.endLineNumber); + const range2: StickyRange = new StickyRange(element2.symbol.range.startLineNumber, element2.symbol.range.endLineNumber); + return this._comparator(range1, range2); + }); + for (const outlineElement of outlineElementsArray) { + stickyChildren.push(this._stickyModelFromOutlineElement(outlineElement, outlineElement.symbol.selectionRange.startLineNumber)); + } + const stickyOutlineElement = new StickyElement(undefined, stickyChildren, undefined); + + return { + stickyOutlineElement: stickyOutlineElement, + providerID: preferredProvider + }; + } + + private _stickyModelFromOutlineElement(outlineElement: OutlineElement, previousStartLine: number): StickyElement { + const children: StickyElement[] = []; + for (const child of outlineElement.children.values()) { + if (child.symbol.selectionRange.startLineNumber !== child.symbol.range.endLineNumber) { + if (child.symbol.selectionRange.startLineNumber !== previousStartLine) { + children.push(this._stickyModelFromOutlineElement(child, child.symbol.selectionRange.startLineNumber)); + } else { + for (const subchild of child.children.values()) { + children.push(this._stickyModelFromOutlineElement(subchild, child.symbol.selectionRange.startLineNumber)); + } + } + } + } + children.sort((child1, child2) => this._comparator(child1.range!, child2.range!)); + const range = new StickyRange(outlineElement.symbol.selectionRange.startLineNumber, outlineElement.symbol.range.endLineNumber); + return new StickyElement(range, children, undefined); + } + + private _comparator(range1: StickyRange, range2: StickyRange): number { + if (range1.startLineNumber !== range2.startLineNumber) { + return range1.startLineNumber - range2.startLineNumber; + } else { + return range2.endLineNumber - range1.endLineNumber; + } + } + + private _findSumOfRangesOfGroup(outline: OutlineGroup | OutlineElement): number { + let res = 0; + for (const child of outline.children.values()) { + res += this._findSumOfRangesOfGroup(child); + } + if (outline instanceof OutlineElement) { + return res + outline.symbol.range.endLineNumber - outline.symbol.selectionRange.startLineNumber; + } else { + return res; + } + } + +} + +abstract class StickyModelFromCandidateFoldingProvider extends StickyModelCandidateProvider { + + protected _foldingLimitReporter: RangesLimitReporter; + + constructor(editor: ICodeEditor) { + super(); + this._foldingLimitReporter = new RangesLimitReporter(editor); + } + + protected createStickyModel(textModel: ITextModel, modelVersionId: number, token: CancellationToken, model: FoldingRegions): StickyModel { + const foldingElement = this._fromFoldingRegions(model); + return new StickyModel(textModel.uri, modelVersionId, foldingElement, undefined); + } + + protected override isModelValid(model: FoldingRegions): boolean { + return model !== null; + } + + + private _fromFoldingRegions(foldingRegions: FoldingRegions): StickyElement { + const length = foldingRegions.length; + const orderedStickyElements: StickyElement[] = []; + + // The root sticky outline element + const stickyOutlineElement = new StickyElement( + undefined, + [], + undefined + ); + + for (let i = 0; i < length; i++) { + // Finding the parent index of the current range + const parentIndex = foldingRegions.getParentIndex(i); + + let parentNode; + if (parentIndex !== -1) { + // Access the reference of the parent node + parentNode = orderedStickyElements[parentIndex]; + } else { + // In that case the parent node is the root node + parentNode = stickyOutlineElement; + } + + const child = new StickyElement( + new StickyRange(foldingRegions.getStartLineNumber(i), foldingRegions.getEndLineNumber(i) + 1), + [], + parentNode + ); + parentNode.children.push(child); + orderedStickyElements.push(child); + } + return stickyOutlineElement; + } +} + +class StickyModelFromCandidateIndentationFoldingProvider extends StickyModelFromCandidateFoldingProvider { + + constructor( + editor: ICodeEditor, + @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService) { + super(editor); + } + + public get provider(): LanguageFeatureRegistry | null { + return null; + } + + protected createModelFromProvider(textModel: TextModel, modelVersionId: number, token: CancellationToken): Promise { + const provider = new IndentRangeProvider(textModel, this._languageConfigurationService, this._foldingLimitReporter); + return provider.compute(token); + } +} + +class StickyModelFromCandidateSyntaxFoldingProvider extends StickyModelFromCandidateFoldingProvider { + + constructor(editor: ICodeEditor, + @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService) { + super(editor); + } + + public get provider(): LanguageFeatureRegistry | null { + return this._languageFeaturesService.foldingRangeProvider; + } + + protected override isProviderValid(textModel: TextModel): boolean { + const selectedProviders = FoldingController.getFoldingRangeProviders(this._languageFeaturesService, textModel); + return selectedProviders.length > 0; + } + + protected createModelFromProvider(textModel: TextModel, modelVersionId: number, token: CancellationToken): Promise { + const selectedProviders = FoldingController.getFoldingRangeProviders(this._languageFeaturesService, textModel); + const provider = new SyntaxRangeProvider(textModel, selectedProviders, () => this.createModelFromProvider(textModel, modelVersionId, token), this._foldingLimitReporter, undefined); + return provider.compute(token); + } +} diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts index 5043d92b662..391ddd6c978 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts @@ -6,25 +6,16 @@ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { OutlineModel, OutlineElement, OutlineGroup } from 'vs/editor/contrib/documentSymbols/browser/outlineModel'; import { CancellationToken, CancellationTokenSource, } from 'vs/base/common/cancellation'; -import { EditorOption } from 'vs/editor/common/config/editorOptions'; +import { EditorOption, IEditorStickyScrollOptions } from 'vs/editor/common/config/editorOptions'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Range } from 'vs/editor/common/core/range'; -import { Emitter } from 'vs/base/common/event'; import { binarySearch } from 'vs/base/common/arrays'; -import { Iterable } from 'vs/base/common/iterator'; -import { FoldingController } from 'vs/editor/contrib/folding/browser/folding'; -import { FoldingModel } from 'vs/editor/contrib/folding/browser/foldingModel'; -import { URI } from 'vs/base/common/uri'; import { isEqual } from 'vs/base/common/resources'; - -export class StickyRange { - constructor( - public readonly startLineNumber: number, - public readonly endLineNumber: number - ) { } -} +import { Event, Emitter } from 'vs/base/common/event'; +import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { StickyModelProvider, IStickyModelProvider } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider'; +import { StickyElement, StickyModel, StickyRange } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollElement'; export class StickyLineCandidate { constructor( @@ -34,7 +25,17 @@ export class StickyLineCandidate { ) { } } -export class StickyLineCandidateProvider extends Disposable { +export interface IStickyLineCandidateProvider { + + dispose(): void; + getVersionId(): number | undefined; + update(): Promise; + getCandidateStickyLinesIntersecting(range: StickyRange): StickyLineCandidate[]; + onDidChangeStickyScroll: Event; + +} + +export class StickyLineCandidateProvider extends Disposable implements IStickyLineCandidateProvider { static readonly ID = 'store.contrib.stickyScrollController'; @@ -42,22 +43,24 @@ export class StickyLineCandidateProvider extends Disposable { public readonly onDidChangeStickyScroll = this._onDidChangeStickyScroll.event; private readonly _editor: ICodeEditor; - private readonly _languageFeaturesService: ILanguageFeaturesService; private readonly _updateSoon: RunOnceScheduler; + private readonly _sessionStore: DisposableStore; - private readonly _sessionStore: DisposableStore = new DisposableStore(); - private _cts: CancellationTokenSource | undefined; - - private _model: StickyOutlineModel | undefined; + private _options: Readonly> | null = null; + private _model: StickyModel | null = null; + private _cts: CancellationTokenSource | null = null; + private _stickyModelProvider: IStickyModelProvider | null = null; constructor( editor: ICodeEditor, - @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, + @ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService, + @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService, ) { super(); this._editor = editor; - this._languageFeaturesService = languageFeaturesService; + this._sessionStore = new DisposableStore(); this._updateSoon = this._register(new RunOnceScheduler(() => this.update(), 50)); + this._register(this._editor.onDidChangeConfiguration(e => { if (e.hasChanged(EditorOption.stickyScroll)) { this.readConfiguration(); @@ -72,74 +75,58 @@ export class StickyLineCandidateProvider extends Disposable { } private readConfiguration() { - const options = this._editor.getOption(EditorOption.stickyScroll); - if (options.enabled === false) { + + this._options = this._editor.getOption(EditorOption.stickyScroll); + if (!this._options.enabled) { this._sessionStore.clear(); return; - } else { - this._sessionStore.add(this._editor.onDidChangeModel(() => { - this.update(); - })); - this._sessionStore.add(this._editor.onDidChangeHiddenAreas(() => this.update())); - this._sessionStore.add(this._editor.onDidChangeModelContent(() => this._updateSoon.schedule())); - this._sessionStore.add(this._languageFeaturesService.documentSymbolProvider.onDidChange(() => { - - this.update(); - })); - this.update(); } + + this._stickyModelProvider = new StickyModelProvider( + this._editor, + this._languageConfigurationService, + this._languageFeaturesService, + this._options.defaultModel + ); + + this._sessionStore.add(this._editor.onDidChangeModel(() => this.update())); + this._sessionStore.add(this._editor.onDidChangeHiddenAreas(() => this.update())); + this._sessionStore.add(this._editor.onDidChangeModelContent(() => this._updateSoon.schedule())); + this._sessionStore.add(this._languageFeaturesService.documentSymbolProvider.onDidChange(() => this.update())); + this.update(); } - public getVersionId() { + public getVersionId(): number | undefined { return this._model?.version; } public async update(): Promise { this._cts?.dispose(true); this._cts = new CancellationTokenSource(); - await this.updateOutlineModel(this._cts.token); + await this.updateStickyModel(this._cts.token); this._onDidChangeStickyScroll.fire(); } - private async updateOutlineModel(token: CancellationToken): Promise { - if (!this._editor.hasModel()) { + private async updateStickyModel(token: CancellationToken): Promise { + + if (!this._editor.hasModel() || !this._stickyModelProvider) { return; } - const model = this._editor.getModel(); - const modelVersionId = model.getVersionId(); - const isDifferentModel = this._model ? !isEqual(this._model.uri, model.uri) : false; + const textModel = this._editor.getModel(); + const modelVersionId = textModel.getVersionId(); + const isDifferentModel = this._model ? !isEqual(this._model.uri, textModel.uri) : false; - // clear sticky scroll to not show stale data for too long + // Clear sticky scroll to not show stale data for too long const resetHandle = isDifferentModel ? setTimeout(() => { if (!token.isCancellationRequested) { - this._model = new StickyOutlineModel(model.uri, model.getVersionId(), undefined, undefined); + this._model = new StickyModel(textModel.uri, textModel.getVersionId(), undefined, undefined); this._onDidChangeStickyScroll.fire(); } }, 75) : undefined; - // get elements from outline or folding model - const outlineModel = await OutlineModel.create(this._languageFeaturesService.documentSymbolProvider, model, token); - if (token.isCancellationRequested) { - return; - } - if (outlineModel.children.size !== 0) { - const { stickyOutlineElement, providerID } = StickyOutlineElement.fromOutlineModel(outlineModel, this._model?.outlineProviderId); - this._model = new StickyOutlineModel(model.uri, modelVersionId, stickyOutlineElement, providerID); + this._model = await this._stickyModelProvider.update(textModel, modelVersionId, token); - } else { - const foldingController = FoldingController.get(this._editor); - const foldingModel = await foldingController?.getFoldingModel(); - if (token.isCancellationRequested) { - return; - } - if (foldingModel && foldingModel.regions.length !== 0) { - const foldingElement = StickyOutlineElement.fromFoldingModel(foldingModel); - this._model = new StickyOutlineModel(model.uri, modelVersionId, foldingElement, undefined); - } else { - this._model = undefined; - } - } clearTimeout(resetHandle); } @@ -152,12 +139,19 @@ export class StickyLineCandidateProvider extends Disposable { return index; } - public getCandidateStickyLinesIntersectingFromOutline(range: StickyRange, outlineModel: StickyOutlineElement, result: StickyLineCandidate[], depth: number, lastStartLineNumber: number): void { + public getCandidateStickyLinesIntersectingFromStickyModel( + range: StickyRange, + outlineModel: StickyElement, + result: StickyLineCandidate[], + depth: number, + lastStartLineNumber: number + ): void { if (outlineModel.children.length === 0) { return; } let lastLine = lastStartLineNumber; const childrenStartLines: number[] = []; + for (let i = 0; i < outlineModel.children.length; i++) { const child = outlineModel.children[i]; if (child.range) { @@ -166,6 +160,7 @@ export class StickyLineCandidateProvider extends Disposable { } const lowerBound = this.updateIndex(binarySearch(childrenStartLines, range.startLineNumber, (a: number, b: number) => { return a - b; })); const upperBound = this.updateIndex(binarySearch(childrenStartLines, range.startLineNumber + depth, (a: number, b: number) => { return a - b; })); + for (let i = lowerBound; i <= upperBound; i++) { const child = outlineModel.children[i]; if (!child) { @@ -177,10 +172,10 @@ export class StickyLineCandidateProvider extends Disposable { if (range.startLineNumber <= childEndLine + 1 && childStartLine - 1 <= range.endLineNumber && childStartLine !== lastLine) { lastLine = childStartLine; result.push(new StickyLineCandidate(childStartLine, childEndLine - 1, depth + 1)); - this.getCandidateStickyLinesIntersectingFromOutline(range, child, result, depth + 1, childStartLine); + this.getCandidateStickyLinesIntersectingFromStickyModel(range, child, result, depth + 1, childStartLine); } } else { - this.getCandidateStickyLinesIntersectingFromOutline(range, child, result, depth, lastStartLineNumber); + this.getCandidateStickyLinesIntersectingFromStickyModel(range, child, result, depth, lastStartLineNumber); } } } @@ -190,8 +185,9 @@ export class StickyLineCandidateProvider extends Disposable { return []; } let stickyLineCandidates: StickyLineCandidate[] = []; - this.getCandidateStickyLinesIntersectingFromOutline(range, this._model.element, stickyLineCandidates, 0, -1); + this.getCandidateStickyLinesIntersectingFromStickyModel(range, this._model.element, stickyLineCandidates, 0, -1); const hiddenRanges: Range[] | undefined = this._editor._getViewModel()?.getHiddenAreas(); + if (hiddenRanges) { for (const hiddenRange of hiddenRanges) { stickyLineCandidates = stickyLineCandidates.filter(stickyLine => !(stickyLine.startLineNumber >= hiddenRange.startLineNumber && stickyLine.endLineNumber <= hiddenRange.endLineNumber + 1)); @@ -200,145 +196,3 @@ export class StickyLineCandidateProvider extends Disposable { return stickyLineCandidates; } } - -class StickyOutlineElement { - - private static comparator(range1: StickyRange, range2: StickyRange): number { - if (range1.startLineNumber !== range2.startLineNumber) { - return range1.startLineNumber - range2.startLineNumber; - } else { - return range2.endLineNumber - range1.endLineNumber; - } - } - - public static fromOutlineElement(outlineElement: OutlineElement, previousStartLine: number): StickyOutlineElement { - const children: StickyOutlineElement[] = []; - for (const child of outlineElement.children.values()) { - if (child.symbol.selectionRange.startLineNumber !== child.symbol.range.endLineNumber) { - if (child.symbol.selectionRange.startLineNumber !== previousStartLine) { - children.push(StickyOutlineElement.fromOutlineElement(child, child.symbol.selectionRange.startLineNumber)); - } else { - for (const subchild of child.children.values()) { - children.push(StickyOutlineElement.fromOutlineElement(subchild, child.symbol.selectionRange.startLineNumber)); - } - } - } - } - children.sort((child1, child2) => this.comparator(child1.range!, child2.range!)); - const range = new StickyRange(outlineElement.symbol.selectionRange.startLineNumber, outlineElement.symbol.range.endLineNumber); - return new StickyOutlineElement(range, children, undefined); - } - - public static fromOutlineModel(outlineModel: OutlineModel, preferredProvider: string | undefined): { stickyOutlineElement: StickyOutlineElement; providerID: string | undefined } { - - let outlineElements: Map; - // When several possible outline providers - if (Iterable.first(outlineModel.children.values()) instanceof OutlineGroup) { - const provider = Iterable.find(outlineModel.children.values(), outlineGroupOfModel => outlineGroupOfModel.id === preferredProvider); - if (provider) { - outlineElements = provider.children; - } else { - let tempID = ''; - let maxTotalSumOfRanges = -1; - let optimalOutlineGroup = undefined; - for (const [_key, outlineGroup] of outlineModel.children.entries()) { - const totalSumRanges = StickyOutlineElement.findSumOfRangesOfGroup(outlineGroup); - if (totalSumRanges > maxTotalSumOfRanges) { - optimalOutlineGroup = outlineGroup; - maxTotalSumOfRanges = totalSumRanges; - tempID = outlineGroup.id; - } - } - preferredProvider = tempID; - outlineElements = optimalOutlineGroup!.children; - } - } else { - outlineElements = outlineModel.children as Map; - } - const stickyChildren: StickyOutlineElement[] = []; - const outlineElementsArray = Array.from(outlineElements.values()).sort((element1, element2) => { - const range1: StickyRange = new StickyRange(element1.symbol.range.startLineNumber, element1.symbol.range.endLineNumber); - const range2: StickyRange = new StickyRange(element2.symbol.range.startLineNumber, element2.symbol.range.endLineNumber); - return this.comparator(range1, range2); - }); - for (const outlineElement of outlineElementsArray) { - stickyChildren.push(StickyOutlineElement.fromOutlineElement(outlineElement, outlineElement.symbol.selectionRange.startLineNumber)); - } - const stickyOutlineElement = new StickyOutlineElement(undefined, stickyChildren, undefined); - - return { - stickyOutlineElement: stickyOutlineElement, - providerID: preferredProvider - }; - } - - private static findSumOfRangesOfGroup(outline: OutlineGroup | OutlineElement): number { - let res = 0; - for (const child of outline.children.values()) { - res += this.findSumOfRangesOfGroup(child); - } - if (outline instanceof OutlineElement) { - return res + outline.symbol.range.endLineNumber - outline.symbol.selectionRange.startLineNumber; - } else { - return res; - } - } - - public static fromFoldingModel(foldingModel: FoldingModel): StickyOutlineElement { - const regions = foldingModel.regions; - const length = regions.length; - let range: StickyRange | undefined; - const stackOfParents: StickyRange[] = []; - - const stickyOutlineElement = new StickyOutlineElement( - undefined, - [], - undefined - ); - let parentStickyOutlineElement = stickyOutlineElement; - - for (let i = 0; i < length; i++) { - range = new StickyRange(regions.getStartLineNumber(i), regions.getEndLineNumber(i) + 1); - while (stackOfParents.length !== 0 && (range.startLineNumber < stackOfParents[stackOfParents.length - 1].startLineNumber || range.endLineNumber > stackOfParents[stackOfParents.length - 1].endLineNumber)) { - stackOfParents.pop(); - if (parentStickyOutlineElement.parent !== undefined) { - parentStickyOutlineElement = parentStickyOutlineElement.parent; - } - } - const child = new StickyOutlineElement( - range, - [], - parentStickyOutlineElement - ); - parentStickyOutlineElement.children.push(child); - parentStickyOutlineElement = child; - stackOfParents.push(range); - } - return stickyOutlineElement; - } - - constructor( - /** - * Range of line numbers spanned by the current scope - */ - public readonly range: StickyRange | undefined, - /** - * Must be sorted by start line number - */ - public readonly children: StickyOutlineElement[], - /** - * Parent sticky outline element - */ - public readonly parent: StickyOutlineElement | undefined - ) { - } -} - -class StickyOutlineModel { - constructor( - readonly uri: URI, - readonly version: number, - readonly element: StickyOutlineElement | undefined, - readonly outlineProviderId: string | undefined - ) { } -} diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts index 0daf442c877..0d425e2f62f 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts @@ -2,29 +2,17 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IActiveCodeEditor, ICodeEditor, IOverlayWidget, IOverlayWidgetPosition } from 'vs/editor/browser/editorBrowser'; -import * as dom from 'vs/base/browser/dom'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition } from 'vs/editor/browser/editorBrowser'; import { EditorLayoutInfo, EditorOption, RenderLineNumbersType } from 'vs/editor/common/config/editorOptions'; import { StringBuilder } from 'vs/editor/common/core/stringBuilder'; import { RenderLineInput, renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer'; import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations'; import { Position } from 'vs/editor/common/core/position'; -import { ClickLinkGesture } from 'vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture'; -import { getDefinitionsAtPosition } from 'vs/editor/contrib/gotoSymbol/browser/goToSymbol'; -import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { goToDefinitionWithLocation } from 'vs/editor/contrib/inlayHints/browser/inlayHintsLocations'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { CancellationTokenSource } from 'vs/base/common/cancellation'; -import { IRange, Range } from 'vs/editor/common/core/range'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; -import 'vs/css!./stickyScroll'; import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; - -interface CustomMouseEvent { - detail: string; - element: HTMLElement; -} +import * as dom from 'vs/base/browser/dom'; +import 'vs/css!./stickyScroll'; export class StickyScrollWidgetState { constructor( @@ -45,13 +33,9 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { private _lastLineRelativePosition: number = 0; private _hoverOnLine: number = -1; private _hoverOnColumn: number = -1; - private _stickyRangeProjectedOnEditor: IRange | undefined; - private _candidateDefinitionsLength: number = -1; constructor( - private readonly _editor: ICodeEditor, - @ILanguageFeaturesService private readonly _languageFeatureService: ILanguageFeaturesService, - @IInstantiationService private readonly _instaService: IInstantiationService + private readonly _editor: ICodeEditor ) { super(); this._layoutInfo = this._editor.getLayoutInfo(); @@ -59,97 +43,14 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { this._rootDomNode.className = 'sticky-widget'; this._rootDomNode.classList.toggle('peek', _editor instanceof EmbeddedCodeEditorWidget); this._rootDomNode.style.width = `${this._layoutInfo.width - this._layoutInfo.minimap.minimapCanvasOuterWidth - this._layoutInfo.verticalScrollbarWidth}px`; - - this._register(this._updateLinkGesture()); } - private _updateLinkGesture(): IDisposable { + get hoverOnLine(): number { + return this._hoverOnLine; + } - const linkGestureStore = new DisposableStore(); - const sessionStore = new DisposableStore(); - linkGestureStore.add(sessionStore); - const gesture = new ClickLinkGesture(this._editor, true); - linkGestureStore.add(gesture); - - linkGestureStore.add(gesture.onMouseMoveOrRelevantKeyDown(([mouseEvent, _keyboardEvent]) => { - if (!this._editor.hasModel() || !mouseEvent.hasTriggerModifier) { - sessionStore.clear(); - return; - } - const targetMouseEvent = mouseEvent.target as unknown as CustomMouseEvent; - if (targetMouseEvent.detail === this.getId() && targetMouseEvent.element.innerText === targetMouseEvent.element.innerHTML) { - const text = targetMouseEvent.element.innerText; - if (this._hoverOnColumn === -1) { - return; - } - const lineNumber = this._hoverOnLine; - const column = this._hoverOnColumn; - - const stickyPositionProjectedOnEditor = new Range(lineNumber, column, lineNumber, column + text.length); - if (!stickyPositionProjectedOnEditor.equalsRange(this._stickyRangeProjectedOnEditor)) { - this._stickyRangeProjectedOnEditor = stickyPositionProjectedOnEditor; - sessionStore.clear(); - } else if (targetMouseEvent.element.style.textDecoration === 'underline') { - return; - } - - const cancellationToken = new CancellationTokenSource(); - sessionStore.add(toDisposable(() => cancellationToken.dispose(true))); - - let currentHTMLChild: HTMLElement; - - getDefinitionsAtPosition(this._languageFeatureService.definitionProvider, this._editor.getModel(), new Position(lineNumber, column + 1), cancellationToken.token).then((candidateDefinitions => { - if (cancellationToken.token.isCancellationRequested) { - return; - } - if (candidateDefinitions.length !== 0) { - this._candidateDefinitionsLength = candidateDefinitions.length; - const childHTML: HTMLElement = targetMouseEvent.element; - if (currentHTMLChild !== childHTML) { - sessionStore.clear(); - currentHTMLChild = childHTML; - currentHTMLChild.style.textDecoration = 'underline'; - sessionStore.add(toDisposable(() => { - currentHTMLChild.style.textDecoration = 'none'; - })); - } else if (!currentHTMLChild) { - currentHTMLChild = childHTML; - currentHTMLChild.style.textDecoration = 'underline'; - sessionStore.add(toDisposable(() => { - currentHTMLChild.style.textDecoration = 'none'; - })); - } - } else { - sessionStore.clear(); - } - })); - } else { - sessionStore.clear(); - } - })); - linkGestureStore.add(gesture.onCancel(() => { - sessionStore.clear(); - })); - linkGestureStore.add(gesture.onExecute(async e => { - if ((e.target as unknown as CustomMouseEvent).detail !== this.getId()) { - return; - } - if (e.hasTriggerModifier) { - // Control click - if (this._candidateDefinitionsLength > 1) { - this._editor.revealPosition({ lineNumber: this._hoverOnLine, column: 1 }); - } - this._instaService.invokeFunction(goToDefinitionWithLocation, e, this._editor as IActiveCodeEditor, { uri: this._editor.getModel()!.uri, range: this._stickyRangeProjectedOnEditor! }); - - } else if (!e.isRightClick) { - // Normal click - const position = { lineNumber: this._hoverOnLine, column: this._hoverOnColumn }; - this._editor.revealPosition(position); - this._editor.setSelection(Range.fromPositions(position)); - this._editor.focus(); - } - })); - return linkGestureStore; + get hoverOnColumn(): number { + return this._hoverOnColumn; } get lineNumbers(): number[] { @@ -165,16 +66,45 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { } setState(state: StickyScrollWidgetState): void { + dom.clearNode(this._rootDomNode); this._disposableStore.clear(); this._lineNumbers.length = 0; - dom.clearNode(this._rootDomNode); + const editorLineHeight = this._editor.getOption(EditorOption.lineHeight); + const futureWidgetHeight = state.lineNumbers.length * editorLineHeight + state.lastLineRelativePosition; - this._lastLineRelativePosition = state.lastLineRelativePosition; - this._lineNumbers = state.lineNumbers; + if (futureWidgetHeight > 0) { + this._lastLineRelativePosition = state.lastLineRelativePosition; + this._lineNumbers = state.lineNumbers; + } else { + this._lastLineRelativePosition = 0; + this._lineNumbers = []; + } this._renderRootNode(); } - private _renderChildNode(index: number, line: number): HTMLElement { + private _renderRootNode(): void { + + if (!this._editor._getViewModel()) { + return; + } + for (const [index, line] of this._lineNumbers.entries()) { + const childNode = this._renderChildNode(index, line); + this._rootDomNode.appendChild(childNode); + } + + const editorLineHeight = this._editor.getOption(EditorOption.lineHeight); + const widgetHeight: number = this._lineNumbers.length * editorLineHeight + this._lastLineRelativePosition; + this._rootDomNode.style.display = widgetHeight > 0 ? 'block' : 'none'; + this._rootDomNode.style.height = widgetHeight.toString() + 'px'; + this._rootDomNode.setAttribute('role', 'list'); + const minimapSide = this._editor.getOption(EditorOption.minimap).side; + + if (minimapSide === 'left') { + this._rootDomNode.style.marginLeft = this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth + 'px'; + } + } + + private _renderChildNode(index: number, line: number): HTMLDivElement { const child = document.createElement('div'); const viewModel = this._editor._getViewModel(); @@ -249,6 +179,8 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { child.appendChild(lineHTMLNode); child.className = 'sticky-line-root'; + child.setAttribute('role', 'listitem'); + child.tabIndex = 0; child.style.lineHeight = `${lineHeight}px`; child.style.width = `${width}px`; child.style.height = `${lineHeight}px`; @@ -261,10 +193,13 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { child.style.top = this._lastLineRelativePosition + 'px'; } + // Each child has a listener which fires when the mouse hovers over the child this._disposableStore.add(dom.addDisposableListener(child, 'mouseover', (e) => { if (this._editor.hasModel()) { const mouseOverEvent = new StandardMouseEvent(e); const text = mouseOverEvent.target.innerText; + + // Line and column number of the hover needed for the control clicking feature this._hoverOnLine = line; // TODO: workaround to find the column index, perhaps need a more solid solution this._hoverOnColumn = this._editor.getModel().getLineContent(line).indexOf(text) + 1 || -1; @@ -274,23 +209,6 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { return child; } - private _renderRootNode(): void { - if (!this._editor._getViewModel()) { - return; - } - for (const [index, line] of this._lineNumbers.entries()) { - this._rootDomNode.appendChild(this._renderChildNode(index, line)); - } - const editorLineHeight = this._editor.getOption(EditorOption.lineHeight); - const widgetHeight: number = this._lineNumbers.length * editorLineHeight + this._lastLineRelativePosition; - this._rootDomNode.style.display = widgetHeight > 0 ? 'block' : 'none'; - this._rootDomNode.style.height = widgetHeight.toString() + 'px'; - const minimapSide = this._editor.getOption(EditorOption.minimap).side; - if (minimapSide === 'left') { - this._rootDomNode.style.marginLeft = this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth + 'px'; - } - } - getId(): string { return 'editor.contrib.stickyScrollWidget'; } diff --git a/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts b/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts index 9e4e01fb994..587cc3b2e68 100644 --- a/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts +++ b/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts @@ -15,13 +15,19 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { mock } from 'vs/base/test/common/mock'; +import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { ILanguageFeatureDebounceService, LanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; +import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; +import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; suite('Sticky Scroll Tests', () => { const serviceCollection = new ServiceCollection( [ILanguageFeaturesService, new LanguageFeaturesService()], [ILogService, new NullLogService()], - [IContextMenuService, new class extends mock() { }] + [IContextMenuService, new class extends mock() { }], + [ILanguageConfigurationService, new TestLanguageConfigurationService()], + [ILanguageFeatureDebounceService, new SyncDescriptor(LanguageFeatureDebounceService)], ); const text = [ @@ -106,10 +112,17 @@ suite('Sticky Scroll Tests', () => { test('Testing the function getCandidateStickyLinesIntersecting', async () => { const model = createTextModel(text); - await withAsyncTestCodeEditor(model, { serviceCollection }, async (editor, _viewModel, instantiationService) => { + await withAsyncTestCodeEditor(model, { + stickyScroll: { + enabled: true, + maxLineCount: 5, + defaultModel: 'outlineModel' + }, serviceCollection: serviceCollection + }, async (editor, _viewModel, instantiationService) => { const languageService = instantiationService.get(ILanguageFeaturesService); + const languageConfigurationService = instantiationService.get(ILanguageConfigurationService); languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel()); - const provider: StickyLineCandidateProvider = new StickyLineCandidateProvider(editor, languageService); + const provider: StickyLineCandidateProvider = new StickyLineCandidateProvider(editor, languageService, languageConfigurationService); await provider.update(); assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 1, endLineNumber: 4 }), [new StickyLineCandidate(1, 2, 1)]); assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 8, endLineNumber: 10 }), [new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]); @@ -123,7 +136,13 @@ suite('Sticky Scroll Tests', () => { test('issue #157180: Render the correct line corresponding to the scope definition', async () => { const model = createTextModel(text); - await withAsyncTestCodeEditor(model, { serviceCollection }, async (editor, _viewModel, instantiationService) => { + await withAsyncTestCodeEditor(model, { + stickyScroll: { + enabled: true, + maxLineCount: 5, + defaultModel: 'outlineModel' + }, serviceCollection + }, async (editor, _viewModel, instantiationService) => { const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController); const lineHeight: number = editor.getOption(EditorOption.lineHeight); @@ -133,27 +152,27 @@ suite('Sticky Scroll Tests', () => { let state; editor.setScrollTop(1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [1]); editor.setScrollTop(lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [1]); editor.setScrollTop(4 * lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, []); editor.setScrollTop(8 * lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [7, 9]); editor.setScrollTop(9 * lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [7, 9]); editor.setScrollTop(10 * lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [7]); stickyScrollController.dispose(); @@ -165,7 +184,13 @@ suite('Sticky Scroll Tests', () => { test('issue #156268 : Do not reveal sticky lines when they are in a folded region ', async () => { const model = createTextModel(text); - await withAsyncTestCodeEditor(model, { serviceCollection }, async (editor, viewModel, instantiationService) => { + await withAsyncTestCodeEditor(model, { + stickyScroll: { + enabled: true, + maxLineCount: 5, + defaultModel: 'outlineModel' + }, serviceCollection + }, async (editor, viewModel, instantiationService) => { const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController); const lineHeight = editor.getOption(EditorOption.lineHeight); @@ -177,23 +202,23 @@ suite('Sticky Scroll Tests', () => { let state; editor.setScrollTop(1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [1]); editor.setScrollTop(lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, []); editor.setScrollTop(6 * lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [7, 9]); editor.setScrollTop(7 * lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [7]); editor.setScrollTop(10 * lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, []); stickyScrollController.dispose(); @@ -252,7 +277,13 @@ suite('Sticky Scroll Tests', () => { test('issue #159271 : render the correct widget state when the child scope starts on the same line as the parent scope', async () => { const model = createTextModel(textWithScopesWithSameStartingLines); - await withAsyncTestCodeEditor(model, { serviceCollection }, async (editor, _viewModel, instantiationService) => { + await withAsyncTestCodeEditor(model, { + stickyScroll: { + enabled: true, + maxLineCount: 5, + defaultModel: 'outlineModel' + }, serviceCollection + }, async (editor, _viewModel, instantiationService) => { const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController); await stickyScrollController.stickyScrollCandidateProvider.update(); @@ -264,23 +295,23 @@ suite('Sticky Scroll Tests', () => { let state; editor.setScrollTop(1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [1, 2]); editor.setScrollTop(lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [1, 2]); editor.setScrollTop(2 * lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [1]); editor.setScrollTop(3 * lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, [1]); editor.setScrollTop(4 * lineHeight + 1); - state = stickyScrollController.getScrollWidgetState(); + state = stickyScrollController.findScrollWidgetState(); assert.deepStrictEqual(state.lineNumbers, []); stickyScrollController.dispose(); diff --git a/src/vs/editor/contrib/suggest/browser/suggest.ts b/src/vs/editor/contrib/suggest/browser/suggest.ts index 29c5c470bb3..3409fa42392 100644 --- a/src/vs/editor/contrib/suggest/browser/suggest.ts +++ b/src/vs/editor/contrib/suggest/browser/suggest.ts @@ -84,7 +84,7 @@ export class CompletionItem { ) { this.textLabel = typeof completion.label === 'string' ? completion.label - : completion.label.label; + : completion.label?.label; // ensure lower-variants (perf) this.labelLow = this.textLabel.toLowerCase(); @@ -397,7 +397,8 @@ CommandsRegistry.registerCommand('_executeCompletionItemProvider', async (access }; const resolving: Promise[] = []; - const completions = await provideSuggestionItems(completionProvider, ref.object.textEditorModel, Position.lift(position), undefined, { triggerCharacter: triggerCharacter ?? undefined, triggerKind: triggerCharacter ? languages.CompletionTriggerKind.TriggerCharacter : languages.CompletionTriggerKind.Invoke }); + const actualPosition = ref.object.textEditorModel.validatePosition(position); + const completions = await provideSuggestionItems(completionProvider, ref.object.textEditorModel, actualPosition, undefined, { triggerCharacter: triggerCharacter ?? undefined, triggerKind: triggerCharacter ? languages.CompletionTriggerKind.TriggerCharacter : languages.CompletionTriggerKind.Invoke }); for (const item of completions.items) { if (resolving.length < (maxItemsToResolve ?? 0)) { resolving.push(item.resolve(CancellationToken.None)); diff --git a/src/vs/editor/contrib/suggest/browser/suggestAlternatives.ts b/src/vs/editor/contrib/suggest/browser/suggestAlternatives.ts index 3df043694c8..2422c361a35 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestAlternatives.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestAlternatives.ts @@ -68,7 +68,7 @@ export class SuggestAlternatives { private static _moveIndex(fwd: boolean, model: CompletionModel, index: number): number { let newIndex = index; - while (true) { + for (let rounds = model.items.length; rounds > 0; rounds--) { newIndex = (newIndex + model.items.length + (fwd ? +1 : -1)) % model.items.length; if (newIndex === index) { break; diff --git a/src/vs/editor/contrib/suggest/browser/suggestController.ts b/src/vs/editor/contrib/suggest/browser/suggestController.ts index 30513721fb3..abd5d8b23bb 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestController.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestController.ts @@ -339,6 +339,10 @@ export class SuggestController implements IEditorContribution { if (Array.isArray(item.completion.additionalTextEdits)) { + + // cancel -> stops all listening and closes widget + this.model.cancel(); + // sync additional edits const scrollState = StableEditorScrollState.capture(this.editor); this.editor.executeEdits( @@ -845,7 +849,7 @@ registerEditorCommand(new SuggestCommand({ registerEditorCommand(new SuggestCommand({ id: 'selectNextSuggestion', - precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.MultipleSuggestions), + precondition: ContextKeyExpr.and(SuggestContext.Visible, ContextKeyExpr.or(SuggestContext.MultipleSuggestions, SuggestContext.HasFocusedSuggestion.negate())), handler: c => c.selectNextSuggestion(), kbOpts: { weight: weight, @@ -858,7 +862,7 @@ registerEditorCommand(new SuggestCommand({ registerEditorCommand(new SuggestCommand({ id: 'selectNextPageSuggestion', - precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.MultipleSuggestions), + precondition: ContextKeyExpr.and(SuggestContext.Visible, ContextKeyExpr.or(SuggestContext.MultipleSuggestions, SuggestContext.HasFocusedSuggestion.negate())), handler: c => c.selectNextPageSuggestion(), kbOpts: { weight: weight, @@ -870,13 +874,13 @@ registerEditorCommand(new SuggestCommand({ registerEditorCommand(new SuggestCommand({ id: 'selectLastSuggestion', - precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.MultipleSuggestions), + precondition: ContextKeyExpr.and(SuggestContext.Visible, ContextKeyExpr.or(SuggestContext.MultipleSuggestions, SuggestContext.HasFocusedSuggestion.negate())), handler: c => c.selectLastSuggestion() })); registerEditorCommand(new SuggestCommand({ id: 'selectPrevSuggestion', - precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.MultipleSuggestions), + precondition: ContextKeyExpr.and(SuggestContext.Visible, ContextKeyExpr.or(SuggestContext.MultipleSuggestions, SuggestContext.HasFocusedSuggestion.negate())), handler: c => c.selectPrevSuggestion(), kbOpts: { weight: weight, @@ -889,7 +893,7 @@ registerEditorCommand(new SuggestCommand({ registerEditorCommand(new SuggestCommand({ id: 'selectPrevPageSuggestion', - precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.MultipleSuggestions), + precondition: ContextKeyExpr.and(SuggestContext.Visible, ContextKeyExpr.or(SuggestContext.MultipleSuggestions, SuggestContext.HasFocusedSuggestion.negate())), handler: c => c.selectPrevPageSuggestion(), kbOpts: { weight: weight, @@ -901,13 +905,13 @@ registerEditorCommand(new SuggestCommand({ registerEditorCommand(new SuggestCommand({ id: 'selectFirstSuggestion', - precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.MultipleSuggestions), + precondition: ContextKeyExpr.and(SuggestContext.Visible, ContextKeyExpr.or(SuggestContext.MultipleSuggestions, SuggestContext.HasFocusedSuggestion.negate())), handler: c => c.selectFirstSuggestion() })); registerEditorCommand(new SuggestCommand({ id: 'focusSuggestion', - precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.HasFocusedSuggestion.negate(), ContextKeyExpr.equals('config.editor.suggest.selectQuickSuggestions', false)), + precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.HasFocusedSuggestion.negate()), handler: x => x.focusSuggestion(), kbOpts: { weight: weight, @@ -918,6 +922,15 @@ registerEditorCommand(new SuggestCommand({ }, })); +registerEditorCommand(new SuggestCommand({ + id: 'focusAndAcceptSuggestion', + precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.HasFocusedSuggestion.negate()), + handler: c => { + c.focusSuggestion(); + c.acceptSelectedSuggestion(true, false); + } +})); + registerEditorCommand(new SuggestCommand({ id: 'toggleSuggestionDetails', precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.HasFocusedSuggestion), diff --git a/src/vs/editor/contrib/suggest/browser/suggestInlineCompletions.ts b/src/vs/editor/contrib/suggest/browser/suggestInlineCompletions.ts index 660d7ecdaab..6768df31b2a 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestInlineCompletions.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestInlineCompletions.ts @@ -16,10 +16,9 @@ import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { IWordAtPosition } from 'vs/editor/common/core/wordHelper'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; -import { Command, CompletionItemProvider, CompletionTriggerKind, InlineCompletion, InlineCompletionContext, InlineCompletions, InlineCompletionsProvider } from 'vs/editor/common/languages'; +import { Command, CompletionItemInsertTextRule, CompletionItemProvider, CompletionTriggerKind, InlineCompletion, InlineCompletionContext, InlineCompletions, InlineCompletionsProvider } from 'vs/editor/common/languages'; import { ITextModel } from 'vs/editor/common/model'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { CompletionItemInsertTextRule } from 'vs/editor/common/standalone/standaloneEnums'; import { CompletionModel, LineContext } from 'vs/editor/contrib/suggest/browser/completionModel'; import { CompletionItem, CompletionItemModel, CompletionOptions, provideSuggestionItems, QuickSuggestionsOptions } from 'vs/editor/contrib/suggest/browser/suggest'; import { ISuggestMemoryService } from 'vs/editor/contrib/suggest/browser/suggestMemory'; diff --git a/src/vs/editor/contrib/suggest/browser/suggestModel.ts b/src/vs/editor/contrib/suggest/browser/suggestModel.ts index 58760d5a539..830560e94a5 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestModel.ts @@ -101,25 +101,13 @@ export const enum State { Auto = 2 } -function isSuggestPreviewEnabled(editor: ICodeEditor): boolean { - return editor.getOption(EditorOption.suggest).preview; -} - function canShowQuickSuggest(editor: ICodeEditor, contextKeyService: IContextKeyService, configurationService: IConfigurationService): boolean { if (!Boolean(contextKeyService.getContextKeyValue('inlineSuggestionVisible'))) { // Allow if there is no inline suggestion. return true; } - const allowQuickSuggestions = configurationService.getValue('editor.inlineSuggest.allowQuickSuggestions', { overrideIdentifier: editor.getModel()?.getLanguageId(), resource: editor.getModel()?.uri }); - if (allowQuickSuggestions !== undefined) { - // Use setting if available. - return Boolean(allowQuickSuggestions); - } - - // Don't allow if inline suggestions are visible and no suggest preview is configured. - // TODO disabled for copilot - return false && isSuggestPreviewEnabled(editor); + return !editor.getOption(EditorOption.inlineSuggest).suppressSuggestions; } function canShowSuggestOnTriggerCharacters(editor: ICodeEditor, contextKeyService: IContextKeyService, configurationService: IConfigurationService): boolean { @@ -128,15 +116,7 @@ function canShowSuggestOnTriggerCharacters(editor: ICodeEditor, contextKeyServic return true; } - const allowQuickSuggestions = configurationService.getValue('editor.inlineSuggest.allowSuggestOnTriggerCharacters', { overrideIdentifier: editor.getModel()?.getLanguageId(), resource: editor.getModel()?.uri }); - if (allowQuickSuggestions !== undefined) { - // Use setting if available. - return Boolean(allowQuickSuggestions); - } - - // Don't allow if inline suggestions are visible and no suggest preview is configured. - // TODO disabled for copilot - return false && isSuggestPreviewEnabled(editor); + return !editor.getOption(EditorOption.inlineSuggest).suppressSuggestions; } export class SuggestModel implements IDisposable { diff --git a/src/vs/editor/contrib/suggest/test/browser/suggestModel.test.ts b/src/vs/editor/contrib/suggest/test/browser/suggestModel.test.ts index 06940a3709f..f1c0f9c4b80 100644 --- a/src/vs/editor/contrib/suggest/test/browser/suggestModel.test.ts +++ b/src/vs/editor/contrib/suggest/test/browser/suggestModel.test.ts @@ -706,7 +706,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { return withOracle(async (sugget, editor) => { class TestCtrl extends SuggestController { - override _insertSuggestion(item: ISelectedSuggestion, flags: number = 0) { + _insertSuggestion_publicForTest(item: ISelectedSuggestion, flags: number = 0) { super._insertSuggestion(item, flags); } } @@ -722,7 +722,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { const [first] = event.completionModel.items; assert.strictEqual(first.completion.label, 'bar'); - ctrl._insertSuggestion({ item: first, index: 0, model: event.completionModel }); + ctrl._insertSuggestion_publicForTest({ item: first, index: 0, model: event.completionModel }); }); assert.strictEqual( @@ -1087,8 +1087,6 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { return withOracle(async function (model, editor) { - // editor.updateOptions({ suggest: { selectQuickSuggestions: 'whenQuickSuggestion' } }); - await assertEvent(model.onDidSuggest, () => { editor.setValue('foo'); editor.setSelection(new Selection(1, 4, 1, 4)); diff --git a/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css b/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css index 45205fea274..475006090b4 100644 --- a/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css +++ b/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css @@ -66,7 +66,7 @@ .monaco-editor .codicon.codicon-symbol-text, .monaco-workbench .codicon.codicon-symbol-text { color: var(--vscode-symbolIcon-textForeground); } .monaco-editor .codicon.codicon-symbol-type-parameter, -.monaco-workbench .codicon.codicon-symbol-type-parameter { color: var(--vscode-typeParameterForeground); } +.monaco-workbench .codicon.codicon-symbol-type-parameter { color: var(--vscode-symbolIcon-typeParameterForeground); } .monaco-editor .codicon.codicon-symbol-unit, .monaco-workbench .codicon.codicon-symbol-unit { color: var(--vscode-symbolIcon-unitForeground); } .monaco-editor .codicon.codicon-symbol-variable, diff --git a/src/vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode.ts b/src/vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode.ts index 6feef76d443..44e53dcee12 100644 --- a/src/vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode.ts +++ b/src/vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode.ts @@ -5,10 +5,11 @@ import { alert } from 'vs/base/browser/ui/aria/aria'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { TabFocus } from 'vs/editor/browser/config/tabFocus'; +import { TabFocus, TabFocusContext } from 'vs/editor/browser/config/tabFocus'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import * as nls from 'vs/nls'; import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; export class ToggleTabFocusModeAction extends Action2 { @@ -18,20 +19,22 @@ export class ToggleTabFocusModeAction extends Action2 { constructor() { super({ id: ToggleTabFocusModeAction.ID, - title: nls.localize({ key: 'toggle.tabMovesFocus', comment: ['Turn on/off use of tab key for moving focus around VS Code'] }, "Toggle Tab Key Moves Focus"), + title: { value: nls.localize({ key: 'toggle.tabMovesFocus', comment: ['Turn on/off use of tab key for moving focus around VS Code'] }, 'Toggle Tab Key Moves Focus'), original: 'Toggle Tab Key Moves Focus' }, precondition: undefined, keybinding: { primary: KeyMod.CtrlCmd | KeyCode.KeyM, mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KeyM }, weight: KeybindingWeight.EditorContrib - } + }, + f1: true }); } public run(accessor: ServicesAccessor): void { - const oldValue = TabFocus.getTabFocusMode(); + const context = accessor.get(IContextKeyService).getContextKeyValue('focusedView') === 'terminal' ? TabFocusContext.Terminal : TabFocusContext.Editor; + const oldValue = TabFocus.getTabFocusMode(context); const newValue = !oldValue; - TabFocus.setTabFocusMode(newValue); + TabFocus.setTabFocusMode(newValue, context); if (newValue) { alert(nls.localize('toggle.tabMovesFocus.on', "Pressing Tab will now move focus to the next focusable element")); } else { diff --git a/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts b/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts index 9cb1e2b67e0..9b77b25b72e 100644 --- a/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts +++ b/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts @@ -9,7 +9,7 @@ import { Codicon } from 'vs/base/common/codicons'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; -import { InvisibleCharacters } from 'vs/base/common/strings'; +import { InvisibleCharacters, isBasicASCII } from 'vs/base/common/strings'; import 'vs/css!./unicodeHighlighter'; import { IActiveCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, EditorContributionInstantiation, registerEditorAction, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; @@ -407,7 +407,7 @@ export class UnicodeHighlighterHover implements IHoverPart { export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipant { - public readonly hoverOrdinal: number = 4; + public readonly hoverOrdinal: number = 5; constructor( private readonly _editor: ICodeEditor, @@ -444,14 +444,24 @@ export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipa let reason: string; switch (highlightInfo.reason.kind) { - case UnicodeHighlighterReasonKind.Ambiguous: - reason = nls.localize( - 'unicodeHighlight.characterIsAmbiguous', - 'The character {0} could be confused with the character {1}, which is more common in source code.', - codePointStr, - formatCodePointMarkdown(highlightInfo.reason.confusableWith.codePointAt(0)!) - ); + case UnicodeHighlighterReasonKind.Ambiguous: { + if (isBasicASCII(highlightInfo.reason.confusableWith)) { + reason = nls.localize( + 'unicodeHighlight.characterIsAmbiguousASCII', + 'The character {0} could be confused with the ASCII character {1}, which is more common in source code.', + codePointStr, + formatCodePointMarkdown(highlightInfo.reason.confusableWith.codePointAt(0)!) + ); + } else { + reason = nls.localize( + 'unicodeHighlight.characterIsAmbiguous', + 'The character {0} could be confused with the character {1}, which is more common in source code.', + codePointStr, + formatCodePointMarkdown(highlightInfo.reason.confusableWith.codePointAt(0)!) + ); + } break; + } case UnicodeHighlighterReasonKind.Invisible: reason = nls.localize( diff --git a/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.css b/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.css index d5406c6d4c8..898d02e3f77 100644 --- a/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.css +++ b/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.css @@ -8,7 +8,7 @@ box-sizing: border-box; border: 1px solid var(--vscode-editor-selectionHighlightBorder); } -.monaco-editor.hc-black .selectionHighlight, .monaco-editor.hc-light .selectionHighlight { +.monaco-editor.hc-black .focused .selectionHighlight, .monaco-editor.hc-light .focused .selectionHighlight { border-style: dotted; } @@ -30,7 +30,7 @@ border-style: dotted; } -.monaco-editor .focused .wordHighlightText { +.monaco-editor .wordHighlightText { background-color: var(--vscode-editor-wordHighlightTextBackground); box-sizing: border-box; border: 1px solid var(--vscode-editor-wordHighlightTextBorder); diff --git a/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts index 4fb065c2823..ee6b06b6319 100644 --- a/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts +++ b/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts @@ -245,6 +245,14 @@ class WordHighlighter { this._run(); } + public stop(): void { + if (!this.occurrencesHighlight) { + return; + } + + this._stopAll(); + } + private _getSortedHighlights(): Range[] { return ( this.decorations.getRanges() @@ -453,7 +461,7 @@ class WordHighlighter { } } -class WordHighlighterContribution extends Disposable implements IEditorContribution { +export class WordHighlighterContribution extends Disposable implements IEditorContribution { public static readonly ID = 'editor.contrib.wordHighlighter'; @@ -502,6 +510,10 @@ class WordHighlighterContribution extends Disposable implements IEditorContribut } } + public stopHighlighting() { + this.wordHighlighter?.stop(); + } + public override dispose(): void { if (this.wordHighlighter) { this.wordHighlighter.dispose(); diff --git a/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts b/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts index cf0ab63f807..d6195522780 100644 --- a/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts +++ b/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts @@ -261,7 +261,7 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { } } - private _getWidth(info: EditorLayoutInfo): number { + protected _getWidth(info: EditorLayoutInfo): number { return info.width - info.minimap.minimapWidth - info.verticalScrollbarWidth; } diff --git a/src/vs/editor/editor.all.ts b/src/vs/editor/editor.all.ts index 9c960331ab4..38a7a98a345 100644 --- a/src/vs/editor/editor.all.ts +++ b/src/vs/editor/editor.all.ts @@ -42,16 +42,17 @@ import 'vs/editor/contrib/longLinesHelper/browser/longLinesHelper'; import 'vs/editor/contrib/multicursor/browser/multicursor'; import 'vs/editor/contrib/parameterHints/browser/parameterHints'; import 'vs/editor/contrib/rename/browser/rename'; -import 'vs/editor/contrib/stickyScroll/browser/stickyScrollContribution'; +import 'vs/editor/contrib/semanticTokens/browser/documentSemanticTokens'; +import 'vs/editor/contrib/semanticTokens/browser/viewportSemanticTokens'; import 'vs/editor/contrib/smartSelect/browser/smartSelect'; import 'vs/editor/contrib/snippet/browser/snippetController2'; +import 'vs/editor/contrib/stickyScroll/browser/stickyScrollContribution'; import 'vs/editor/contrib/suggest/browser/suggestController'; import 'vs/editor/contrib/suggest/browser/suggestInlineCompletions'; import 'vs/editor/contrib/tokenization/browser/tokenization'; import 'vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode'; import 'vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter'; import 'vs/editor/contrib/unusualLineTerminators/browser/unusualLineTerminators'; -import 'vs/editor/contrib/viewportSemanticTokens/browser/viewportSemanticTokens'; import 'vs/editor/contrib/wordHighlighter/browser/wordHighlighter'; import 'vs/editor/contrib/wordOperations/browser/wordOperations'; import 'vs/editor/contrib/wordPartOperations/browser/wordPartOperations'; diff --git a/src/vs/editor/editor.api.ts b/src/vs/editor/editor.api.ts index 2378f8508ef..a9fc0b29404 100644 --- a/src/vs/editor/editor.api.ts +++ b/src/vs/editor/editor.api.ts @@ -7,7 +7,6 @@ import { EditorOptions, WrappingIndent, EditorAutoIndentStrategy } from 'vs/edit import { createMonacoBaseAPI } from 'vs/editor/common/services/editorBaseApi'; import { createMonacoEditorAPI } from 'vs/editor/standalone/browser/standaloneEditor'; import { createMonacoLanguagesAPI } from 'vs/editor/standalone/browser/standaloneLanguages'; -import { globals } from 'vs/base/common/platform'; import { FormattingConflicts } from 'vs/editor/contrib/format/browser/format'; // Set defaults for standalone editor @@ -38,12 +37,16 @@ export const Token = api.Token; export const editor = api.editor; export const languages = api.languages; -if (globals.MonacoEnvironment?.globalAPI || (typeof define === 'function' && (define).amd)) { - self.monaco = api; +interface IMonacoEnvironment { + globalAPI?: boolean; +} +const monacoEnvironment: IMonacoEnvironment | undefined = (globalThis as any).MonacoEnvironment; +if (monacoEnvironment?.globalAPI || (typeof define === 'function' && (define).amd)) { + globalThis.monaco = api; } -if (typeof self.require !== 'undefined' && typeof self.require.config === 'function') { - self.require.config({ +if (typeof globalThis.require !== 'undefined' && typeof globalThis.require.config === 'function') { + globalThis.require.config({ ignoreDuplicateModules: [ 'vscode-languageserver-types', 'vscode-languageserver-types/main', diff --git a/src/vs/editor/editor.worker.ts b/src/vs/editor/editor.worker.ts index e5931ee62ba..7c53a6094b2 100644 --- a/src/vs/editor/editor.worker.ts +++ b/src/vs/editor/editor.worker.ts @@ -16,15 +16,15 @@ export function initialize(foreignModule: any) { initialized = true; const simpleWorker = new SimpleWorkerServer((msg) => { - (self).postMessage(msg); + globalThis.postMessage(msg); }, (host: IEditorWorkerHost) => new EditorSimpleWorker(host, foreignModule)); - self.onmessage = (e: MessageEvent) => { + globalThis.onmessage = (e: MessageEvent) => { simpleWorker.onmessage(e.data); }; } -self.onmessage = (e: MessageEvent) => { +globalThis.onmessage = (e: MessageEvent) => { // Ignore first message in this case and initialize if not yet initialized if (!initialized) { initialize(null); diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts index dfa8aa29f3f..d5664fcb738 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts @@ -327,7 +327,7 @@ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandalon ); const contextMenuGroupId = _descriptor.contextMenuGroupId || null; const contextMenuOrder = _descriptor.contextMenuOrder || 0; - const run = (accessor?: ServicesAccessor, ...args: any[]): Promise => { + const run = (_accessor?: ServicesAccessor, ...args: any[]): Promise => { return Promise.resolve(_descriptor.run(this, ...args)); }; @@ -367,7 +367,7 @@ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandalon label, label, precondition, - run, + (...args: unknown[]) => Promise.resolve(_descriptor.run(this, ...args)), this._contextKeyService ); @@ -470,7 +470,7 @@ export class StandaloneEditor extends StandaloneCodeEditor implements IStandalon super.updateOptions(newOptions); } - override _postDetachModelCleanup(detachedModel: ITextModel): void { + protected override _postDetachModelCleanup(detachedModel: ITextModel): void { super._postDetachModelCleanup(detachedModel); if (detachedModel && this._ownsModel) { detachedModel.dispose(); diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index f976cb4aa5f..826b9f3f0ff 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -34,7 +34,10 @@ import { EditorCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensi import { IMenuItem, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; -import { LineRange, LineRangeMapping, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { LineRangeMapping, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { LineRange } from 'vs/editor/common/core/lineRange'; +import { EditorZoom } from 'vs/editor/common/config/editorZoom'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; /** * Create a new editor under `domElement`. @@ -240,9 +243,8 @@ export function createModel(value: string, language?: string, uri?: URI): ITextM */ export function setModelLanguage(model: ITextModel, mimeTypeOrLanguageId: string): void { const languageService = StandaloneServices.get(ILanguageService); - const modelService = StandaloneServices.get(IModelService); const languageId = languageService.getLanguageIdByMimeType(mimeTypeOrLanguageId) || mimeTypeOrLanguageId || PLAINTEXT_LANGUAGE_ID; - modelService.setMode(model, languageService.createById(languageId)); + model.setLanguage(languageService.createById(languageId)); } /** @@ -432,6 +434,28 @@ export function registerCommand(id: string, handler: (accessor: any, ...args: an return CommandsRegistry.registerCommand({ id, handler }); } +export interface ILinkOpener { + open(resource: URI): boolean | Promise; +} + +/** + * Registers a handler that is called when a link is opened in any editor. The handler callback should return `true` if the link was handled and `false` otherwise. + * The handler that was registered last will be called first when a link is opened. + * + * Returns a disposable that can unregister the opener again. + */ +export function registerLinkOpener(opener: ILinkOpener): IDisposable { + const openerService = StandaloneServices.get(IOpenerService); + return openerService.registerOpener({ + async open(resource: string | URI) { + if (typeof resource === 'string') { + resource = URI.parse(resource); + } + return opener.open(resource); + } + }); +} + /** * @internal */ @@ -474,6 +498,8 @@ export function createMonacoEditorAPI(): typeof monaco.editor { remeasureFonts: remeasureFonts, registerCommand: registerCommand, + registerLinkOpener: registerLinkOpener, + // enums AccessibilitySupport: standaloneEnums.AccessibilitySupport, ContentWidgetPositionPreference: standaloneEnums.ContentWidgetPositionPreference, @@ -508,6 +534,7 @@ export function createMonacoEditorAPI(): typeof monaco.editor { LineRange: LineRange, LineRangeMapping: LineRangeMapping, RangeMapping: RangeMapping, + EditorZoom: EditorZoom, // vars EditorType: EditorType, diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 56f84726c98..23ad93ee7a1 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -24,6 +24,7 @@ import { IMarkerData, IMarkerService } from 'vs/platform/markers/common/markers' import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { LanguageSelector } from 'vs/editor/common/languageSelector'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { MetadataConsts } from 'vs/editor/common/encodedTokenAttributes'; /** * Register information about a new language. @@ -49,12 +50,30 @@ export function getEncodedLanguageId(languageId: string): number { } /** - * An event emitted when a language is needed for the first time (e.g. a model has it set). + * An event emitted when a language is associated for the first time with a text model. * @event */ export function onLanguage(languageId: string, callback: () => void): IDisposable { const languageService = StandaloneServices.get(ILanguageService); - const disposable = languageService.onDidEncounterLanguage((encounteredLanguageId) => { + const disposable = languageService.onDidRequestRichLanguageFeatures((encounteredLanguageId) => { + if (encounteredLanguageId === languageId) { + // stop listening + disposable.dispose(); + // invoke actual listener + callback(); + } + }); + return disposable; +} + +/** + * An event emitted when a language is associated for the first time with a text model or + * whena language is encountered during the tokenization of another language. + * @event + */ +export function onLanguageEncountered(languageId: string, callback: () => void): IDisposable { + const languageService = StandaloneServices.get(ILanguageService); + const disposable = languageService.onDidRequestBasicLanguageFeatures((encounteredLanguageId) => { if (encounteredLanguageId === languageId) { // stop listening disposable.dispose(); @@ -80,7 +99,7 @@ export function setLanguageConfiguration(languageId: string, configuration: Lang /** * @internal */ -export class EncodedTokenizationSupportAdapter implements languages.ITokenizationSupport { +export class EncodedTokenizationSupportAdapter implements languages.ITokenizationSupport, IDisposable { private readonly _languageId: string; private readonly _actual: EncodedTokensProvider; @@ -90,6 +109,10 @@ export class EncodedTokenizationSupportAdapter implements languages.ITokenizatio this._actual = actual; } + dispose(): void { + // NOOP + } + public getInitialState(): languages.IState { return this._actual.getInitialState(); } @@ -110,7 +133,7 @@ export class EncodedTokenizationSupportAdapter implements languages.ITokenizatio /** * @internal */ -export class TokenizationSupportAdapter implements languages.ITokenizationSupport { +export class TokenizationSupportAdapter implements languages.ITokenizationSupport, IDisposable { constructor( private readonly _languageId: string, @@ -120,6 +143,10 @@ export class TokenizationSupportAdapter implements languages.ITokenizationSuppor ) { } + dispose(): void { + // NOOP + } + public getInitialState(): languages.IState { return this._actual.getInitialState(); } @@ -175,7 +202,7 @@ export class TokenizationSupportAdapter implements languages.ITokenizationSuppor let previousStartIndex: number = 0; for (let i = 0, len = tokens.length; i < len; i++) { const t = tokens[i]; - const metadata = tokenTheme.match(languageId, t.scopes); + const metadata = tokenTheme.match(languageId, t.scopes) | MetadataConsts.BALANCED_BRACKETS_MASK; if (resultLen > 0 && result[resultLen - 1] === metadata) { // same metadata continue; @@ -366,18 +393,16 @@ function createTokenizationSupportAdapter(languageId: string, provider: TokensPr * with a tokens provider set using `registerDocumentSemanticTokensProvider` or `registerDocumentRangeSemanticTokensProvider`. */ export function registerTokensProviderFactory(languageId: string, factory: TokensProviderFactory): IDisposable { - const adaptedFactory: languages.ITokenizationSupportFactory = { - createTokenizationSupport: async (): Promise => { - const result = await Promise.resolve(factory.create()); - if (!result) { - return null; - } - if (isATokensProvider(result)) { - return createTokenizationSupportAdapter(languageId, result); - } - return new MonarchTokenizer(StandaloneServices.get(ILanguageService), StandaloneServices.get(IStandaloneThemeService), languageId, compile(languageId, result), StandaloneServices.get(IConfigurationService)); + const adaptedFactory = new languages.LazyTokenizationSupport(async () => { + const result = await Promise.resolve(factory.create()); + if (!result) { + return null; } - }; + if (isATokensProvider(result)) { + return createTokenizationSupportAdapter(languageId, result); + } + return new MonarchTokenizer(StandaloneServices.get(ILanguageService), StandaloneServices.get(IStandaloneThemeService), languageId, compile(languageId, result), StandaloneServices.get(IConfigurationService)); + }); return languages.TokenizationRegistry.registerFactory(languageId, adaptedFactory); } @@ -715,6 +740,7 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages { register: register, getLanguages: getLanguages, onLanguage: onLanguage, + onLanguageEncountered: onLanguageEncountered, getEncodedLanguageId: getEncodedLanguageId, // provider methods diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index 3aeae6d6fc5..2f7eb0bc07a 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -8,6 +8,8 @@ import 'vs/editor/standalone/browser/standaloneCodeEditorService'; import 'vs/editor/standalone/browser/standaloneLayoutService'; import 'vs/platform/undoRedo/common/undoRedoService'; import 'vs/editor/common/services/languageFeatureDebounce'; +import 'vs/editor/common/services/semanticTokensStylingService'; +import 'vs/editor/common/services/languageFeaturesService'; import * as strings from 'vs/base/common/strings'; import * as dom from 'vs/base/browser/dom'; @@ -42,11 +44,10 @@ import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayo import { ILabelService, ResourceLabelFormatter, IFormatterChangeEvent, Verbosity } from 'vs/platform/label/common/label'; import { INotification, INotificationHandle, INotificationService, IPromptChoice, IPromptOptions, NoOpNotification, IStatusMessageOptions } from 'vs/platform/notification/common/notification'; import { IProgressRunner, IEditorProgressService, IProgressService, IProgress, IProgressCompositeOptions, IProgressDialogOptions, IProgressNotificationOptions, IProgressOptions, IProgressStep, IProgressWindowOptions } from 'vs/platform/progress/common/progress'; -import { ITelemetryInfo, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; -import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier, IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, IWorkspaceFoldersWillChangeEvent, WorkbenchState, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; +import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier, IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, IWorkspaceFoldersWillChangeEvent, WorkbenchState, WorkspaceFolder, STANDALONE_EDITOR_WORKSPACE_ID } from 'vs/platform/workspace/common/workspace'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { StandaloneServicesNLS } from 'vs/editor/common/standaloneStrings'; -import { ClassifiedEvent, StrictPropertyCheck, OmitMetadata, IGDPRProperty } from 'vs/platform/telemetry/common/gdprTypings'; import { basename } from 'vs/base/common/resources'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { ConsoleLogger, ILogService } from 'vs/platform/log/common/log'; @@ -84,12 +85,12 @@ import { MarkerService } from 'vs/platform/markers/common/markerService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { IStorageService, InMemoryStorageService } from 'vs/platform/storage/common/storage'; - -import 'vs/editor/common/services/languageFeaturesService'; import { DefaultConfiguration } from 'vs/platform/configuration/common/configurations'; import { WorkspaceEdit } from 'vs/editor/common/languages'; import { AudioCue, IAudioCueService, Sound } from 'vs/platform/audioCues/browser/audioCueService'; import { LogService } from 'vs/platform/log/common/logService'; +import { getEditorFeatures } from 'vs/editor/common/editorFeatures'; +import { onUnexpectedError } from 'vs/base/common/errors'; class SimpleModel implements IResolvedTextEditorModel { @@ -715,35 +716,17 @@ class StandaloneResourcePropertiesService implements ITextResourcePropertiesServ class StandaloneTelemetryService implements ITelemetryService { declare readonly _serviceBrand: undefined; - - public telemetryLevel = TelemetryLevel.NONE; - public sendErrorTelemetry = false; - - public setEnabled(value: boolean): void { - } - - public setExperimentProperty(name: string, value: string): void { - } - - public publicLog(eventName: string, data?: any): Promise { - return Promise.resolve(undefined); - } - - publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck) { - return this.publicLog(eventName, data as any); - } - - public publicLogError(eventName: string, data?: any): Promise { - return Promise.resolve(undefined); - } - - publicLogError2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck) { - return this.publicLogError(eventName, data as any); - } - - public getTelemetryInfo(): Promise { - throw new Error(`Not available`); - } + readonly telemetryLevel = TelemetryLevel.NONE; + readonly sessionId = 'someValue.sessionId'; + readonly machineId = 'someValue.machineId'; + readonly firstSessionDate = 'someValue.firstSessionDate'; + readonly sendErrorTelemetry = false; + setEnabled(): void { } + setExperimentProperty(): void { } + publicLog() { } + publicLog2() { } + publicLogError() { } + publicLogError2() { } } class StandaloneWorkspaceContextService implements IWorkspaceContextService { @@ -768,7 +751,7 @@ class StandaloneWorkspaceContextService implements IWorkspaceContextService { constructor() { const resource = URI.from({ scheme: StandaloneWorkspaceContextService.SCHEME, authority: 'model', path: '/' }); - this.workspace = { id: '4064f6ec-cb38-4ad0-af64-ee6467e63c82', folders: [new WorkspaceFolder({ uri: resource, name: '', index: 0 })] }; + this.workspace = { id: STANDALONE_EDITOR_WORKSPACE_ID, folders: [new WorkspaceFolder({ uri: resource, name: '', index: 0 })] }; } getCompleteWorkspace(): Promise { @@ -1125,6 +1108,16 @@ export module StandaloneServices { } } + // Instantiate all editor features + const editorFeatures = getEditorFeatures(); + for (const feature of editorFeatures) { + try { + instantiationService.createInstance(feature); + } catch (err) { + onUnexpectedError(err); + } + } + return instantiationService; } } diff --git a/src/vs/editor/standalone/browser/standaloneThemeService.ts b/src/vs/editor/standalone/browser/standaloneThemeService.ts index 669791cecee..ec49af70ece 100644 --- a/src/vs/editor/standalone/browser/standaloneThemeService.ts +++ b/src/vs/editor/standalone/browser/standaloneThemeService.ts @@ -274,18 +274,20 @@ export class StandaloneThemeService extends Disposable implements IStandaloneThe private _registerRegularEditorContainer(): IDisposable { if (!this._globalStyleElement) { - this._globalStyleElement = dom.createStyleSheet(); - this._globalStyleElement.className = 'monaco-colors'; - this._globalStyleElement.textContent = this._allCSS; + this._globalStyleElement = dom.createStyleSheet(undefined, style => { + style.className = 'monaco-colors'; + style.textContent = this._allCSS; + }); this._styleElements.push(this._globalStyleElement); } return Disposable.None; } private _registerShadowDomContainer(domNode: HTMLElement): IDisposable { - const styleElement = dom.createStyleSheet(domNode); - styleElement.className = 'monaco-colors'; - styleElement.textContent = this._allCSS; + const styleElement = dom.createStyleSheet(domNode, style => { + style.className = 'monaco-colors'; + style.textContent = this._allCSS; + }); this._styleElements.push(styleElement); return { dispose: () => { diff --git a/src/vs/editor/standalone/common/monarch/monarchLexer.ts b/src/vs/editor/standalone/common/monarch/monarchLexer.ts index e434e40917f..9c451c4690c 100644 --- a/src/vs/editor/standalone/common/monarch/monarchLexer.ts +++ b/src/vs/editor/standalone/common/monarch/monarchLexer.ts @@ -387,7 +387,7 @@ class MonarchModernTokensCollector implements IMonarchTokensCollector { export type ILoadStatus = { loaded: true } | { loaded: false; promise: Promise }; -export class MonarchTokenizer implements languages.ITokenizationSupport { +export class MonarchTokenizer implements languages.ITokenizationSupport, IDisposable { private readonly _languageService: ILanguageService; private readonly _standaloneThemeService: IStandaloneThemeService; @@ -422,7 +422,7 @@ export class MonarchTokenizer implements languages.ITokenizationSupport { } if (isOneOfMyEmbeddedModes) { emitting = true; - languages.TokenizationRegistry.fire([this._languageId]); + languages.TokenizationRegistry.handleChange([this._languageId]); emitting = false; } }); diff --git a/src/vs/editor/standalone/test/browser/standaloneLanguages.test.ts b/src/vs/editor/standalone/test/browser/standaloneLanguages.test.ts index dbb0ee675a8..b4a255004f6 100644 --- a/src/vs/editor/standalone/test/browser/standaloneLanguages.test.ts +++ b/src/vs/editor/standalone/test/browser/standaloneLanguages.test.ts @@ -160,8 +160,8 @@ suite('TokenizationSupport2Adapter', () => { new Token(0, 'bar', languageId), ], [ - 0, (0 << MetadataConsts.FOREGROUND_OFFSET), - 0, (1 << MetadataConsts.FOREGROUND_OFFSET) + 0, (0 << MetadataConsts.FOREGROUND_OFFSET) | MetadataConsts.BALANCED_BRACKETS_MASK, + 0, (1 << MetadataConsts.FOREGROUND_OFFSET) | MetadataConsts.BALANCED_BRACKETS_MASK ] ); }); @@ -179,9 +179,9 @@ suite('TokenizationSupport2Adapter', () => { new Token(5, 'foo', languageId), ], [ - 0, (0 << MetadataConsts.FOREGROUND_OFFSET), - 5, (1 << MetadataConsts.FOREGROUND_OFFSET), - 5, (2 << MetadataConsts.FOREGROUND_OFFSET) + 0, (0 << MetadataConsts.FOREGROUND_OFFSET) | MetadataConsts.BALANCED_BRACKETS_MASK, + 5, (1 << MetadataConsts.FOREGROUND_OFFSET) | MetadataConsts.BALANCED_BRACKETS_MASK, + 5, (2 << MetadataConsts.FOREGROUND_OFFSET) | MetadataConsts.BALANCED_BRACKETS_MASK ] ); }); diff --git a/src/vs/editor/test/browser/widget/codeEditorWidget.test.ts b/src/vs/editor/test/browser/widget/codeEditorWidget.test.ts index 7fa0217572a..43a058e3b74 100644 --- a/src/vs/editor/test/browser/widget/codeEditorWidget.test.ts +++ b/src/vs/editor/test/browser/widget/codeEditorWidget.test.ts @@ -41,7 +41,7 @@ suite('CodeEditorWidget', () => { invoked = true; })); - viewModel.model.setMode('testMode'); + viewModel.model.setLanguage('testMode'); assert.deepStrictEqual(invoked, true); @@ -55,7 +55,7 @@ suite('CodeEditorWidget', () => { const languageService = instantiationService.get(ILanguageService); const disposables = new DisposableStore(); disposables.add(languageService.registerLanguage({ id: 'testMode' })); - viewModel.model.setMode('testMode'); + viewModel.model.setLanguage('testMode'); let invoked = false; disposables.add(editor.onDidChangeModelLanguageConfiguration((e) => { diff --git a/src/vs/editor/test/common/diff/standardLinesDiffCompute.test.ts b/src/vs/editor/test/common/diff/standardLinesDiffCompute.test.ts deleted file mode 100644 index c2f6e8afe6e..00000000000 --- a/src/vs/editor/test/common/diff/standardLinesDiffCompute.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import { Range } from 'vs/editor/common/core/range'; -import { LineRangeMapping, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -import { lineRangeMappingFromRangeMappings, StandardLinesDiffComputer } from 'vs/editor/common/diff/standardLinesDiffComputer'; - -suite('standardLinesDiffCompute', () => { - test('1', () => { - assert.deepStrictEqual( - toJson( - lineRangeMappingFromRangeMappings([ - new RangeMapping(r([1, 1, 1, 1]), r([1, 1, 1, 2])), - ]) - ), - (["{[1,2)->[1,2)}"]) - ); - }); - - test('2', () => { - assert.deepStrictEqual( - toJson( - lineRangeMappingFromRangeMappings([ - new RangeMapping(r([1, 1, 1, 2]), r([1, 1, 1, 1])), - ]) - ), - (["{[1,2)->[1,2)}"]) - ); - }); - - test('3', () => { - assert.deepStrictEqual( - toJson( - lineRangeMappingFromRangeMappings([ - new RangeMapping(r([1, 1, 2, 1]), r([1, 1, 1, 1])), - ]) - ), - (["{[1,2)->[1,1)}"]) - ); - }); - - test('4', () => { - assert.deepStrictEqual( - toJson( - lineRangeMappingFromRangeMappings([ - new RangeMapping(r([1, 1, 1, 1]), r([1, 1, 2, 1])), - ]) - ), - (["{[1,1)->[1,2)}"]) - ); - }); - - test('Suboptimal Diff (needs improving)', () => { - const c = new StandardLinesDiffComputer(); - - const lines1 = - ` - FirstKeyword = BreakKeyword, - LastKeyword = StringKeyword, - FirstFutureReservedWord = ImplementsKeyword, - LastFutureReservedWord = YieldKeyword - } -`.split('\n'); - - const lines2 = - ` - FirstKeyword = BreakKeyword, - LastKeyword = StringKeyword, - FirstFutureReservedWord = ImplementsKeyword, - LastFutureReservedWord = YieldKeyword, - FirstTypeNode = TypeReference, - LastTypeNode = ArrayType - } -`.split('\n'); - - const diff = c.computeDiff(lines1, lines2, { maxComputationTimeMs: 1000, ignoreTrimWhitespace: false }); - - // TODO this diff should only have one inner, not two. - assert.deepStrictEqual( - toJsonWithDetails(diff.changes), - [ - { - main: "{[5,6)->[5,8)}", - inner: [ - "{[5,41 -> 5,41]->[5,41 -> 7,28]}" - ] - } - ] - ); - }); -}); - -function r(values: [startLineNumber: number, startColumn: number, endLineNumber: number, endColumn: number]): Range { - return new Range(values[0], values[1], values[2], values[3]); -} - -function toJson(mappings: LineRangeMapping[]): unknown { - return mappings.map(m => m.toString()); -} - -function toJsonWithDetails(mappings: LineRangeMapping[]): unknown { - return mappings.map(m => { - return { main: m.toString(), inner: m.innerChanges?.map(c => c.toString()) }; - }); -} diff --git a/src/vs/editor/test/common/model/bracketPairColorizer/combineTextEditInfos.test.ts b/src/vs/editor/test/common/model/bracketPairColorizer/combineTextEditInfos.test.ts index 20bd2a503f8..619d10d52ec 100644 --- a/src/vs/editor/test/common/model/bracketPairColorizer/combineTextEditInfos.test.ts +++ b/src/vs/editor/test/common/model/bracketPairColorizer/combineTextEditInfos.test.ts @@ -72,11 +72,7 @@ function getRandomEdit(textModel: TextModel, rangeOffsetStart: number, rng: Mers const lineCount = rng.nextIntRange(0, 3); const columnCount = rng.nextIntRange(0, 5); - return { - startOffset: positionToLength(textModel.getPositionAt(offsetStart)), - endOffset: positionToLength(textModel.getPositionAt(offsetEnd)), - newLength: toLength(lineCount, columnCount) - }; + return new TextEditInfo(positionToLength(textModel.getPositionAt(offsetStart)), positionToLength(textModel.getPositionAt(offsetEnd)), toLength(lineCount, columnCount)); } function toEdit(editInfo: TextEditInfo): ISingleEditOperation { diff --git a/src/vs/editor/test/common/model/model.modes.test.ts b/src/vs/editor/test/common/model/model.modes.test.ts index c6287828d6d..dfefb300423 100644 --- a/src/vs/editor/test/common/model/model.modes.test.ts +++ b/src/vs/editor/test/common/model/model.modes.test.ts @@ -19,9 +19,10 @@ suite('Editor Model - Model Modes 1', () => { let calledFor: string[] = []; - function checkAndClear(arr: string[]) { - assert.deepStrictEqual(calledFor, arr); + function getAndClear(): string[] { + const result = calledFor; calledFor = []; + return result; } const tokenizationSupport: languages.ITokenizationSupport = { @@ -57,98 +58,98 @@ suite('Editor Model - Model Modes 1', () => { test('model calls syntax highlighter 1', () => { thisModel.tokenization.forceTokenization(1); - checkAndClear(['1']); + assert.deepStrictEqual(getAndClear(), ['1']); }); test('model calls syntax highlighter 2', () => { thisModel.tokenization.forceTokenization(2); - checkAndClear(['1', '2']); + assert.deepStrictEqual(getAndClear(), ['1', '2']); thisModel.tokenization.forceTokenization(2); - checkAndClear([]); + assert.deepStrictEqual(getAndClear(), []); }); test('model caches states', () => { thisModel.tokenization.forceTokenization(1); - checkAndClear(['1']); + assert.deepStrictEqual(getAndClear(), ['1']); thisModel.tokenization.forceTokenization(2); - checkAndClear(['2']); + assert.deepStrictEqual(getAndClear(), ['2']); thisModel.tokenization.forceTokenization(3); - checkAndClear(['3']); + assert.deepStrictEqual(getAndClear(), ['3']); thisModel.tokenization.forceTokenization(4); - checkAndClear(['4']); + assert.deepStrictEqual(getAndClear(), ['4']); thisModel.tokenization.forceTokenization(5); - checkAndClear(['5']); + assert.deepStrictEqual(getAndClear(), ['5']); thisModel.tokenization.forceTokenization(5); - checkAndClear([]); + assert.deepStrictEqual(getAndClear(), []); }); test('model invalidates states for one line insert', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['1', '2', '3', '4', '5']); + assert.deepStrictEqual(getAndClear(), ['1', '2', '3', '4', '5']); thisModel.applyEdits([EditOperation.insert(new Position(1, 1), '-')]); thisModel.tokenization.forceTokenization(5); - checkAndClear(['-']); + assert.deepStrictEqual(getAndClear(), ['-']); thisModel.tokenization.forceTokenization(5); - checkAndClear([]); + assert.deepStrictEqual(getAndClear(), []); }); test('model invalidates states for many lines insert', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['1', '2', '3', '4', '5']); + assert.deepStrictEqual(getAndClear(), ['1', '2', '3', '4', '5']); thisModel.applyEdits([EditOperation.insert(new Position(1, 1), '0\n-\n+')]); assert.strictEqual(thisModel.getLineCount(), 7); thisModel.tokenization.forceTokenization(7); - checkAndClear(['0', '-', '+']); + assert.deepStrictEqual(getAndClear(), ['0', '-', '+']); thisModel.tokenization.forceTokenization(7); - checkAndClear([]); + assert.deepStrictEqual(getAndClear(), []); }); test('model invalidates states for one new line', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['1', '2', '3', '4', '5']); + assert.deepStrictEqual(getAndClear(), ['1', '2', '3', '4', '5']); thisModel.applyEdits([EditOperation.insert(new Position(1, 2), '\n')]); thisModel.applyEdits([EditOperation.insert(new Position(2, 1), 'a')]); thisModel.tokenization.forceTokenization(6); - checkAndClear(['1', 'a']); + assert.deepStrictEqual(getAndClear(), ['1', 'a']); }); test('model invalidates states for one line delete', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['1', '2', '3', '4', '5']); + assert.deepStrictEqual(getAndClear(), ['1', '2', '3', '4', '5']); thisModel.applyEdits([EditOperation.insert(new Position(1, 2), '-')]); thisModel.tokenization.forceTokenization(5); - checkAndClear(['1']); + assert.deepStrictEqual(getAndClear(), ['1']); thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 2))]); thisModel.tokenization.forceTokenization(5); - checkAndClear(['-']); + assert.deepStrictEqual(getAndClear(), ['-']); thisModel.tokenization.forceTokenization(5); - checkAndClear([]); + assert.deepStrictEqual(getAndClear(), []); }); test('model invalidates states for many lines delete', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['1', '2', '3', '4', '5']); + assert.deepStrictEqual(getAndClear(), ['1', '2', '3', '4', '5']); thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 3, 1))]); thisModel.tokenization.forceTokenization(3); - checkAndClear(['3']); + assert.deepStrictEqual(getAndClear(), ['3']); thisModel.tokenization.forceTokenization(3); - checkAndClear([]); + assert.deepStrictEqual(getAndClear(), []); }); }); @@ -172,9 +173,10 @@ suite('Editor Model - Model Modes 2', () => { let calledFor: string[] = []; - function checkAndClear(arr: string[]): void { - assert.deepStrictEqual(calledFor, arr); + function getAndClear(): string[] { + const actual = calledFor; calledFor = []; + return actual; } const tokenizationSupport: languages.ITokenizationSupport = { @@ -209,54 +211,54 @@ suite('Editor Model - Model Modes 2', () => { test('getTokensForInvalidLines one text insert', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + assert.deepStrictEqual(getAndClear(), ['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([EditOperation.insert(new Position(1, 6), '-')]); thisModel.tokenization.forceTokenization(5); - checkAndClear(['Line1-', 'Line2']); + assert.deepStrictEqual(getAndClear(), ['Line1-', 'Line2']); }); test('getTokensForInvalidLines two text insert', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + assert.deepStrictEqual(getAndClear(), ['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([ EditOperation.insert(new Position(1, 6), '-'), EditOperation.insert(new Position(3, 6), '-') ]); thisModel.tokenization.forceTokenization(5); - checkAndClear(['Line1-', 'Line2', 'Line3-', 'Line4']); + assert.deepStrictEqual(getAndClear(), ['Line1-', 'Line2', 'Line3-', 'Line4']); }); test('getTokensForInvalidLines one multi-line text insert, one small text insert', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + assert.deepStrictEqual(getAndClear(), ['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([EditOperation.insert(new Position(1, 6), '\nNew line\nAnother new line')]); thisModel.applyEdits([EditOperation.insert(new Position(5, 6), '-')]); thisModel.tokenization.forceTokenization(7); - checkAndClear(['Line1', 'New line', 'Another new line', 'Line2', 'Line3-', 'Line4']); + assert.deepStrictEqual(getAndClear(), ['Line1', 'New line', 'Another new line', 'Line2', 'Line3-', 'Line4']); }); test('getTokensForInvalidLines one delete text', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + assert.deepStrictEqual(getAndClear(), ['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 5))]); thisModel.tokenization.forceTokenization(5); - checkAndClear(['1', 'Line2']); + assert.deepStrictEqual(getAndClear(), ['1', 'Line2']); }); test('getTokensForInvalidLines one line delete text', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + assert.deepStrictEqual(getAndClear(), ['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 2, 1))]); thisModel.tokenization.forceTokenization(4); - checkAndClear(['Line2']); + assert.deepStrictEqual(getAndClear(), ['Line2']); }); test('getTokensForInvalidLines multiple lines delete text', () => { thisModel.tokenization.forceTokenization(5); - checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + assert.deepStrictEqual(getAndClear(), ['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 3, 3))]); thisModel.tokenization.forceTokenization(3); - checkAndClear(['ne3', 'Line4']); + assert.deepStrictEqual(getAndClear(), ['ne3', 'Line4']); }); }); diff --git a/src/vs/editor/test/common/model/textModelTokens.test.ts b/src/vs/editor/test/common/model/textModelTokens.test.ts new file mode 100644 index 00000000000..3bcabeba1e0 --- /dev/null +++ b/src/vs/editor/test/common/model/textModelTokens.test.ts @@ -0,0 +1,96 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; +import { RangePriorityQueueImpl } from 'vs/editor/common/model/textModelTokens'; + +suite('RangePriorityQueueImpl', () => { + + test('addRange', () => { + const ranges: OffsetRange[] = []; + + OffsetRange.addRange(new OffsetRange(0, 2), ranges); + OffsetRange.addRange(new OffsetRange(10, 13), ranges); + OffsetRange.addRange(new OffsetRange(20, 24), ranges); + + assert.deepStrictEqual( + ranges.map(r => r.toString()), + (['[0, 2)', '[10, 13)', '[20, 24)']) + ); + + OffsetRange.addRange(new OffsetRange(2, 10), ranges); + + assert.deepStrictEqual( + ranges.map(r => r.toString()), + (['[0, 13)', '[20, 24)']) + ); + + OffsetRange.addRange(new OffsetRange(14, 19), ranges); + + assert.deepStrictEqual( + ranges.map(r => r.toString()), + (['[0, 13)', '[14, 19)', '[20, 24)']) + ); + + OffsetRange.addRange(new OffsetRange(10, 22), ranges); + + assert.deepStrictEqual( + ranges.map(r => r.toString()), + (['[0, 24)']) + ); + + OffsetRange.addRange(new OffsetRange(-1, 29), ranges); + + assert.deepStrictEqual( + ranges.map(r => r.toString()), + (['[-1, 29)']) + ); + + OffsetRange.addRange(new OffsetRange(-10, -5), ranges); + + assert.deepStrictEqual( + ranges.map(r => r.toString()), + (['[-10, -5)', '[-1, 29)']) + ); + }); + + test('addRangeAndResize', () => { + const queue = new RangePriorityQueueImpl(); + + queue.addRange(new OffsetRange(0, 20)); + queue.addRange(new OffsetRange(100, 120)); + queue.addRange(new OffsetRange(200, 220)); + + // disjoint + queue.addRangeAndResize(new OffsetRange(25, 27), 0); + + assert.deepStrictEqual( + queue.getRanges().map(r => r.toString()), + (['[0, 20)', '[98, 118)', '[198, 218)']) + ); + + queue.addRangeAndResize(new OffsetRange(19, 20), 0); + + assert.deepStrictEqual( + queue.getRanges().map(r => r.toString()), + (['[0, 19)', '[97, 117)', '[197, 217)']) + ); + + queue.addRangeAndResize(new OffsetRange(19, 97), 0); + + assert.deepStrictEqual( + queue.getRanges().map(r => r.toString()), + (['[0, 39)', '[119, 139)']) + ); + + queue.addRangeAndResize(new OffsetRange(-1000, 1000), 0); + + assert.deepStrictEqual( + queue.getRanges().map(r => r.toString()), + ([]) + ); + }); +}); diff --git a/src/vs/editor/test/common/model/textModelWithTokens.test.ts b/src/vs/editor/test/common/model/textModelWithTokens.test.ts index 39add3ef287..9406e15adf7 100644 --- a/src/vs/editor/test/common/model/textModelWithTokens.test.ts +++ b/src/vs/editor/test/common/model/textModelWithTokens.test.ts @@ -586,12 +586,12 @@ suite('TextModelWithTokens regression tests', () => { assertViewLineTokens(model, 1, true, [createViewLineToken(12, 1)]); assertViewLineTokens(model, 2, true, [createViewLineToken(9, 1)]); - model.setMode(LANG_ID1); + model.setLanguage(LANG_ID1); assertViewLineTokens(model, 1, true, [createViewLineToken(12, 11)]); assertViewLineTokens(model, 2, true, [createViewLineToken(9, 12)]); - model.setMode(LANG_ID2); + model.setLanguage(LANG_ID2); assertViewLineTokens(model, 1, false, [createViewLineToken(12, 1)]); assertViewLineTokens(model, 2, false, [createViewLineToken(9, 1)]); diff --git a/src/vs/editor/test/common/modes/linkComputer.test.ts b/src/vs/editor/test/common/modes/linkComputer.test.ts index 0b6e6bb7cf4..4ddf17ba95a 100644 --- a/src/vs/editor/test/common/modes/linkComputer.test.ts +++ b/src/vs/editor/test/common/modes/linkComputer.test.ts @@ -26,29 +26,38 @@ function myComputeLinks(lines: string[]): ILink[] { return computeLinks(target); } -function extractLinks(text: string): string { - const keep: boolean[] = []; - const links = myComputeLinks([text]); - for (const link of links) { - const startChar = link.range.startColumn - 1; - const endChar = link.range.endColumn - 1; - for (let char = startChar; char < endChar; char++) { - keep[char] = true; - } - } - const result: string[] = []; - for (let i = 0; i < text.length; i++) { - if (keep[i]) { - result.push(text.charAt(i)); - } else { - result.push(' '); - } - } - return result.join(''); -} +function assertLink(text: string, extractedLink: string): void { + let startColumn = 0, + endColumn = 0, + chr: string, + i = 0; -function assertLink(text: string, expectedLinks: string): void { - assert.deepStrictEqual(extractLinks(text), expectedLinks); + for (i = 0; i < extractedLink.length; i++) { + chr = extractedLink.charAt(i); + if (chr !== ' ' && chr !== '\t') { + startColumn = i + 1; + break; + } + } + + for (i = extractedLink.length - 1; i >= 0; i--) { + chr = extractedLink.charAt(i); + if (chr !== ' ' && chr !== '\t') { + endColumn = i + 2; + break; + } + } + + const r = myComputeLinks([text]); + assert.deepStrictEqual(r, [{ + range: { + startLineNumber: 1, + startColumn: startColumn, + endLineNumber: 1, + endColumn: endColumn + }, + url: extractedLink.substring(startColumn - 1, endColumn - 1) + }]); } suite('Editor Modes - Link Computer', () => { @@ -97,19 +106,19 @@ suite('Editor Modes - Link Computer', () => { assertLink( '(see http://foo.bar)', - ' http://foo.bar ' + ' http://foo.bar ' ); assertLink( '[see http://foo.bar]', - ' http://foo.bar ' + ' http://foo.bar ' ); assertLink( '{see http://foo.bar}', - ' http://foo.bar ' + ' http://foo.bar ' ); assertLink( '', - ' http://foo.bar ' + ' http://foo.bar ' ); assertLink( 'http://mylink.com', @@ -190,7 +199,7 @@ suite('Editor Modes - Link Computer', () => { test('issue #62278: "Ctrl + click to follow link" for IPv6 URLs', () => { assertLink( 'let x = "http://[::1]:5000/connect/token"', - ' http://[::1]:5000/connect/token ' + ' http://[::1]:5000/connect/token ' ); }); @@ -264,15 +273,4 @@ suite('Editor Modes - Link Computer', () => { ` https://github.com/jeff-hykin/better-c-syntax/blob/master/autogenerated/c.tmLanguage.json `, ); }); - - test('issue #119696: Links shouldn\'t include commas', () => { - assertLink( - `https://apod.nasa.gov/apod/ap170720.html,IC 1396: Emission Nebula in Cepheus,https://apod.nasa.gov/apod/image/1707/MOSAIC_IC1396_HaSHO_blanco1024.jpg,https://apod.nasa.gov/apod/image/1707/MOSAIC_IC1396_HaSHO_blanco.jpg`, - `https://apod.nasa.gov/apod/ap170720.html https://apod.nasa.gov/apod/image/1707/MOSAIC_IC1396_HaSHO_blanco1024.jpg https://apod.nasa.gov/apod/image/1707/MOSAIC_IC1396_HaSHO_blanco.jpg` - ); - assertLink( - `https://apod.nasa.gov/apod/ap180402.html,"Moons, Rings, Shadows, Clouds: Saturn (Cassini)",https://apod.nasa.gov/apod/image/1804/SaturnRingsMoons_Cassini_967.jpg,https://apod.nasa.gov/apod/image/1804/SaturnRingsMoons_Cassini_967.jpg`, - `https://apod.nasa.gov/apod/ap180402.html https://apod.nasa.gov/apod/image/1804/SaturnRingsMoons_Cassini_967.jpg https://apod.nasa.gov/apod/image/1804/SaturnRingsMoons_Cassini_967.jpg`, - ); - }); }); diff --git a/src/vs/editor/test/common/services/editorSimpleWorker.test.ts b/src/vs/editor/test/common/services/editorSimpleWorker.test.ts index d47496fad22..5236d20e271 100644 --- a/src/vs/editor/test/common/services/editorSimpleWorker.test.ts +++ b/src/vs/editor/test/common/services/editorSimpleWorker.test.ts @@ -88,7 +88,7 @@ suite('EditorSimpleWorker', () => { test('MoreMinimal', () => { - return worker.computeMoreMinimalEdits(model.uri.toString(), [{ text: 'This is line One', range: new Range(1, 1, 1, 17) }]).then(edits => { + return worker.computeMoreMinimalEdits(model.uri.toString(), [{ text: 'This is line One', range: new Range(1, 1, 1, 17) }], false).then(edits => { assert.strictEqual(edits.length, 1); const [first] = edits; assert.strictEqual(first.text, 'O'); @@ -104,7 +104,7 @@ suite('EditorSimpleWorker', () => { '}' ], '\n'); - return worker.computeMoreMinimalEdits(model.uri.toString(), [{ text: '{\r\n\t"a":1\r\n}', range: new Range(1, 1, 3, 2) }]).then(edits => { + return worker.computeMoreMinimalEdits(model.uri.toString(), [{ text: '{\r\n\t"a":1\r\n}', range: new Range(1, 1, 3, 2) }], false).then(edits => { assert.strictEqual(edits.length, 0); }); }); @@ -117,7 +117,7 @@ suite('EditorSimpleWorker', () => { '}' ], '\n'); - return worker.computeMoreMinimalEdits(model.uri.toString(), [{ text: '{\r\n\t"b":1\r\n}', range: new Range(1, 1, 3, 2) }]).then(edits => { + return worker.computeMoreMinimalEdits(model.uri.toString(), [{ text: '{\r\n\t"b":1\r\n}', range: new Range(1, 1, 3, 2) }], false).then(edits => { assert.strictEqual(edits.length, 1); const [first] = edits; assert.strictEqual(first.text, 'b'); @@ -125,7 +125,7 @@ suite('EditorSimpleWorker', () => { }); }); - test('MoreMinimal, issue #15385 newline changes and other', function () { + test('MoreMinimal, issue #15385 newline changes and other 2/2', function () { const model = worker.addModel([ 'package main', // 1 @@ -133,7 +133,7 @@ suite('EditorSimpleWorker', () => { '}' // 3 ]); - return worker.computeMoreMinimalEdits(model.uri.toString(), [{ text: '\n', range: new Range(3, 2, 4, 1000) }]).then(edits => { + return worker.computeMoreMinimalEdits(model.uri.toString(), [{ text: '\n', range: new Range(3, 2, 4, 1000) }], false).then(edits => { assert.strictEqual(edits.length, 1); const [first] = edits; assert.strictEqual(first.text, '\n'); diff --git a/src/vs/editor/test/common/services/modelService.test.ts b/src/vs/editor/test/common/services/modelService.test.ts index 04fa4cc1362..07c303ba1b1 100644 --- a/src/vs/editor/test/common/services/modelService.test.ts +++ b/src/vs/editor/test/common/services/modelService.test.ts @@ -5,38 +5,19 @@ import * as assert from 'assert'; import { CharCode } from 'vs/base/common/charCode'; -import { Emitter, Event } from 'vs/base/common/event'; import * as platform from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { StringBuilder } from 'vs/editor/common/core/stringBuilder'; -import { DefaultEndOfLine, ITextModel } from 'vs/editor/common/model'; +import { DefaultEndOfLine } from 'vs/editor/common/model'; import { createTextBuffer } from 'vs/editor/common/model/textModel'; import { ModelService } from 'vs/editor/common/services/modelService'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; -import { TestColorTheme, TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; -import { NullLogService } from 'vs/platform/log/common/log'; -import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService'; -import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; -import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { createModelServices, createTextModel } from 'vs/editor/test/common/testTextModel'; import { DisposableStore } from 'vs/base/common/lifecycle'; -import { DocumentSemanticTokensProvider, SemanticTokens, SemanticTokensEdits, SemanticTokensLegend } from 'vs/editor/common/languages'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { Barrier, timeout } from 'vs/base/common/async'; -import { LanguageService } from 'vs/editor/common/services/languageService'; -import { ColorScheme } from 'vs/platform/theme/common/theme'; import { IModelService } from 'vs/editor/common/services/model'; -import { ILanguageService } from 'vs/editor/common/languages/language'; -import { TestTextResourcePropertiesService } from 'vs/editor/test/common/services/testTextResourcePropertiesService'; -import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; -import { getDocumentSemanticTokens, isSemanticTokens } from 'vs/editor/common/services/getSemanticTokens'; -import { LanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; -import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler'; -import { LanguageFeaturesService } from 'vs/editor/common/services/languageFeaturesService'; -import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; @@ -408,253 +389,6 @@ suite('ModelService', () => { }); }); -suite('ModelSemanticColoring', () => { - - const disposables = new DisposableStore(); - let modelService: IModelService; - let languageService: ILanguageService; - let languageFeaturesService: ILanguageFeaturesService; - - setup(() => { - const configService = new TestConfigurationService({ editor: { semanticHighlighting: true } }); - const themeService = new TestThemeService(); - themeService.setTheme(new TestColorTheme({}, ColorScheme.DARK, true)); - const logService = new NullLogService(); - languageFeaturesService = new LanguageFeaturesService(); - modelService = disposables.add(new ModelService( - configService, - new TestTextResourcePropertiesService(configService), - themeService, - logService, - new UndoRedoService(new TestDialogService(), new TestNotificationService()), - disposables.add(new LanguageService()), - new TestLanguageConfigurationService(), - new LanguageFeatureDebounceService(logService), - languageFeaturesService - )); - languageService = disposables.add(new LanguageService(false)); - }); - - teardown(() => { - disposables.clear(); - }); - - test('DocumentSemanticTokens should be fetched when the result is empty if there are pending changes', async () => { - await runWithFakedTimers({}, async () => { - - disposables.add(languageService.registerLanguage({ id: 'testMode' })); - - const inFirstCall = new Barrier(); - const delayFirstResult = new Barrier(); - const secondResultProvided = new Barrier(); - let callCount = 0; - - disposables.add(languageFeaturesService.documentSemanticTokensProvider.register('testMode', new class implements DocumentSemanticTokensProvider { - getLegend(): SemanticTokensLegend { - return { tokenTypes: ['class'], tokenModifiers: [] }; - } - async provideDocumentSemanticTokens(model: ITextModel, lastResultId: string | null, token: CancellationToken): Promise { - callCount++; - if (callCount === 1) { - assert.ok('called once'); - inFirstCall.open(); - await delayFirstResult.wait(); - await timeout(0); // wait for the simple scheduler to fire to check that we do actually get rescheduled - return null; - } - if (callCount === 2) { - assert.ok('called twice'); - secondResultProvided.open(); - return null; - } - assert.fail('Unexpected call'); - } - releaseDocumentSemanticTokens(resultId: string | undefined): void { - } - })); - - const textModel = disposables.add(modelService.createModel('Hello world', languageService.createById('testMode'))); - - // wait for the provider to be called - await inFirstCall.wait(); - - // the provider is now in the provide call - // change the text buffer while the provider is running - textModel.applyEdits([{ range: new Range(1, 1, 1, 1), text: 'x' }]); - - // let the provider finish its first result - delayFirstResult.open(); - - // we need to check that the provider is called again, even if it returns null - await secondResultProvided.wait(); - - // assert that it got called twice - assert.strictEqual(callCount, 2); - }); - }); - - test('issue #149412: VS Code hangs when bad semantic token data is received', async () => { - await runWithFakedTimers({}, async () => { - - disposables.add(languageService.registerLanguage({ id: 'testMode' })); - - let lastResult: SemanticTokens | SemanticTokensEdits | null = null; - - disposables.add(languageFeaturesService.documentSemanticTokensProvider.register('testMode', new class implements DocumentSemanticTokensProvider { - getLegend(): SemanticTokensLegend { - return { tokenTypes: ['class'], tokenModifiers: [] }; - } - async provideDocumentSemanticTokens(model: ITextModel, lastResultId: string | null, token: CancellationToken): Promise { - if (!lastResultId) { - // this is the first call - lastResult = { - resultId: '1', - data: new Uint32Array([4294967293, 0, 7, 16, 0, 1, 4, 3, 11, 1]) - }; - } else { - // this is the second call - lastResult = { - resultId: '2', - edits: [{ - start: 4294967276, - deleteCount: 0, - data: new Uint32Array([2, 0, 3, 11, 0]) - }] - }; - } - return lastResult; - } - releaseDocumentSemanticTokens(resultId: string | undefined): void { - } - })); - - const textModel = disposables.add(modelService.createModel('', languageService.createById('testMode'))); - - // wait for the semantic tokens to be fetched - await Event.toPromise(textModel.onDidChangeTokens); - assert.strictEqual(lastResult!.resultId, '1'); - - // edit the text - textModel.applyEdits([{ range: new Range(1, 1, 1, 1), text: 'foo' }]); - - // wait for the semantic tokens to be fetched again - await Event.toPromise(textModel.onDidChangeTokens); - assert.strictEqual(lastResult!.resultId, '2'); - }); - }); - - test('issue #161573: onDidChangeSemanticTokens doesn\'t consistently trigger provideDocumentSemanticTokens', async () => { - await runWithFakedTimers({}, async () => { - - disposables.add(languageService.registerLanguage({ id: 'testMode' })); - - const emitter = new Emitter(); - let requestCount = 0; - disposables.add(languageFeaturesService.documentSemanticTokensProvider.register('testMode', new class implements DocumentSemanticTokensProvider { - onDidChange = emitter.event; - getLegend(): SemanticTokensLegend { - return { tokenTypes: ['class'], tokenModifiers: [] }; - } - async provideDocumentSemanticTokens(model: ITextModel, lastResultId: string | null, token: CancellationToken): Promise { - requestCount++; - if (requestCount === 1) { - await timeout(1000); - // send a change event - emitter.fire(); - await timeout(1000); - return null; - } - return null; - } - releaseDocumentSemanticTokens(resultId: string | undefined): void { - } - })); - - disposables.add(modelService.createModel('', languageService.createById('testMode'))); - - await timeout(5000); - assert.deepStrictEqual(requestCount, 2); - }); - }); - - test('DocumentSemanticTokens should be pick the token provider with actual items', async () => { - await runWithFakedTimers({}, async () => { - - let callCount = 0; - disposables.add(languageService.registerLanguage({ id: 'testMode2' })); - disposables.add(languageFeaturesService.documentSemanticTokensProvider.register('testMode2', new class implements DocumentSemanticTokensProvider { - getLegend(): SemanticTokensLegend { - return { tokenTypes: ['class1'], tokenModifiers: [] }; - } - async provideDocumentSemanticTokens(model: ITextModel, lastResultId: string | null, token: CancellationToken): Promise { - callCount++; - // For a secondary request return a different value - if (lastResultId) { - return { - data: new Uint32Array([2, 1, 1, 1, 1, 0, 2, 1, 1, 1]) - }; - } - return { - resultId: '1', - data: new Uint32Array([0, 1, 1, 1, 1, 0, 2, 1, 1, 1]) - }; - } - releaseDocumentSemanticTokens(resultId: string | undefined): void { - } - })); - disposables.add(languageFeaturesService.documentSemanticTokensProvider.register('testMode2', new class implements DocumentSemanticTokensProvider { - getLegend(): SemanticTokensLegend { - return { tokenTypes: ['class2'], tokenModifiers: [] }; - } - async provideDocumentSemanticTokens(model: ITextModel, lastResultId: string | null, token: CancellationToken): Promise { - callCount++; - return null; - } - releaseDocumentSemanticTokens(resultId: string | undefined): void { - } - })); - - function toArr(arr: Uint32Array): number[] { - const result: number[] = []; - for (let i = 0; i < arr.length; i++) { - result[i] = arr[i]; - } - return result; - } - - const textModel = modelService.createModel('Hello world 2', languageService.createById('testMode2')); - try { - let result = await getDocumentSemanticTokens(languageFeaturesService.documentSemanticTokensProvider, textModel, null, null, CancellationToken.None); - assert.ok(result, `We should have tokens (1)`); - assert.ok(result.tokens, `Tokens are found from multiple providers (1)`); - assert.ok(isSemanticTokens(result.tokens), `Tokens are full (1)`); - assert.ok(result.tokens.resultId, `Token result id found from multiple providers (1)`); - assert.deepStrictEqual(toArr(result.tokens.data), [0, 1, 1, 1, 1, 0, 2, 1, 1, 1], `Token data returned for multiple providers (1)`); - assert.deepStrictEqual(callCount, 2, `Called both token providers (1)`); - assert.deepStrictEqual(result.provider.getLegend(), { tokenTypes: ['class1'], tokenModifiers: [] }, `Legend matches the tokens (1)`); - - // Make a second request. Make sure we get the secondary value - result = await getDocumentSemanticTokens(languageFeaturesService.documentSemanticTokensProvider, textModel, result.provider, result.tokens.resultId, CancellationToken.None); - assert.ok(result, `We should have tokens (2)`); - assert.ok(result.tokens, `Tokens are found from multiple providers (2)`); - assert.ok(isSemanticTokens(result.tokens), `Tokens are full (2)`); - assert.ok(!result.tokens.resultId, `Token result id found from multiple providers (2)`); - assert.deepStrictEqual(toArr(result.tokens.data), [2, 1, 1, 1, 1, 0, 2, 1, 1, 1], `Token data returned for multiple providers (2)`); - assert.deepStrictEqual(callCount, 4, `Called both token providers (2)`); - assert.deepStrictEqual(result.provider.getLegend(), { tokenTypes: ['class1'], tokenModifiers: [] }, `Legend matches the tokens (2)`); - } finally { - disposables.clear(); - - // Wait for scheduler to finish - await timeout(0); - - // Now dispose the text model - textModel.dispose(); - } - }); - }); -}); - function assertComputeEdits(lines1: string[], lines2: string[]): void { const model = createTextModel(lines1.join('\n')); const textBuffer = createTextBuffer(lines2.join('\n'), DefaultEndOfLine.LF).textBuffer; diff --git a/src/vs/editor/test/common/services/testEditorWorkerService.ts b/src/vs/editor/test/common/services/testEditorWorkerService.ts index a0fb8772d7f..640a3e4b596 100644 --- a/src/vs/editor/test/common/services/testEditorWorkerService.ts +++ b/src/vs/editor/test/common/services/testEditorWorkerService.ts @@ -20,6 +20,7 @@ export class TestEditorWorkerService implements IEditorWorkerService { canComputeDirtyDiff(original: URI, modified: URI): boolean { return false; } async computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise { return null; } async computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise { return undefined; } + async computeHumanReadableDiff(resource: URI, edits: TextEdit[] | null | undefined): Promise { return undefined; } canComputeWordRanges(resource: URI): boolean { return false; } async computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] } | null> { return null; } canNavigateValueSet(resource: URI): boolean { return false; } diff --git a/src/vs/editor/test/node/diffing/diffing.test.ts b/src/vs/editor/test/node/diffing/diffingFixture.test.ts similarity index 86% rename from src/vs/editor/test/node/diffing/diffing.test.ts rename to src/vs/editor/test/node/diffing/diffingFixture.test.ts index eafdd623421..831a64d243f 100644 --- a/src/vs/editor/test/node/diffing/diffing.test.ts +++ b/src/vs/editor/test/node/diffing/diffingFixture.test.ts @@ -24,16 +24,18 @@ suite('diff fixtures', () => { const firstFileName = files.find(f => f.startsWith('1.'))!; const secondFileName = files.find(f => f.startsWith('2.'))!; - const firstContentLines = readFileSync(join(folderPath, firstFileName), 'utf8').split(/\r\n|\r|\n/); - const secondContentLines = readFileSync(join(folderPath, secondFileName), 'utf8').split(/\r\n|\r|\n/); + const firstContent = readFileSync(join(folderPath, firstFileName), 'utf8').replaceAll('\r\n', '\n').replaceAll('\r', '\n'); + const firstContentLines = firstContent.split(/\n/); + const secondContent = readFileSync(join(folderPath, secondFileName), 'utf8').replaceAll('\r\n', '\n').replaceAll('\r', '\n'); + const secondContentLines = secondContent.split(/\n/); const diffingAlgo = diffingAlgoName === 'smart' ? new SmartLinesDiffComputer() : new StandardLinesDiffComputer(); const diff = diffingAlgo.computeDiff(firstContentLines, secondContentLines, { ignoreTrimWhitespace: false, maxComputationTimeMs: Number.MAX_SAFE_INTEGER }); const actualDiffingResult: DiffingResult = { - originalFileName: `./${firstFileName}`, - modifiedFileName: `./${secondFileName}`, + original: { content: firstContent, fileName: `./${firstFileName}` }, + modified: { content: secondContent, fileName: `./${secondFileName}` }, diffs: diff.changes.map(c => ({ originalRange: c.originalRange.toString(), modifiedRange: c.modifiedRange.toString(), @@ -88,6 +90,10 @@ suite('diff fixtures', () => { } } + test(`uiae`, () => { + runTest('subword', 'experimental'); + }); + for (const folder of folders) { for (const diffingAlgoName of ['smart', 'experimental'] as const) { test(`${folder}-${diffingAlgoName}`, () => { @@ -98,8 +104,8 @@ suite('diff fixtures', () => { }); interface DiffingResult { - originalFileName: string; - modifiedFileName: string; + original: { content: string; fileName: string }; + modified: { content: string; fileName: string }; diffs: IDetailedDiff[]; } diff --git a/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/experimental.expected.diff.json index c1238378e94..18845aa6ccd 100644 --- a/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { CompareResult } from 'vs/base/common/arrays';\nimport { autorun, derived } from 'vs/base/common/observable';\nimport { IModelDeltaDecoration, MinimapPosition, OverviewRulerLane } from 'vs/editor/common/model';\nimport { localize } from 'vs/nls';\nimport { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';\nimport { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';\nimport { applyObservableDecorations, join } from 'vs/workbench/contrib/mergeEditor/browser/utils';\nimport { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors';\nimport { CodeEditorView } from './codeEditorView';\n\nexport class ResultCodeEditorView extends CodeEditorView {\n\tprivate readonly decorations = derived('result.decorations', reader => {\n\t\tconst viewModel = this.viewModel.read(reader);\n\t\tif (!viewModel) {\n\t\t\treturn [];\n\t\t}\n\t\tconst model = viewModel.model;\n\t\tconst result = new Array();\n\n\t\tconst baseRangeWithStoreAndTouchingDiffs = join(\n\t\t\tmodel.modifiedBaseRanges.read(reader),\n\t\t\tmodel.resultDiffs.read(reader),\n\t\t\t(baseRange, diff) => baseRange.baseRange.touches(diff.inputRange)\n\t\t\t\t? CompareResult.neitherLessOrGreaterThan\n\t\t\t\t: LineRange.compareByStart(\n\t\t\t\t\tbaseRange.baseRange,\n\t\t\t\t\tdiff.inputRange\n\t\t\t\t)\n\t\t);\n\n\t\tconst activeModifiedBaseRange = viewModel.activeModifiedBaseRange.read(reader);\n\n\t\tfor (const m of baseRangeWithStoreAndTouchingDiffs) {\n\t\t\tconst modifiedBaseRange = m.left;\n\n\t\t\tif (modifiedBaseRange) {\n\t\t\t\tconst range = model.getRangeInResult(modifiedBaseRange.baseRange, reader).toInclusiveRange();\n\t\t\t\tif (range) {\n\t\t\t\t\tconst blockClassNames = ['merge-editor-block'];\n\t\t\t\t\tconst isHandled = model.isHandled(modifiedBaseRange).read(reader);\n\t\t\t\t\tif (isHandled) {\n\t\t\t\t\t\tblockClassNames.push('handled');\n\t\t\t\t\t}\n\t\t\t\t\tif (modifiedBaseRange === activeModifiedBaseRange) {\n\t\t\t\t\t\tblockClassNames.push('focused');\n\t\t\t\t\t}\n\t\t\t\t\tblockClassNames.push('result');\n\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\trange,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tisWholeLine: true,\n\t\t\t\t\t\t\tblockClassName: blockClassNames.join(' '),\n\t\t\t\t\t\t\tdescription: 'Result Diff',\n\t\t\t\t\t\t\tminimap: {\n\t\t\t\t\t\t\t\tposition: MinimapPosition.Gutter,\n\t\t\t\t\t\t\t\tcolor: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toverviewRuler: {\n\t\t\t\t\t\t\t\tposition: OverviewRulerLane.Center,\n\t\t\t\t\t\t\t\tcolor: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor },\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const diff of m.rights) {\n\t\t\t\tconst range = diff.outputRange.toInclusiveRange();\n\t\t\t\tif (range) {\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\trange,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclassName: `merge-editor-diff result`,\n\t\t\t\t\t\t\tdescription: 'Merge Editor',\n\t\t\t\t\t\t\tisWholeLine: true,\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (diff.rangeMappings) {\n\t\t\t\t\tfor (const d of diff.rangeMappings) {\n\t\t\t\t\t\tresult.push({\n\t\t\t\t\t\t\trange: d.outputRange,\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tclassName: `merge-editor-diff-word result`,\n\t\t\t\t\t\t\t\tdescription: 'Merge Editor'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t});\n\n\tconstructor(\n\t\t@IInstantiationService instantiationService: IInstantiationService\n\t) {\n\t\tsuper(instantiationService);\n\n\t\tthis._register(applyObservableDecorations(this.editor, this.decorations));\n\n\n\t\tthis._register(autorun('update remainingConflicts label', reader => {\n\t\t\tconst model = this.model.read(reader);\n\t\t\tif (!model) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst count = model.unhandledConflictsCount.read(reader);\n\n\t\t\tthis.htmlElements.detail.innerText = count === 1\n\t\t\t\t? localize(\n\t\t\t\t\t'mergeEditor.remainingConflicts',\n\t\t\t\t\t'{0} Conflict Remaining',\n\t\t\t\t\tcount\n\t\t\t\t)\n\t\t\t\t: localize(\n\t\t\t\t\t'mergeEditor.remainingConflict',\n\t\t\t\t\t'{0} Conflicts Remaining ',\n\t\t\t\t\tcount\n\t\t\t\t);\n\n\t\t}));\n\t}\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { CompareResult } from 'vs/base/common/arrays';\nimport { autorun, derived } from 'vs/base/common/observable';\nimport { IModelDeltaDecoration, MinimapPosition, OverviewRulerLane } from 'vs/editor/common/model';\nimport { localize } from 'vs/nls';\nimport { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';\nimport { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';\nimport { applyObservableDecorations, join } from 'vs/workbench/contrib/mergeEditor/browser/utils';\nimport { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors';\nimport { CodeEditorView } from './codeEditorView';\n\nexport class ResultCodeEditorView extends CodeEditorView {\n\tprivate readonly decorations = derived('result.decorations', reader => {\n\t\tconst viewModel = this.viewModel.read(reader);\n\t\tif (!viewModel) {\n\t\t\treturn [];\n\t\t}\n\t\tconst model = viewModel.model;\n\t\tconst result = new Array();\n\n\t\tconst baseRangeWithStoreAndTouchingDiffs = join(\n\t\t\tmodel.modifiedBaseRanges.read(reader),\n\t\t\tmodel.resultDiffs.read(reader),\n\t\t\t(baseRange, diff) => baseRange.baseRange.touches(diff.inputRange)\n\t\t\t\t? CompareResult.neitherLessOrGreaterThan\n\t\t\t\t: LineRange.compareByStart(\n\t\t\t\t\tbaseRange.baseRange,\n\t\t\t\t\tdiff.inputRange\n\t\t\t\t)\n\t\t);\n\n\t\tconst activeModifiedBaseRange = viewModel.activeModifiedBaseRange.read(reader);\n\n\t\tfor (const m of baseRangeWithStoreAndTouchingDiffs) {\n\t\t\tconst modifiedBaseRange = m.left;\n\n\t\t\tif (modifiedBaseRange) {\n\t\t\t\tconst range = model.getRangeInResult(modifiedBaseRange.baseRange, reader).toInclusiveRange();\n\t\t\t\tif (range) {\n\t\t\t\t\tconst blockClassNames = ['merge-editor-block'];\n\t\t\t\t\tconst isHandled = model.isHandled(modifiedBaseRange).read(reader);\n\t\t\t\t\tif (isHandled) {\n\t\t\t\t\t\tblockClassNames.push('handled');\n\t\t\t\t\t}\n\t\t\t\t\tif (modifiedBaseRange === activeModifiedBaseRange) {\n\t\t\t\t\t\tblockClassNames.push('focused');\n\t\t\t\t\t}\n\t\t\t\t\tblockClassNames.push('result');\n\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\trange,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tisWholeLine: true,\n\t\t\t\t\t\t\tblockClassName: blockClassNames.join(' '),\n\t\t\t\t\t\t\tdescription: 'Result Diff',\n\t\t\t\t\t\t\tminimap: {\n\t\t\t\t\t\t\t\tposition: MinimapPosition.Gutter,\n\t\t\t\t\t\t\t\tcolor: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toverviewRuler: {\n\t\t\t\t\t\t\t\tposition: OverviewRulerLane.Center,\n\t\t\t\t\t\t\t\tcolor: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor },\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tif (!modifiedBaseRange || modifiedBaseRange.isConflicting) {\n\t\t\t\tfor (const diff of m.rights) {\n\t\t\t\t\tconst range = diff.outputRange.toInclusiveRange();\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\tresult.push({\n\t\t\t\t\t\t\trange,\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tclassName: `merge-editor-diff result`,\n\t\t\t\t\t\t\t\tdescription: 'Merge Editor',\n\t\t\t\t\t\t\t\tisWholeLine: true,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (diff.rangeMappings) {\n\t\t\t\t\t\tfor (const d of diff.rangeMappings) {\n\t\t\t\t\t\t\tresult.push({\n\t\t\t\t\t\t\t\trange: d.outputRange,\n\t\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\t\tclassName: `merge-editor-diff-word result`,\n\t\t\t\t\t\t\t\t\tdescription: 'Merge Editor'\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t});\n\n\tconstructor(\n\t\t@IInstantiationService instantiationService: IInstantiationService\n\t) {\n\t\tsuper(instantiationService);\n\n\t\tthis._register(applyObservableDecorations(this.editor, this.decorations));\n\n\n\t\tthis._register(autorun('update remainingConflicts label', reader => {\n\t\t\tconst model = this.model.read(reader);\n\t\t\tif (!model) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst count = model.unhandledConflictsCount.read(reader);\n\n\t\t\tthis.htmlElements.detail.innerText = count === 1\n\t\t\t\t? localize(\n\t\t\t\t\t'mergeEditor.remainingConflicts',\n\t\t\t\t\t'{0} Conflict Remaining',\n\t\t\t\t\tcount\n\t\t\t\t)\n\t\t\t\t: localize(\n\t\t\t\t\t'mergeEditor.remainingConflict',\n\t\t\t\t\t'{0} Conflicts Remaining ',\n\t\t\t\t\tcount\n\t\t\t\t);\n\n\t\t}));\n\t}\n}\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[73,85)", diff --git a/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/smart.expected.diff.json index 17dd9daa899..79632981113 100644 --- a/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/bracket-aligning/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { CompareResult } from 'vs/base/common/arrays';\nimport { autorun, derived } from 'vs/base/common/observable';\nimport { IModelDeltaDecoration, MinimapPosition, OverviewRulerLane } from 'vs/editor/common/model';\nimport { localize } from 'vs/nls';\nimport { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';\nimport { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';\nimport { applyObservableDecorations, join } from 'vs/workbench/contrib/mergeEditor/browser/utils';\nimport { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors';\nimport { CodeEditorView } from './codeEditorView';\n\nexport class ResultCodeEditorView extends CodeEditorView {\n\tprivate readonly decorations = derived('result.decorations', reader => {\n\t\tconst viewModel = this.viewModel.read(reader);\n\t\tif (!viewModel) {\n\t\t\treturn [];\n\t\t}\n\t\tconst model = viewModel.model;\n\t\tconst result = new Array();\n\n\t\tconst baseRangeWithStoreAndTouchingDiffs = join(\n\t\t\tmodel.modifiedBaseRanges.read(reader),\n\t\t\tmodel.resultDiffs.read(reader),\n\t\t\t(baseRange, diff) => baseRange.baseRange.touches(diff.inputRange)\n\t\t\t\t? CompareResult.neitherLessOrGreaterThan\n\t\t\t\t: LineRange.compareByStart(\n\t\t\t\t\tbaseRange.baseRange,\n\t\t\t\t\tdiff.inputRange\n\t\t\t\t)\n\t\t);\n\n\t\tconst activeModifiedBaseRange = viewModel.activeModifiedBaseRange.read(reader);\n\n\t\tfor (const m of baseRangeWithStoreAndTouchingDiffs) {\n\t\t\tconst modifiedBaseRange = m.left;\n\n\t\t\tif (modifiedBaseRange) {\n\t\t\t\tconst range = model.getRangeInResult(modifiedBaseRange.baseRange, reader).toInclusiveRange();\n\t\t\t\tif (range) {\n\t\t\t\t\tconst blockClassNames = ['merge-editor-block'];\n\t\t\t\t\tconst isHandled = model.isHandled(modifiedBaseRange).read(reader);\n\t\t\t\t\tif (isHandled) {\n\t\t\t\t\t\tblockClassNames.push('handled');\n\t\t\t\t\t}\n\t\t\t\t\tif (modifiedBaseRange === activeModifiedBaseRange) {\n\t\t\t\t\t\tblockClassNames.push('focused');\n\t\t\t\t\t}\n\t\t\t\t\tblockClassNames.push('result');\n\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\trange,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tisWholeLine: true,\n\t\t\t\t\t\t\tblockClassName: blockClassNames.join(' '),\n\t\t\t\t\t\t\tdescription: 'Result Diff',\n\t\t\t\t\t\t\tminimap: {\n\t\t\t\t\t\t\t\tposition: MinimapPosition.Gutter,\n\t\t\t\t\t\t\t\tcolor: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toverviewRuler: {\n\t\t\t\t\t\t\t\tposition: OverviewRulerLane.Center,\n\t\t\t\t\t\t\t\tcolor: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor },\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const diff of m.rights) {\n\t\t\t\tconst range = diff.outputRange.toInclusiveRange();\n\t\t\t\tif (range) {\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\trange,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclassName: `merge-editor-diff result`,\n\t\t\t\t\t\t\tdescription: 'Merge Editor',\n\t\t\t\t\t\t\tisWholeLine: true,\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (diff.rangeMappings) {\n\t\t\t\t\tfor (const d of diff.rangeMappings) {\n\t\t\t\t\t\tresult.push({\n\t\t\t\t\t\t\trange: d.outputRange,\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tclassName: `merge-editor-diff-word result`,\n\t\t\t\t\t\t\t\tdescription: 'Merge Editor'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t});\n\n\tconstructor(\n\t\t@IInstantiationService instantiationService: IInstantiationService\n\t) {\n\t\tsuper(instantiationService);\n\n\t\tthis._register(applyObservableDecorations(this.editor, this.decorations));\n\n\n\t\tthis._register(autorun('update remainingConflicts label', reader => {\n\t\t\tconst model = this.model.read(reader);\n\t\t\tif (!model) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst count = model.unhandledConflictsCount.read(reader);\n\n\t\t\tthis.htmlElements.detail.innerText = count === 1\n\t\t\t\t? localize(\n\t\t\t\t\t'mergeEditor.remainingConflicts',\n\t\t\t\t\t'{0} Conflict Remaining',\n\t\t\t\t\tcount\n\t\t\t\t)\n\t\t\t\t: localize(\n\t\t\t\t\t'mergeEditor.remainingConflict',\n\t\t\t\t\t'{0} Conflicts Remaining ',\n\t\t\t\t\tcount\n\t\t\t\t);\n\n\t\t}));\n\t}\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { CompareResult } from 'vs/base/common/arrays';\nimport { autorun, derived } from 'vs/base/common/observable';\nimport { IModelDeltaDecoration, MinimapPosition, OverviewRulerLane } from 'vs/editor/common/model';\nimport { localize } from 'vs/nls';\nimport { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';\nimport { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';\nimport { applyObservableDecorations, join } from 'vs/workbench/contrib/mergeEditor/browser/utils';\nimport { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors';\nimport { CodeEditorView } from './codeEditorView';\n\nexport class ResultCodeEditorView extends CodeEditorView {\n\tprivate readonly decorations = derived('result.decorations', reader => {\n\t\tconst viewModel = this.viewModel.read(reader);\n\t\tif (!viewModel) {\n\t\t\treturn [];\n\t\t}\n\t\tconst model = viewModel.model;\n\t\tconst result = new Array();\n\n\t\tconst baseRangeWithStoreAndTouchingDiffs = join(\n\t\t\tmodel.modifiedBaseRanges.read(reader),\n\t\t\tmodel.resultDiffs.read(reader),\n\t\t\t(baseRange, diff) => baseRange.baseRange.touches(diff.inputRange)\n\t\t\t\t? CompareResult.neitherLessOrGreaterThan\n\t\t\t\t: LineRange.compareByStart(\n\t\t\t\t\tbaseRange.baseRange,\n\t\t\t\t\tdiff.inputRange\n\t\t\t\t)\n\t\t);\n\n\t\tconst activeModifiedBaseRange = viewModel.activeModifiedBaseRange.read(reader);\n\n\t\tfor (const m of baseRangeWithStoreAndTouchingDiffs) {\n\t\t\tconst modifiedBaseRange = m.left;\n\n\t\t\tif (modifiedBaseRange) {\n\t\t\t\tconst range = model.getRangeInResult(modifiedBaseRange.baseRange, reader).toInclusiveRange();\n\t\t\t\tif (range) {\n\t\t\t\t\tconst blockClassNames = ['merge-editor-block'];\n\t\t\t\t\tconst isHandled = model.isHandled(modifiedBaseRange).read(reader);\n\t\t\t\t\tif (isHandled) {\n\t\t\t\t\t\tblockClassNames.push('handled');\n\t\t\t\t\t}\n\t\t\t\t\tif (modifiedBaseRange === activeModifiedBaseRange) {\n\t\t\t\t\t\tblockClassNames.push('focused');\n\t\t\t\t\t}\n\t\t\t\t\tblockClassNames.push('result');\n\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\trange,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tisWholeLine: true,\n\t\t\t\t\t\t\tblockClassName: blockClassNames.join(' '),\n\t\t\t\t\t\t\tdescription: 'Result Diff',\n\t\t\t\t\t\t\tminimap: {\n\t\t\t\t\t\t\t\tposition: MinimapPosition.Gutter,\n\t\t\t\t\t\t\t\tcolor: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toverviewRuler: {\n\t\t\t\t\t\t\t\tposition: OverviewRulerLane.Center,\n\t\t\t\t\t\t\t\tcolor: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor },\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tif (!modifiedBaseRange || modifiedBaseRange.isConflicting) {\n\t\t\t\tfor (const diff of m.rights) {\n\t\t\t\t\tconst range = diff.outputRange.toInclusiveRange();\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\tresult.push({\n\t\t\t\t\t\t\trange,\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tclassName: `merge-editor-diff result`,\n\t\t\t\t\t\t\t\tdescription: 'Merge Editor',\n\t\t\t\t\t\t\t\tisWholeLine: true,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (diff.rangeMappings) {\n\t\t\t\t\t\tfor (const d of diff.rangeMappings) {\n\t\t\t\t\t\t\tresult.push({\n\t\t\t\t\t\t\t\trange: d.outputRange,\n\t\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\t\tclassName: `merge-editor-diff-word result`,\n\t\t\t\t\t\t\t\t\tdescription: 'Merge Editor'\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t});\n\n\tconstructor(\n\t\t@IInstantiationService instantiationService: IInstantiationService\n\t) {\n\t\tsuper(instantiationService);\n\n\t\tthis._register(applyObservableDecorations(this.editor, this.decorations));\n\n\n\t\tthis._register(autorun('update remainingConflicts label', reader => {\n\t\t\tconst model = this.model.read(reader);\n\t\t\tif (!model) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst count = model.unhandledConflictsCount.read(reader);\n\n\t\t\tthis.htmlElements.detail.innerText = count === 1\n\t\t\t\t? localize(\n\t\t\t\t\t'mergeEditor.remainingConflicts',\n\t\t\t\t\t'{0} Conflict Remaining',\n\t\t\t\t\tcount\n\t\t\t\t)\n\t\t\t\t: localize(\n\t\t\t\t\t'mergeEditor.remainingConflict',\n\t\t\t\t\t'{0} Conflicts Remaining ',\n\t\t\t\t\tcount\n\t\t\t\t);\n\n\t\t}));\n\t}\n}\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[73,85)", diff --git a/src/vs/editor/test/node/diffing/fixtures/class-replacement/1.tst b/src/vs/editor/test/node/diffing/fixtures/class-replacement/1.tst new file mode 100644 index 00000000000..0a33e795f61 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/class-replacement/1.tst @@ -0,0 +1,92 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as arrays from 'vs/base/common/arrays'; +import { IdleDeadline, runWhenIdle } from 'vs/base/common/async'; +import { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { setTimeout0 } from 'vs/base/common/platform'; +import { StopWatch } from 'vs/base/common/stopwatch'; +import { countEOL } from 'vs/editor/common/core/eolCounter'; +import { Position } from 'vs/editor/common/core/position'; +import { IRange } from 'vs/editor/common/core/range'; +import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; +import { EncodedTokenizationResult, IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/languages'; +import { nullTokenizeEncoded } from 'vs/editor/common/languages/nullTokenize'; +import { ITextModel } from 'vs/editor/common/model'; +import { TextModel } from 'vs/editor/common/model/textModel'; +import { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart'; +import { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents'; +import { ContiguousMultilineTokensBuilder } from 'vs/editor/common/tokens/contiguousMultilineTokensBuilder'; +import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; + +const enum Constants { + CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048 +} + +/** + * An array that avoids being sparse by always + * filling up unused indices with a default value. + */ +export class ContiguousGrowingArray { + + private _store: T[] = []; + + constructor( + private readonly _default: T + ) { } + + public get(index: number): T { + if (index < this._store.length) { + return this._store[index]; + } + return this._default; + } + + public set(index: number, value: T): void { + while (index >= this._store.length) { + this._store[this._store.length] = this._default; + } + this._store[index] = value; + } + + // TODO have `replace` instead of `delete` and `insert` + public delete(deleteIndex: number, deleteCount: number): void { + if (deleteCount === 0 || deleteIndex >= this._store.length) { + return; + } + this._store.splice(deleteIndex, deleteCount); + } + + public insert(insertIndex: number, insertCount: number): void { + if (insertCount === 0 || insertIndex >= this._store.length) { + return; + } + const arr: T[] = []; + for (let i = 0; i < insertCount; i++) { + arr[i] = this._default; + } + this._store = arrays.arrayInsert(this._store, insertIndex, arr); + } +} + +/** + * Stores the states at the start of each line and keeps track of which lines + * must be re-tokenized. Also uses state equality to quickly validate lines + * that don't need to be re-tokenized. + * + * For example, when typing on a line, the line gets marked as needing to be tokenized. + * Once the line is tokenized, the end state is checked for equality against the begin + * state of the next line. If the states are equal, tokenization doesn't need to run + * again over the rest of the file. If the states are not equal, the next line gets marked + * as needing to be tokenized. + */ +export class TokenizationStateStore { + requestTokens(startLineNumber: number, endLineNumberExclusive: number): void { + for (let lineNumber = startLineNumber; lineNumber < endLineNumberExclusive; lineNumber++) { + this._stateStore.markMustBeTokenized(lineNumber - 1); + } + } +} diff --git a/src/vs/editor/test/node/diffing/fixtures/class-replacement/2.tst b/src/vs/editor/test/node/diffing/fixtures/class-replacement/2.tst new file mode 100644 index 00000000000..7dce96cdbae --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/class-replacement/2.tst @@ -0,0 +1,60 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as arrays from 'vs/base/common/arrays'; +import { IdleDeadline, runWhenIdle } from 'vs/base/common/async'; +import { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { setTimeout0 } from 'vs/base/common/platform'; +import { StopWatch } from 'vs/base/common/stopwatch'; +import { countEOL } from 'vs/editor/common/core/eolCounter'; +import { Position } from 'vs/editor/common/core/position'; +import { IRange } from 'vs/editor/common/core/range'; +import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; +import { EncodedTokenizationResult, IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/languages'; +import { nullTokenizeEncoded } from 'vs/editor/common/languages/nullTokenize'; +import { ITextModel } from 'vs/editor/common/model'; +import { TextModel } from 'vs/editor/common/model/textModel'; +import { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart'; +import { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents'; +import { ContiguousMultilineTokensBuilder } from 'vs/editor/common/tokens/contiguousMultilineTokensBuilder'; +import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; + +const enum Constants { + CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048 +} + +export class TokenizationStateStore2 { + public invalidateEndState(lineNumber: number): void; + + public getEndState(lineNumber: number): IState; + + public setEndState(lineNumber: number, state: IState): boolean { } + + public getFirstInvalidEndStateLineNumber(): number | undefined { + } + + public applyEdits(range: IRange, eolCount: number): void { + } +} + +/** + * Stores the states at the start of each line and keeps track of which lines + * must be re-tokenized. Also uses state equality to quickly validate lines + * that don't need to be re-tokenized. + * + * For example, when typing on a line, the line gets marked as needing to be tokenized. + * Once the line is tokenized, the end state is checked for equality against the begin + * state of the next line. If the states are equal, tokenization doesn't need to run + * again over the rest of the file. If the states are not equal, the next line gets marked + * as needing to be tokenized. + */ +export class TokenizationStateStore { + requestTokens(startLineNumber: number, endLineNumberExclusive: number): void { + for (let lineNumber = startLineNumber; lineNumber < endLineNumberExclusive; lineNumber++) { + this._stateStore.markMustBeTokenized(lineNumber - 1); + } + } +} diff --git a/src/vs/editor/test/node/diffing/fixtures/class-replacement/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/class-replacement/experimental.expected.diff.json new file mode 100644 index 00000000000..c6bc1333002 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/class-replacement/experimental.expected.diff.json @@ -0,0 +1,78 @@ +{ + "original": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as arrays from 'vs/base/common/arrays';\nimport { IdleDeadline, runWhenIdle } from 'vs/base/common/async';\nimport { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors';\nimport { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';\nimport { setTimeout0 } from 'vs/base/common/platform';\nimport { StopWatch } from 'vs/base/common/stopwatch';\nimport { countEOL } from 'vs/editor/common/core/eolCounter';\nimport { Position } from 'vs/editor/common/core/position';\nimport { IRange } from 'vs/editor/common/core/range';\nimport { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes';\nimport { EncodedTokenizationResult, IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/languages';\nimport { nullTokenizeEncoded } from 'vs/editor/common/languages/nullTokenize';\nimport { ITextModel } from 'vs/editor/common/model';\nimport { TextModel } from 'vs/editor/common/model/textModel';\nimport { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart';\nimport { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents';\nimport { ContiguousMultilineTokensBuilder } from 'vs/editor/common/tokens/contiguousMultilineTokensBuilder';\nimport { LineTokens } from 'vs/editor/common/tokens/lineTokens';\n\nconst enum Constants {\n\tCHEAP_TOKENIZATION_LENGTH_LIMIT = 2048\n}\n\n/**\n * An array that avoids being sparse by always\n * filling up unused indices with a default value.\n */\nexport class ContiguousGrowingArray {\n\n\tprivate _store: T[] = [];\n\n\tconstructor(\n\t\tprivate readonly _default: T\n\t) { }\n\n\tpublic get(index: number): T {\n\t\tif (index < this._store.length) {\n\t\t\treturn this._store[index];\n\t\t}\n\t\treturn this._default;\n\t}\n\n\tpublic set(index: number, value: T): void {\n\t\twhile (index >= this._store.length) {\n\t\t\tthis._store[this._store.length] = this._default;\n\t\t}\n\t\tthis._store[index] = value;\n\t}\n\n\t// TODO have `replace` instead of `delete` and `insert`\n\tpublic delete(deleteIndex: number, deleteCount: number): void {\n\t\tif (deleteCount === 0 || deleteIndex >= this._store.length) {\n\t\t\treturn;\n\t\t}\n\t\tthis._store.splice(deleteIndex, deleteCount);\n\t}\n\n\tpublic insert(insertIndex: number, insertCount: number): void {\n\t\tif (insertCount === 0 || insertIndex >= this._store.length) {\n\t\t\treturn;\n\t\t}\n\t\tconst arr: T[] = [];\n\t\tfor (let i = 0; i < insertCount; i++) {\n\t\t\tarr[i] = this._default;\n\t\t}\n\t\tthis._store = arrays.arrayInsert(this._store, insertIndex, arr);\n\t}\n}\n\n/**\n * Stores the states at the start of each line and keeps track of which lines\n * must be re-tokenized. Also uses state equality to quickly validate lines\n * that don't need to be re-tokenized.\n *\n * For example, when typing on a line, the line gets marked as needing to be tokenized.\n * Once the line is tokenized, the end state is checked for equality against the begin\n * state of the next line. If the states are equal, tokenization doesn't need to run\n * again over the rest of the file. If the states are not equal, the next line gets marked\n * as needing to be tokenized.\n */\nexport class TokenizationStateStore {\n\trequestTokens(startLineNumber: number, endLineNumberExclusive: number): void {\n\t\tfor (let lineNumber = startLineNumber; lineNumber < endLineNumberExclusive; lineNumber++) {\n\t\t\tthis._stateStore.markMustBeTokenized(lineNumber - 1);\n\t\t}\n\t}\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as arrays from 'vs/base/common/arrays';\nimport { IdleDeadline, runWhenIdle } from 'vs/base/common/async';\nimport { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors';\nimport { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';\nimport { setTimeout0 } from 'vs/base/common/platform';\nimport { StopWatch } from 'vs/base/common/stopwatch';\nimport { countEOL } from 'vs/editor/common/core/eolCounter';\nimport { Position } from 'vs/editor/common/core/position';\nimport { IRange } from 'vs/editor/common/core/range';\nimport { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes';\nimport { EncodedTokenizationResult, IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/languages';\nimport { nullTokenizeEncoded } from 'vs/editor/common/languages/nullTokenize';\nimport { ITextModel } from 'vs/editor/common/model';\nimport { TextModel } from 'vs/editor/common/model/textModel';\nimport { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart';\nimport { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents';\nimport { ContiguousMultilineTokensBuilder } from 'vs/editor/common/tokens/contiguousMultilineTokensBuilder';\nimport { LineTokens } from 'vs/editor/common/tokens/lineTokens';\n\nconst enum Constants {\n\tCHEAP_TOKENIZATION_LENGTH_LIMIT = 2048\n}\n\nexport class TokenizationStateStore2 {\n\tpublic invalidateEndState(lineNumber: number): void;\n\n\tpublic getEndState(lineNumber: number): IState;\n\n\tpublic setEndState(lineNumber: number, state: IState): boolean { }\n\n\tpublic getFirstInvalidEndStateLineNumber(): number | undefined {\n\t}\n\n\tpublic applyEdits(range: IRange, eolCount: number): void {\n\t}\n}\n\n/**\n * Stores the states at the start of each line and keeps track of which lines\n * must be re-tokenized. Also uses state equality to quickly validate lines\n * that don't need to be re-tokenized.\n *\n * For example, when typing on a line, the line gets marked as needing to be tokenized.\n * Once the line is tokenized, the end state is checked for equality against the begin\n * state of the next line. If the states are equal, tokenization doesn't need to run\n * again over the rest of the file. If the states are not equal, the next line gets marked\n * as needing to be tokenized.\n */\nexport class TokenizationStateStore {\n\trequestTokens(startLineNumber: number, endLineNumberExclusive: number): void {\n\t\tfor (let lineNumber = startLineNumber; lineNumber < endLineNumberExclusive; lineNumber++) {\n\t\t\tthis._stateStore.markMustBeTokenized(lineNumber - 1);\n\t\t}\n\t}\n}\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[29,34)", + "modifiedRange": "[29,31)", + "innerChanges": [ + { + "originalRange": "[29,1 -> 33,1]", + "modifiedRange": "[29,1 -> 29,1]" + }, + { + "originalRange": "[33,14 -> 33,41]", + "modifiedRange": "[29,14 -> 30,54]" + } + ] + }, + { + "originalRange": "[35,36)", + "modifiedRange": "[32,33)", + "innerChanges": [ + { + "originalRange": "[35,2 -> 35,26]", + "modifiedRange": "[32,2 -> 32,48]" + } + ] + }, + { + "originalRange": "[37,40)", + "modifiedRange": "[34,35)", + "innerChanges": [ + { + "originalRange": "[37,2 -> 39,3]", + "modifiedRange": "[34,2 -> 34,64]" + } + ] + }, + { + "originalRange": "[41,46)", + "modifiedRange": "[36,37)", + "innerChanges": [ + { + "originalRange": "[41,9 -> 41,18]", + "modifiedRange": "[36,9 -> 36,44]" + }, + { + "originalRange": "[41,26 -> 42,34]", + "modifiedRange": "[36,52 -> 36,64]" + }, + { + "originalRange": "[43,1 -> 46,1]", + "modifiedRange": "[37,1 -> 37,1]" + } + ] + }, + { + "originalRange": "[48,72)", + "modifiedRange": "[39,40)", + "innerChanges": [ + { + "originalRange": "[48,9 -> 63,48]", + "modifiedRange": "[39,9 -> 39,43]" + }, + { + "originalRange": "[64,1 -> 72,1]", + "modifiedRange": "[40,1 -> 40,1]" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/class-replacement/experimental.human.diff.json b/src/vs/editor/test/node/diffing/fixtures/class-replacement/experimental.human.diff.json new file mode 100644 index 00000000000..9faf4e61a98 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/class-replacement/experimental.human.diff.json @@ -0,0 +1,16 @@ +{ + "originalFileName": "./1.tst", + "modifiedFileName": "./2.tst", + "diffs": [ + { + "originalRange": "[29,74)", + "modifiedRange": "[29,42)", + "innerChanges": [ + { + "originalRange": "[29,1 -> 74,1]", + "modifiedRange": "[29,1 -> 42,1]" + } + ] + } + ] +} diff --git a/src/vs/editor/test/node/diffing/fixtures/class-replacement/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/class-replacement/smart.expected.diff.json new file mode 100644 index 00000000000..ec12e5d7a02 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/class-replacement/smart.expected.diff.json @@ -0,0 +1,73 @@ +{ + "original": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as arrays from 'vs/base/common/arrays';\nimport { IdleDeadline, runWhenIdle } from 'vs/base/common/async';\nimport { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors';\nimport { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';\nimport { setTimeout0 } from 'vs/base/common/platform';\nimport { StopWatch } from 'vs/base/common/stopwatch';\nimport { countEOL } from 'vs/editor/common/core/eolCounter';\nimport { Position } from 'vs/editor/common/core/position';\nimport { IRange } from 'vs/editor/common/core/range';\nimport { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes';\nimport { EncodedTokenizationResult, IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/languages';\nimport { nullTokenizeEncoded } from 'vs/editor/common/languages/nullTokenize';\nimport { ITextModel } from 'vs/editor/common/model';\nimport { TextModel } from 'vs/editor/common/model/textModel';\nimport { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart';\nimport { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents';\nimport { ContiguousMultilineTokensBuilder } from 'vs/editor/common/tokens/contiguousMultilineTokensBuilder';\nimport { LineTokens } from 'vs/editor/common/tokens/lineTokens';\n\nconst enum Constants {\n\tCHEAP_TOKENIZATION_LENGTH_LIMIT = 2048\n}\n\n/**\n * An array that avoids being sparse by always\n * filling up unused indices with a default value.\n */\nexport class ContiguousGrowingArray {\n\n\tprivate _store: T[] = [];\n\n\tconstructor(\n\t\tprivate readonly _default: T\n\t) { }\n\n\tpublic get(index: number): T {\n\t\tif (index < this._store.length) {\n\t\t\treturn this._store[index];\n\t\t}\n\t\treturn this._default;\n\t}\n\n\tpublic set(index: number, value: T): void {\n\t\twhile (index >= this._store.length) {\n\t\t\tthis._store[this._store.length] = this._default;\n\t\t}\n\t\tthis._store[index] = value;\n\t}\n\n\t// TODO have `replace` instead of `delete` and `insert`\n\tpublic delete(deleteIndex: number, deleteCount: number): void {\n\t\tif (deleteCount === 0 || deleteIndex >= this._store.length) {\n\t\t\treturn;\n\t\t}\n\t\tthis._store.splice(deleteIndex, deleteCount);\n\t}\n\n\tpublic insert(insertIndex: number, insertCount: number): void {\n\t\tif (insertCount === 0 || insertIndex >= this._store.length) {\n\t\t\treturn;\n\t\t}\n\t\tconst arr: T[] = [];\n\t\tfor (let i = 0; i < insertCount; i++) {\n\t\t\tarr[i] = this._default;\n\t\t}\n\t\tthis._store = arrays.arrayInsert(this._store, insertIndex, arr);\n\t}\n}\n\n/**\n * Stores the states at the start of each line and keeps track of which lines\n * must be re-tokenized. Also uses state equality to quickly validate lines\n * that don't need to be re-tokenized.\n *\n * For example, when typing on a line, the line gets marked as needing to be tokenized.\n * Once the line is tokenized, the end state is checked for equality against the begin\n * state of the next line. If the states are equal, tokenization doesn't need to run\n * again over the rest of the file. If the states are not equal, the next line gets marked\n * as needing to be tokenized.\n */\nexport class TokenizationStateStore {\n\trequestTokens(startLineNumber: number, endLineNumberExclusive: number): void {\n\t\tfor (let lineNumber = startLineNumber; lineNumber < endLineNumberExclusive; lineNumber++) {\n\t\t\tthis._stateStore.markMustBeTokenized(lineNumber - 1);\n\t\t}\n\t}\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as arrays from 'vs/base/common/arrays';\nimport { IdleDeadline, runWhenIdle } from 'vs/base/common/async';\nimport { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors';\nimport { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';\nimport { setTimeout0 } from 'vs/base/common/platform';\nimport { StopWatch } from 'vs/base/common/stopwatch';\nimport { countEOL } from 'vs/editor/common/core/eolCounter';\nimport { Position } from 'vs/editor/common/core/position';\nimport { IRange } from 'vs/editor/common/core/range';\nimport { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes';\nimport { EncodedTokenizationResult, IBackgroundTokenizationStore, IBackgroundTokenizer, ILanguageIdCodec, IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/languages';\nimport { nullTokenizeEncoded } from 'vs/editor/common/languages/nullTokenize';\nimport { ITextModel } from 'vs/editor/common/model';\nimport { TextModel } from 'vs/editor/common/model/textModel';\nimport { TokenizationTextModelPart } from 'vs/editor/common/model/tokenizationTextModelPart';\nimport { IModelContentChangedEvent, IModelLanguageChangedEvent } from 'vs/editor/common/textModelEvents';\nimport { ContiguousMultilineTokensBuilder } from 'vs/editor/common/tokens/contiguousMultilineTokensBuilder';\nimport { LineTokens } from 'vs/editor/common/tokens/lineTokens';\n\nconst enum Constants {\n\tCHEAP_TOKENIZATION_LENGTH_LIMIT = 2048\n}\n\nexport class TokenizationStateStore2 {\n\tpublic invalidateEndState(lineNumber: number): void;\n\n\tpublic getEndState(lineNumber: number): IState;\n\n\tpublic setEndState(lineNumber: number, state: IState): boolean { }\n\n\tpublic getFirstInvalidEndStateLineNumber(): number | undefined {\n\t}\n\n\tpublic applyEdits(range: IRange, eolCount: number): void {\n\t}\n}\n\n/**\n * Stores the states at the start of each line and keeps track of which lines\n * must be re-tokenized. Also uses state equality to quickly validate lines\n * that don't need to be re-tokenized.\n *\n * For example, when typing on a line, the line gets marked as needing to be tokenized.\n * Once the line is tokenized, the end state is checked for equality against the begin\n * state of the next line. If the states are equal, tokenization doesn't need to run\n * again over the rest of the file. If the states are not equal, the next line gets marked\n * as needing to be tokenized.\n */\nexport class TokenizationStateStore {\n\trequestTokens(startLineNumber: number, endLineNumberExclusive: number): void {\n\t\tfor (let lineNumber = startLineNumber; lineNumber < endLineNumberExclusive; lineNumber++) {\n\t\t\tthis._stateStore.markMustBeTokenized(lineNumber - 1);\n\t\t}\n\t}\n}\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[29,34)", + "modifiedRange": "[29,31)", + "innerChanges": [ + { + "originalRange": "[29,1 -> 33,41]", + "modifiedRange": "[29,1 -> 30,54]" + } + ] + }, + { + "originalRange": "[35,36)", + "modifiedRange": "[32,33)", + "innerChanges": [ + { + "originalRange": "[35,3 -> 35,6]", + "modifiedRange": "[32,3 -> 32,17]" + }, + { + "originalRange": "[35,9 -> 35,26]", + "modifiedRange": "[32,20 -> 32,48]" + } + ] + }, + { + "originalRange": "[37,40)", + "modifiedRange": "[34,35)", + "innerChanges": [ + { + "originalRange": "[37,2 -> 38,7]", + "modifiedRange": "[34,2 -> 34,43]" + }, + { + "originalRange": "[38,10 -> 39,3]", + "modifiedRange": "[34,46 -> 34,64]" + } + ] + }, + { + "originalRange": "[41,46)", + "modifiedRange": "[36,37)", + "innerChanges": [ + { + "originalRange": "[41,12 -> 41,21]", + "modifiedRange": "[36,12 -> 36,37]" + }, + { + "originalRange": "[41,26 -> 41,26]", + "modifiedRange": "[36,42 -> 36,43]" + }, + { + "originalRange": "[41,29 -> 45,24]", + "modifiedRange": "[36,46 -> 36,66]" + } + ] + }, + { + "originalRange": "[48,72)", + "modifiedRange": "[39,40)", + "innerChanges": null + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/equals/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/equals/experimental.expected.diff.json index a4f5476baf2..5b8da09f932 100644 --- a/src/vs/editor/test/node/diffing/fixtures/equals/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/equals/experimental.expected.diff.json @@ -1,5 +1,11 @@ { - "originalFileName": "./1.txt", - "modifiedFileName": "./2.txt", + "original": { + "content": "hello\nworld", + "fileName": "./1.txt" + }, + "modified": { + "content": "hello\nworld", + "fileName": "./2.txt" + }, "diffs": [] } \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/equals/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/equals/smart.expected.diff.json index a4f5476baf2..5b8da09f932 100644 --- a/src/vs/editor/test/node/diffing/fixtures/equals/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/equals/smart.expected.diff.json @@ -1,5 +1,11 @@ { - "originalFileName": "./1.txt", - "modifiedFileName": "./2.txt", + "original": { + "content": "hello\nworld", + "fileName": "./1.txt" + }, + "modified": { + "content": "hello\nworld", + "fileName": "./2.txt" + }, "diffs": [] } \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/experimental.expected.diff.json index 52c3f93400f..ed6c0fe7ff1 100644 --- a/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.txt", - "modifiedFileName": "./2.txt", + "original": { + "content": "\nconsole.log(1)\nconsole.log(2)\nconsole.log(3)\nconsole.log(4)\nconsole.log(5)\nconsole.log(6)\nconsole.log(7)\n", + "fileName": "./1.txt" + }, + "modified": { + "content": "console.log(1);\nconsole.log(2);\nconsole.log(3);\nconsole.log(4);\n\nconsole.log(5);\nconsole.log(6);\nconsole.log(7);\n\n", + "fileName": "./2.txt" + }, "diffs": [ { "originalRange": "[1,1)", diff --git a/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/smart.expected.diff.json index 3a2b5cf1e02..f30b581bd3f 100644 --- a/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/fuzzy-matching/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.txt", - "modifiedFileName": "./2.txt", + "original": { + "content": "\nconsole.log(1)\nconsole.log(2)\nconsole.log(3)\nconsole.log(4)\nconsole.log(5)\nconsole.log(6)\nconsole.log(7)\n", + "fileName": "./1.txt" + }, + "modified": { + "content": "console.log(1);\nconsole.log(2);\nconsole.log(3);\nconsole.log(4);\n\nconsole.log(5);\nconsole.log(6);\nconsole.log(7);\n\n", + "fileName": "./2.txt" + }, "diffs": [ { "originalRange": "[1,1)", diff --git a/src/vs/editor/test/node/diffing/fixtures/indentation/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/indentation/experimental.expected.diff.json index 9eea9d215ec..2e7031437fa 100644 --- a/src/vs/editor/test/node/diffing/fixtures/indentation/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/indentation/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[]): LineRangeMapping[] {\n\tconst changes: LineRangeMapping[] = [];\n\tfor (const g of group(\n\t\talignments,\n\t\t(a1, a2) =>\n\t\t\t(a2.originalRange.startLineNumber - (a1.originalRange.endLineNumber - (a1.originalRange.endColumn > 1 ? 0 : 1)) <= 1)\n\t\t\t|| (a2.modifiedRange.startLineNumber - (a1.modifiedRange.endLineNumber - (a1.modifiedRange.endColumn > 1 ? 0 : 1)) <= 1)\n\t)) {\n\t\tconst first = g[0];\n\t\tconst last = g[g.length - 1];\n\n\t\tchanges.push(new LineRangeMapping(\n\t\t\tnew LineRange(\n\t\t\t\tfirst.originalRange.startLineNumber,\n\t\t\t\tlast.originalRange.endLineNumber + (last.originalRange.endColumn > 1 || last.modifiedRange.endColumn > 1 ? 1 : 0)\n\t\t\t),\n\t\t\tnew LineRange(\n\t\t\t\tfirst.modifiedRange.startLineNumber,\n\t\t\t\tlast.modifiedRange.endLineNumber + (last.originalRange.endColumn > 1 || last.modifiedRange.endColumn > 1 ? 1 : 0)\n\t\t\t),\n\t\t\tg\n\t\t));\n\t}\n\n\tassertFn(() => {\n\t\treturn checkAdjacentItems(changes,\n\t\t\t(m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive &&\n\t\t\t\t// There has to be an unchanged line in between (otherwise both diffs should have been joined)\n\t\t\t\tm1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber &&\n\t\t\t\tm1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber,\n\t\t);\n\t});\n\n\n\treturn changes;\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[]): LineRangeMapping[] {\n\tconst changes: LineRangeMapping[] = [];\n\tfor (const g of group(\n\t\talignments,\n\t\t(a1, a2) =>\n\t\t\t(a2.originalRange.startLineNumber - (a1.originalRange.endLineNumber - (a1.originalRange.endColumn > 1 ? 0 : 1)) <= 1)\n\t\t\t|| (a2.modifiedRange.startLineNumber - (a1.modifiedRange.endLineNumber - (a1.modifiedRange.endColumn > 1 ? 0 : 1)) <= 1)\n\t)) {\n\t\tif (true) {\n\t\t\tconst first = g[0];\n\t\t\tconst last = g[g.length - 1];\n\n\t\t\tchanges.push(new LineRangeMapping(\n\t\t\t\tnew LineRange(\n\t\t\t\t\tfirst.originalRange.startLineNumber,\n\t\t\t\t\tlast.originalRange.endLineNumber + (last.originalRange.endColumn > 1 || last.modifiedRange.endColumn > 1 ? 1 : 0)\n\t\t\t\t),\n\t\t\t\tnew LineRange(\n\t\t\t\t\tfirst.modifiedRange.startLineNumber,\n\t\t\t\t\tlast.modifiedRange.endLineNumber + (last.originalRange.endColumn > 1 || last.modifiedRange.endColumn > 1 ? 1 : 0)\n\t\t\t\t),\n\t\t\t\tg\n\t\t\t));\n\t\t}\n\t}\n\n\tassertFn(() => {\n\t\treturn checkAdjacentItems(changes,\n\t\t\t(m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive &&\n\t\t\t\t// There has to be an unchanged line in between (otherwise both diffs should have been joined)\n\t\t\t\tm1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber &&\n\t\t\t\tm1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber,\n\t\t);\n\t});\n\n\n\treturn changes;\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[9,11)", diff --git a/src/vs/editor/test/node/diffing/fixtures/indentation/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/indentation/smart.expected.diff.json index 1673eac315e..06d9414be5c 100644 --- a/src/vs/editor/test/node/diffing/fixtures/indentation/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/indentation/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[]): LineRangeMapping[] {\n\tconst changes: LineRangeMapping[] = [];\n\tfor (const g of group(\n\t\talignments,\n\t\t(a1, a2) =>\n\t\t\t(a2.originalRange.startLineNumber - (a1.originalRange.endLineNumber - (a1.originalRange.endColumn > 1 ? 0 : 1)) <= 1)\n\t\t\t|| (a2.modifiedRange.startLineNumber - (a1.modifiedRange.endLineNumber - (a1.modifiedRange.endColumn > 1 ? 0 : 1)) <= 1)\n\t)) {\n\t\tconst first = g[0];\n\t\tconst last = g[g.length - 1];\n\n\t\tchanges.push(new LineRangeMapping(\n\t\t\tnew LineRange(\n\t\t\t\tfirst.originalRange.startLineNumber,\n\t\t\t\tlast.originalRange.endLineNumber + (last.originalRange.endColumn > 1 || last.modifiedRange.endColumn > 1 ? 1 : 0)\n\t\t\t),\n\t\t\tnew LineRange(\n\t\t\t\tfirst.modifiedRange.startLineNumber,\n\t\t\t\tlast.modifiedRange.endLineNumber + (last.originalRange.endColumn > 1 || last.modifiedRange.endColumn > 1 ? 1 : 0)\n\t\t\t),\n\t\t\tg\n\t\t));\n\t}\n\n\tassertFn(() => {\n\t\treturn checkAdjacentItems(changes,\n\t\t\t(m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive &&\n\t\t\t\t// There has to be an unchanged line in between (otherwise both diffs should have been joined)\n\t\t\t\tm1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber &&\n\t\t\t\tm1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber,\n\t\t);\n\t});\n\n\n\treturn changes;\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[]): LineRangeMapping[] {\n\tconst changes: LineRangeMapping[] = [];\n\tfor (const g of group(\n\t\talignments,\n\t\t(a1, a2) =>\n\t\t\t(a2.originalRange.startLineNumber - (a1.originalRange.endLineNumber - (a1.originalRange.endColumn > 1 ? 0 : 1)) <= 1)\n\t\t\t|| (a2.modifiedRange.startLineNumber - (a1.modifiedRange.endLineNumber - (a1.modifiedRange.endColumn > 1 ? 0 : 1)) <= 1)\n\t)) {\n\t\tif (true) {\n\t\t\tconst first = g[0];\n\t\t\tconst last = g[g.length - 1];\n\n\t\t\tchanges.push(new LineRangeMapping(\n\t\t\t\tnew LineRange(\n\t\t\t\t\tfirst.originalRange.startLineNumber,\n\t\t\t\t\tlast.originalRange.endLineNumber + (last.originalRange.endColumn > 1 || last.modifiedRange.endColumn > 1 ? 1 : 0)\n\t\t\t\t),\n\t\t\t\tnew LineRange(\n\t\t\t\t\tfirst.modifiedRange.startLineNumber,\n\t\t\t\t\tlast.modifiedRange.endLineNumber + (last.originalRange.endColumn > 1 || last.modifiedRange.endColumn > 1 ? 1 : 0)\n\t\t\t\t),\n\t\t\t\tg\n\t\t\t));\n\t\t}\n\t}\n\n\tassertFn(() => {\n\t\treturn checkAdjacentItems(changes,\n\t\t\t(m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive &&\n\t\t\t\t// There has to be an unchanged line in between (otherwise both diffs should have been joined)\n\t\t\t\tm1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber &&\n\t\t\t\tm1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber,\n\t\t);\n\t});\n\n\n\treturn changes;\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[9,11)", diff --git a/src/vs/editor/test/node/diffing/fixtures/intra-block-align/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/intra-block-align/experimental.expected.diff.json index 7ac4028731d..84c7fde1881 100644 --- a/src/vs/editor/test/node/diffing/fixtures/intra-block-align/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/intra-block-align/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.txt", - "modifiedFileName": "./2.txt", + "original": { + "content": "console.log(1);\nconsole.log(2);\nconsole.log(3);\nconsole.log(4);\n", + "fileName": "./1.txt" + }, + "modified": { + "content": "console.log(1)\nconsole.log(2)\nconsole.log(4)\n", + "fileName": "./2.txt" + }, "diffs": [ { "originalRange": "[1,5)", diff --git a/src/vs/editor/test/node/diffing/fixtures/intra-block-align/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/intra-block-align/smart.expected.diff.json index 7ac4028731d..84c7fde1881 100644 --- a/src/vs/editor/test/node/diffing/fixtures/intra-block-align/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/intra-block-align/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.txt", - "modifiedFileName": "./2.txt", + "original": { + "content": "console.log(1);\nconsole.log(2);\nconsole.log(3);\nconsole.log(4);\n", + "fileName": "./1.txt" + }, + "modified": { + "content": "console.log(1)\nconsole.log(2)\nconsole.log(4)\n", + "fileName": "./2.txt" + }, "diffs": [ { "originalRange": "[1,5)", diff --git a/src/vs/editor/test/node/diffing/fixtures/json-brackets/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/json-brackets/experimental.expected.diff.json index 7e258364cfc..17ca1b5e92a 100644 --- a/src/vs/editor/test/node/diffing/fixtures/json-brackets/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/json-brackets/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.json", - "modifiedFileName": "./2.json", + "original": { + "content": "{\n\t\"editor\": [\n\t\t{\n\t\t\t\"name\": \"vs/platform\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/editor/contrib\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/editor\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/base\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t}\n\t],\n\t\"workbench\": [\n\t\t{\n\t\t\t\"name\": \"vs/code\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/api/common\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/bulkEdit\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/cli\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/codeEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/callHierarchy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/typeHierarchy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/codeActions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/comments\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/debug\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/dialogs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/emmet\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/experiments\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/extensions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/externalTerminal\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/feedback\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/files\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/html\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/issue\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/inlayHints\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/interactive\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/languageStatus\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/keybindings\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/markers\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/mergeEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/localization\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/logs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/output\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/performance\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/preferences\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/notebook\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/quickaccess\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userData\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/remote\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/relauncher\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/sash\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/scm\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/search\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/searchEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/snippets\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/format\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/tags\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/surveys\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/tasks\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/testing\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/terminal\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/themes\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/trust\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/update\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/url\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/watermark\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/webview\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/webviewPanel\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/workspace\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/workspaces\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/customEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/externalUriOpener\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeGettingStarted\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeOverlay\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomePage\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeViews\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeWalkthrough\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/outline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userDataSync\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/editSessions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/views\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/languageDetection\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/audioCues\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/deprecatedExtensionMigrator\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/offline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/actions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/authToken\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/backup\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/bulkEdit\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/clipboard\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/commands\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/configuration\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/configurationResolver\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/dialogs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/editor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensionManagement\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/files\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/history\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/log\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/integrity\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/keybinding\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/lifecycle\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/language\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/progress\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/remote\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/search\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/textfile\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/themes\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/textMate\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/workingCopy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/workspaces\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/decorations\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/label\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/preferences\",\n\t\t\t\"project\": \"vscode-preferences\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/notification\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userData\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userDataSync\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/editSessions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/views\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/timeline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/localHistory\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/authentication\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensionRecommendations\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/gettingStarted\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/host\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userDataProfile\",\n\t\t\t\"project\": \"vscode-profiles\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userDataProfile\",\n\t\t\t\"project\": \"vscode-profiles\"\n\t\t}\n\t]\n}\n", + "fileName": "./1.json" + }, + "modified": { + "content": "{\n\t\"editor\": [\n\t\t{\n\t\t\t\"name\": \"vs/platform\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/editor/contrib\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/editor\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/base\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t}\n\t],\n\t\"workbench\": [\n\t\t{\n\t\t\t\"name\": \"vs/code\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/api/common\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/bulkEdit\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/cli\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/codeEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/callHierarchy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/typeHierarchy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/codeActions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/comments\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/debug\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/dialogs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/emmet\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/experiments\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/extensions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/externalTerminal\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/feedback\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/files\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/html\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/issue\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/inlayHints\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/interactive\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/languageStatus\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/keybindings\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/markers\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/mergeEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/localization\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/logs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/output\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/performance\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/preferences\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/notebook\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/quickaccess\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userData\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/remote\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/relauncher\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/sash\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/scm\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/search\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/searchEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/snippets\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/format\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/tags\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/surveys\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/tasks\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/testing\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/terminal\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/themes\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/trust\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/update\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/url\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/watermark\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/webview\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/webviewPanel\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/workspace\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/workspaces\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/customEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/externalUriOpener\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeGettingStarted\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeOverlay\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomePage\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeViews\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeWalkthrough\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/outline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userDataSync\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/editSessions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/views\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/languageDetection\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/audioCues\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/deprecatedExtensionMigrator\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/bracketPairColorizer2Telemetry\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/offline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/actions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/authToken\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/backup\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/bulkEdit\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/clipboard\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/commands\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/configuration\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/configurationResolver\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/dialogs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/editor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensionManagement\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/files\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/history\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/log\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/integrity\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/keybinding\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/lifecycle\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/language\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/progress\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/remote\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/search\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/textfile\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/themes\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/textMate\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/workingCopy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/workspaces\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/decorations\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/label\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/preferences\",\n\t\t\t\"project\": \"vscode-preferences\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/notification\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userData\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userDataSync\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/editSessions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/views\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/timeline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/localHistory\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/authentication\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensionRecommendations\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/gettingStarted\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/host\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userDataProfile\",\n\t\t\t\"project\": \"vscode-profiles\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userDataProfile\",\n\t\t\t\"project\": \"vscode-profiles\"\n\t\t}\n\t]\n}\n", + "fileName": "./2.json" + }, "diffs": [ { "originalRange": "[301,301)", diff --git a/src/vs/editor/test/node/diffing/fixtures/json-brackets/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/json-brackets/smart.expected.diff.json index 93b4f55206e..128567c85ec 100644 --- a/src/vs/editor/test/node/diffing/fixtures/json-brackets/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/json-brackets/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.json", - "modifiedFileName": "./2.json", + "original": { + "content": "{\n\t\"editor\": [\n\t\t{\n\t\t\t\"name\": \"vs/platform\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/editor/contrib\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/editor\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/base\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t}\n\t],\n\t\"workbench\": [\n\t\t{\n\t\t\t\"name\": \"vs/code\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/api/common\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/bulkEdit\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/cli\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/codeEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/callHierarchy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/typeHierarchy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/codeActions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/comments\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/debug\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/dialogs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/emmet\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/experiments\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/extensions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/externalTerminal\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/feedback\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/files\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/html\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/issue\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/inlayHints\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/interactive\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/languageStatus\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/keybindings\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/markers\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/mergeEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/localization\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/logs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/output\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/performance\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/preferences\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/notebook\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/quickaccess\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userData\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/remote\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/relauncher\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/sash\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/scm\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/search\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/searchEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/snippets\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/format\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/tags\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/surveys\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/tasks\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/testing\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/terminal\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/themes\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/trust\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/update\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/url\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/watermark\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/webview\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/webviewPanel\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/workspace\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/workspaces\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/customEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/externalUriOpener\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeGettingStarted\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeOverlay\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomePage\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeViews\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeWalkthrough\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/outline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userDataSync\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/editSessions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/views\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/languageDetection\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/audioCues\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/deprecatedExtensionMigrator\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/offline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/actions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/authToken\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/backup\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/bulkEdit\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/clipboard\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/commands\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/configuration\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/configurationResolver\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/dialogs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/editor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensionManagement\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/files\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/history\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/log\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/integrity\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/keybinding\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/lifecycle\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/language\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/progress\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/remote\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/search\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/textfile\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/themes\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/textMate\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/workingCopy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/workspaces\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/decorations\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/label\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/preferences\",\n\t\t\t\"project\": \"vscode-preferences\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/notification\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userData\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userDataSync\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/editSessions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/views\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/timeline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/localHistory\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/authentication\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensionRecommendations\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/gettingStarted\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/host\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userDataProfile\",\n\t\t\t\"project\": \"vscode-profiles\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userDataProfile\",\n\t\t\t\"project\": \"vscode-profiles\"\n\t\t}\n\t]\n}\n", + "fileName": "./1.json" + }, + "modified": { + "content": "{\n\t\"editor\": [\n\t\t{\n\t\t\t\"name\": \"vs/platform\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/editor/contrib\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/editor\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/base\",\n\t\t\t\"project\": \"vscode-editor\"\n\t\t}\n\t],\n\t\"workbench\": [\n\t\t{\n\t\t\t\"name\": \"vs/code\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/api/common\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/bulkEdit\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/cli\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/codeEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/callHierarchy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/typeHierarchy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/codeActions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/comments\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/debug\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/dialogs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/emmet\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/experiments\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/extensions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/externalTerminal\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/feedback\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/files\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/html\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/issue\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/inlayHints\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/interactive\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/languageStatus\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/keybindings\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/markers\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/mergeEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/localization\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/logs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/output\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/performance\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/preferences\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/notebook\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/quickaccess\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userData\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/remote\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/relauncher\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/sash\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/scm\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/search\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/searchEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/snippets\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/format\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/tags\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/surveys\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/tasks\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/testing\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/terminal\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/themes\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/trust\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/update\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/url\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/watermark\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/webview\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/webviewPanel\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/workspace\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/workspaces\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/customEditor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/externalUriOpener\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeGettingStarted\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeOverlay\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomePage\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeViews\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/welcomeWalkthrough\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/outline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userDataSync\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/editSessions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/views\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/languageDetection\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/audioCues\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/deprecatedExtensionMigrator\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/bracketPairColorizer2Telemetry\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/offline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/actions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/authToken\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/backup\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/bulkEdit\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/clipboard\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/commands\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/configuration\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/configurationResolver\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/dialogs\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/editor\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensionManagement\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/files\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/history\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/log\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/integrity\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/keybinding\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/lifecycle\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/language\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/progress\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/remote\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/search\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/textfile\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/themes\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/textMate\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/workingCopy\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/workspaces\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/decorations\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/label\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/preferences\",\n\t\t\t\"project\": \"vscode-preferences\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/notification\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userData\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userDataSync\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/editSessions\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/views\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/timeline\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/localHistory\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/authentication\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/extensionRecommendations\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/gettingStarted\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/host\",\n\t\t\t\"project\": \"vscode-workbench\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/contrib/userDataProfile\",\n\t\t\t\"project\": \"vscode-profiles\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"vs/workbench/services/userDataProfile\",\n\t\t\t\"project\": \"vscode-profiles\"\n\t\t}\n\t]\n}\n", + "fileName": "./2.json" + }, "diffs": [ { "originalRange": "[302,302)", diff --git a/src/vs/editor/test/node/diffing/fixtures/just-whitespace/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/just-whitespace/experimental.expected.diff.json index cf6f3ec5f25..a24c28bdcfa 100644 --- a/src/vs/editor/test/node/diffing/fixtures/just-whitespace/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/just-whitespace/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.js", - "modifiedFileName": "./2.js", + "original": { + "content": "console.log('foo'); ", + "fileName": "./1.js" + }, + "modified": { + "content": "console.log('foo');", + "fileName": "./2.js" + }, "diffs": [ { "originalRange": "[1,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/just-whitespace/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/just-whitespace/smart.expected.diff.json index cf6f3ec5f25..a24c28bdcfa 100644 --- a/src/vs/editor/test/node/diffing/fixtures/just-whitespace/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/just-whitespace/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.js", - "modifiedFileName": "./2.js", + "original": { + "content": "console.log('foo'); ", + "fileName": "./1.js" + }, + "modified": { + "content": "console.log('foo');", + "fileName": "./2.js" + }, "diffs": [ { "originalRange": "[1,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/method-splitting/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/method-splitting/experimental.expected.diff.json index f79a1b00f3a..fd9618278ca 100644 --- a/src/vs/editor/test/node/diffing/fixtures/method-splitting/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/method-splitting/experimental.expected.diff.json @@ -1,14 +1,20 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "class Test {\n public getDecorationsViewportData(viewRange: Range): IDecorationsViewportData {\n\t\treturn null!;\n\t}\n\n\tpublic getInlineDecorationsOnLine(lineNumber: number): InlineDecoration[] {\n\t\tconst range = new Range(lineNumber, this._linesCollection.getViewLineMinColumn(lineNumber), lineNumber, this._linesCollection.getViewLineMaxColumn(lineNumber));\n\t\treturn this._getDecorationsInRange(range).inlineDecorations[0];\n\t}\n\n\tprivate _getDecorationsInRange(viewRange: Range): IDecorationsViewportData {\n\t\tconst modelDecorations = this._linesCollection.getDecorationsInRange(viewRange, this.editorId, filterValidationDecorations(this.configuration.options));\n\t\tconst startLineNumber = viewRange.startLineNumber;\n\t\tconst endLineNumber = viewRange.endLineNumber;\n\n\t\tconst decorationsInViewport: ViewModelDecoration[] = [];\n\t\tlet decorationsInViewportLen = 0;\n\t\tconst inlineDecorations: InlineDecoration[][] = [];\n\t\tfor (let j = startLineNumber; j <= endLineNumber; j++) {\n\t\t\tinlineDecorations[j - startLineNumber] = [];\n\t\t}\n\n\t\tfor (let i = 0, len = modelDecorations.length; i < len; i++) {\n\t\t\tconst modelDecoration = modelDecorations[i];\n\t\t\tconst decorationOptions = modelDecoration.options;\n\n\t\t\tif (!isModelDecorationVisible(this.model, modelDecoration)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst viewModelDecoration = this._getOrCreateViewModelDecoration(modelDecoration);\n\t\t\tconst viewRange = viewModelDecoration.range;\n\n\t\t\tdecorationsInViewport[decorationsInViewportLen++] = viewModelDecoration;\n\n\t\t\tif (decorationOptions.inlineClassName) {\n\t\t\t\tconst inlineDecoration = new InlineDecoration(viewRange, decorationOptions.inlineClassName, decorationOptions.inlineClassNameAffectsLetterSpacing ? InlineDecorationType.RegularAffectingLetterSpacing : InlineDecorationType.Regular);\n\t\t\t\tconst intersectedStartLineNumber = Math.max(startLineNumber, viewRange.startLineNumber);\n\t\t\t\tconst intersectedEndLineNumber = Math.min(endLineNumber, viewRange.endLineNumber);\n\t\t\t\tfor (let j = intersectedStartLineNumber; j <= intersectedEndLineNumber; j++) {\n\t\t\t\t\tinlineDecorations[j - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (decorationOptions.beforeContentClassName) {\n\t\t\t\tif (startLineNumber <= viewRange.startLineNumber && viewRange.startLineNumber <= endLineNumber) {\n\t\t\t\t\tconst inlineDecoration = new InlineDecoration(\n\t\t\t\t\t\tnew Range(viewRange.startLineNumber, viewRange.startColumn, viewRange.startLineNumber, viewRange.startColumn),\n\t\t\t\t\t\tdecorationOptions.beforeContentClassName,\n\t\t\t\t\t\tInlineDecorationType.Before\n\t\t\t\t\t);\n\t\t\t\t\tinlineDecorations[viewRange.startLineNumber - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (decorationOptions.afterContentClassName) {\n\t\t\t\tif (startLineNumber <= viewRange.endLineNumber && viewRange.endLineNumber <= endLineNumber) {\n\t\t\t\t\tconst inlineDecoration = new InlineDecoration(\n\t\t\t\t\t\tnew Range(viewRange.endLineNumber, viewRange.endColumn, viewRange.endLineNumber, viewRange.endColumn),\n\t\t\t\t\t\tdecorationOptions.afterContentClassName,\n\t\t\t\t\t\tInlineDecorationType.After\n\t\t\t\t\t);\n\t\t\t\t\tinlineDecorations[viewRange.endLineNumber - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tdecorations: decorationsInViewport,\n\t\t\tinlineDecorations: inlineDecorations\n\t\t};\n\t}\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "class Test {\n public getDecorationsViewportData(viewRange: Range): IDecorationsViewportData {\n\t\treturn null!;\n\t}\n\n\tprivate _getDecorationsViewportData(viewportRange: Range, onlyMinimapDecorations: boolean): IDecorationsViewportData {\n\t\tconst modelDecorations = this._linesCollection.getDecorationsInRange(viewportRange, this.editorId, filterValidationDecorations(this.configuration.options), onlyMinimapDecorations);\n\n\t\tconst startLineNumber = viewportRange.startLineNumber;\n\t\tconst endLineNumber = viewportRange.endLineNumber;\n\n\t\tconst decorationsInViewport: ViewModelDecoration[] = [];\n\t\tlet decorationsInViewportLen = 0;\n\t\tconst inlineDecorations: InlineDecoration[][] = [];\n\t\tfor (let j = startLineNumber; j <= endLineNumber; j++) {\n\t\t\tinlineDecorations[j - startLineNumber] = [];\n\t\t}\n\n\t\tfor (let i = 0, len = modelDecorations.length; i < len; i++) {\n\t\t\tconst modelDecoration = modelDecorations[i];\n\t\t\tconst decorationOptions = modelDecoration.options;\n\n\t\t\tif (!isModelDecorationVisible(this.model, modelDecoration)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst viewModelDecoration = this._getOrCreateViewModelDecoration(modelDecoration);\n\t\t\tconst viewRange = viewModelDecoration.range;\n\n\t\t\tdecorationsInViewport[decorationsInViewportLen++] = viewModelDecoration;\n\n\t\t\tif (decorationOptions.inlineClassName) {\n\t\t\t\tconst inlineDecoration = new InlineDecoration(viewRange, decorationOptions.inlineClassName, decorationOptions.inlineClassNameAffectsLetterSpacing ? InlineDecorationType.RegularAffectingLetterSpacing : InlineDecorationType.Regular);\n\t\t\t\tconst intersectedStartLineNumber = Math.max(startLineNumber, viewRange.startLineNumber);\n\t\t\t\tconst intersectedEndLineNumber = Math.min(endLineNumber, viewRange.endLineNumber);\n\t\t\t\tfor (let j = intersectedStartLineNumber; j <= intersectedEndLineNumber; j++) {\n\t\t\t\t\tinlineDecorations[j - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (decorationOptions.beforeContentClassName) {\n\t\t\t\tif (startLineNumber <= viewRange.startLineNumber && viewRange.startLineNumber <= endLineNumber) {\n\t\t\t\t\tconst inlineDecoration = new InlineDecoration(\n\t\t\t\t\t\tnew Range(viewRange.startLineNumber, viewRange.startColumn, viewRange.startLineNumber, viewRange.startColumn),\n\t\t\t\t\t\tdecorationOptions.beforeContentClassName,\n\t\t\t\t\t\tInlineDecorationType.Before\n\t\t\t\t\t);\n\t\t\t\t\tinlineDecorations[viewRange.startLineNumber - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (decorationOptions.afterContentClassName) {\n\t\t\t\tif (startLineNumber <= viewRange.endLineNumber && viewRange.endLineNumber <= endLineNumber) {\n\t\t\t\t\tconst inlineDecoration = new InlineDecoration(\n\t\t\t\t\t\tnew Range(viewRange.endLineNumber, viewRange.endColumn, viewRange.endLineNumber, viewRange.endColumn),\n\t\t\t\t\t\tdecorationOptions.afterContentClassName,\n\t\t\t\t\t\tInlineDecorationType.After\n\t\t\t\t\t);\n\t\t\t\t\tinlineDecorations[viewRange.endLineNumber - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tdecorations: decorationsInViewport,\n\t\t\tinlineDecorations: inlineDecorations\n\t\t};\n\t}\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[6,10)", "modifiedRange": "[6,8)", "innerChanges": [ { - "originalRange": "[6,3 -> 6,9]", - "modifiedRange": "[6,3 -> 6,11]" + "originalRange": "[6,2 -> 6,9]", + "modifiedRange": "[6,2 -> 6,11]" }, { "originalRange": "[6,12 -> 6,18]", @@ -19,36 +25,20 @@ "modifiedRange": "[6,25 -> 6,91]" }, { - "originalRange": "[6,58 -> 6,63]", - "modifiedRange": "[6,95 -> 6,95]" - }, - { - "originalRange": "[6,73 -> 6,75]", - "modifiedRange": "[6,105 -> 6,118]" + "originalRange": "[6,57 -> 6,75]", + "modifiedRange": "[6,94 -> 6,118]" }, { "originalRange": "[7,9 -> 7,38]", "modifiedRange": "[7,9 -> 7,27]" }, { - "originalRange": "[7,64 -> 7,105]", - "modifiedRange": "[7,53 -> 7,85]" + "originalRange": "[7,61 -> 7,105]", + "modifiedRange": "[7,50 -> 7,85]" }, { - "originalRange": "[7,112 -> 8,11]", - "modifiedRange": "[7,92 -> 7,131]" - }, - { - "originalRange": "[8,15 -> 8,23]", - "modifiedRange": "[7,135 -> 7,142]" - }, - { - "originalRange": "[8,29 -> 8,51]", - "modifiedRange": "[7,148 -> 7,170]" - }, - { - "originalRange": "[8,62 -> 10,1]", - "modifiedRange": "[7,181 -> 8,1]" + "originalRange": "[7,112 -> 10,1]", + "modifiedRange": "[7,92 -> 8,1]" } ] }, diff --git a/src/vs/editor/test/node/diffing/fixtures/method-splitting/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/method-splitting/smart.expected.diff.json index d0b4abc03ed..e1f4edb8a10 100644 --- a/src/vs/editor/test/node/diffing/fixtures/method-splitting/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/method-splitting/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "class Test {\n public getDecorationsViewportData(viewRange: Range): IDecorationsViewportData {\n\t\treturn null!;\n\t}\n\n\tpublic getInlineDecorationsOnLine(lineNumber: number): InlineDecoration[] {\n\t\tconst range = new Range(lineNumber, this._linesCollection.getViewLineMinColumn(lineNumber), lineNumber, this._linesCollection.getViewLineMaxColumn(lineNumber));\n\t\treturn this._getDecorationsInRange(range).inlineDecorations[0];\n\t}\n\n\tprivate _getDecorationsInRange(viewRange: Range): IDecorationsViewportData {\n\t\tconst modelDecorations = this._linesCollection.getDecorationsInRange(viewRange, this.editorId, filterValidationDecorations(this.configuration.options));\n\t\tconst startLineNumber = viewRange.startLineNumber;\n\t\tconst endLineNumber = viewRange.endLineNumber;\n\n\t\tconst decorationsInViewport: ViewModelDecoration[] = [];\n\t\tlet decorationsInViewportLen = 0;\n\t\tconst inlineDecorations: InlineDecoration[][] = [];\n\t\tfor (let j = startLineNumber; j <= endLineNumber; j++) {\n\t\t\tinlineDecorations[j - startLineNumber] = [];\n\t\t}\n\n\t\tfor (let i = 0, len = modelDecorations.length; i < len; i++) {\n\t\t\tconst modelDecoration = modelDecorations[i];\n\t\t\tconst decorationOptions = modelDecoration.options;\n\n\t\t\tif (!isModelDecorationVisible(this.model, modelDecoration)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst viewModelDecoration = this._getOrCreateViewModelDecoration(modelDecoration);\n\t\t\tconst viewRange = viewModelDecoration.range;\n\n\t\t\tdecorationsInViewport[decorationsInViewportLen++] = viewModelDecoration;\n\n\t\t\tif (decorationOptions.inlineClassName) {\n\t\t\t\tconst inlineDecoration = new InlineDecoration(viewRange, decorationOptions.inlineClassName, decorationOptions.inlineClassNameAffectsLetterSpacing ? InlineDecorationType.RegularAffectingLetterSpacing : InlineDecorationType.Regular);\n\t\t\t\tconst intersectedStartLineNumber = Math.max(startLineNumber, viewRange.startLineNumber);\n\t\t\t\tconst intersectedEndLineNumber = Math.min(endLineNumber, viewRange.endLineNumber);\n\t\t\t\tfor (let j = intersectedStartLineNumber; j <= intersectedEndLineNumber; j++) {\n\t\t\t\t\tinlineDecorations[j - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (decorationOptions.beforeContentClassName) {\n\t\t\t\tif (startLineNumber <= viewRange.startLineNumber && viewRange.startLineNumber <= endLineNumber) {\n\t\t\t\t\tconst inlineDecoration = new InlineDecoration(\n\t\t\t\t\t\tnew Range(viewRange.startLineNumber, viewRange.startColumn, viewRange.startLineNumber, viewRange.startColumn),\n\t\t\t\t\t\tdecorationOptions.beforeContentClassName,\n\t\t\t\t\t\tInlineDecorationType.Before\n\t\t\t\t\t);\n\t\t\t\t\tinlineDecorations[viewRange.startLineNumber - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (decorationOptions.afterContentClassName) {\n\t\t\t\tif (startLineNumber <= viewRange.endLineNumber && viewRange.endLineNumber <= endLineNumber) {\n\t\t\t\t\tconst inlineDecoration = new InlineDecoration(\n\t\t\t\t\t\tnew Range(viewRange.endLineNumber, viewRange.endColumn, viewRange.endLineNumber, viewRange.endColumn),\n\t\t\t\t\t\tdecorationOptions.afterContentClassName,\n\t\t\t\t\t\tInlineDecorationType.After\n\t\t\t\t\t);\n\t\t\t\t\tinlineDecorations[viewRange.endLineNumber - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tdecorations: decorationsInViewport,\n\t\t\tinlineDecorations: inlineDecorations\n\t\t};\n\t}\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "class Test {\n public getDecorationsViewportData(viewRange: Range): IDecorationsViewportData {\n\t\treturn null!;\n\t}\n\n\tprivate _getDecorationsViewportData(viewportRange: Range, onlyMinimapDecorations: boolean): IDecorationsViewportData {\n\t\tconst modelDecorations = this._linesCollection.getDecorationsInRange(viewportRange, this.editorId, filterValidationDecorations(this.configuration.options), onlyMinimapDecorations);\n\n\t\tconst startLineNumber = viewportRange.startLineNumber;\n\t\tconst endLineNumber = viewportRange.endLineNumber;\n\n\t\tconst decorationsInViewport: ViewModelDecoration[] = [];\n\t\tlet decorationsInViewportLen = 0;\n\t\tconst inlineDecorations: InlineDecoration[][] = [];\n\t\tfor (let j = startLineNumber; j <= endLineNumber; j++) {\n\t\t\tinlineDecorations[j - startLineNumber] = [];\n\t\t}\n\n\t\tfor (let i = 0, len = modelDecorations.length; i < len; i++) {\n\t\t\tconst modelDecoration = modelDecorations[i];\n\t\t\tconst decorationOptions = modelDecoration.options;\n\n\t\t\tif (!isModelDecorationVisible(this.model, modelDecoration)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst viewModelDecoration = this._getOrCreateViewModelDecoration(modelDecoration);\n\t\t\tconst viewRange = viewModelDecoration.range;\n\n\t\t\tdecorationsInViewport[decorationsInViewportLen++] = viewModelDecoration;\n\n\t\t\tif (decorationOptions.inlineClassName) {\n\t\t\t\tconst inlineDecoration = new InlineDecoration(viewRange, decorationOptions.inlineClassName, decorationOptions.inlineClassNameAffectsLetterSpacing ? InlineDecorationType.RegularAffectingLetterSpacing : InlineDecorationType.Regular);\n\t\t\t\tconst intersectedStartLineNumber = Math.max(startLineNumber, viewRange.startLineNumber);\n\t\t\t\tconst intersectedEndLineNumber = Math.min(endLineNumber, viewRange.endLineNumber);\n\t\t\t\tfor (let j = intersectedStartLineNumber; j <= intersectedEndLineNumber; j++) {\n\t\t\t\t\tinlineDecorations[j - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (decorationOptions.beforeContentClassName) {\n\t\t\t\tif (startLineNumber <= viewRange.startLineNumber && viewRange.startLineNumber <= endLineNumber) {\n\t\t\t\t\tconst inlineDecoration = new InlineDecoration(\n\t\t\t\t\t\tnew Range(viewRange.startLineNumber, viewRange.startColumn, viewRange.startLineNumber, viewRange.startColumn),\n\t\t\t\t\t\tdecorationOptions.beforeContentClassName,\n\t\t\t\t\t\tInlineDecorationType.Before\n\t\t\t\t\t);\n\t\t\t\t\tinlineDecorations[viewRange.startLineNumber - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (decorationOptions.afterContentClassName) {\n\t\t\t\tif (startLineNumber <= viewRange.endLineNumber && viewRange.endLineNumber <= endLineNumber) {\n\t\t\t\t\tconst inlineDecoration = new InlineDecoration(\n\t\t\t\t\t\tnew Range(viewRange.endLineNumber, viewRange.endColumn, viewRange.endLineNumber, viewRange.endColumn),\n\t\t\t\t\t\tdecorationOptions.afterContentClassName,\n\t\t\t\t\t\tInlineDecorationType.After\n\t\t\t\t\t);\n\t\t\t\t\tinlineDecorations[viewRange.endLineNumber - startLineNumber].push(inlineDecoration);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tdecorations: decorationsInViewport,\n\t\t\tinlineDecorations: inlineDecorations\n\t\t};\n\t}\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[6,10)", diff --git a/src/vs/editor/test/node/diffing/fixtures/minimal-diff-character/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/minimal-diff-character/experimental.expected.diff.json index 430db713be3..e66bd17ab11 100644 --- a/src/vs/editor/test/node/diffing/fixtures/minimal-diff-character/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/minimal-diff-character/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import * as path from 'path';\nimport { Command } from 'vscode';\nimport * as nls from 'vscode-nls';\n\n\"()()()()()()()()()()()()()\"", + "fileName": "./1.tst" + }, + "modified": { + "content": "import * as path from 'path';\nimport { Command, commands } from 'vscode';\nimport * as nls from 'vscode-nls';\n\n\"Gallicum()est()divisa()in()partres()tres()quarum()unam()est()()()()()()()()()()()()\"", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,3)", diff --git a/src/vs/editor/test/node/diffing/fixtures/minimal-diff-character/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/minimal-diff-character/smart.expected.diff.json index 430db713be3..e66bd17ab11 100644 --- a/src/vs/editor/test/node/diffing/fixtures/minimal-diff-character/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/minimal-diff-character/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import * as path from 'path';\nimport { Command } from 'vscode';\nimport * as nls from 'vscode-nls';\n\n\"()()()()()()()()()()()()()\"", + "fileName": "./1.tst" + }, + "modified": { + "content": "import * as path from 'path';\nimport { Command, commands } from 'vscode';\nimport * as nls from 'vscode-nls';\n\n\"Gallicum()est()divisa()in()partres()tres()quarum()unam()est()()()()()()()()()()()()\"", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,3)", diff --git a/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/experimental.expected.diff.json index c0ce019463b..7fee9a6d76d 100644 --- a/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.txt", - "modifiedFileName": "./2.txt", + "original": { + "content": "import { IChange, IDiffComputationResult } from 'vs/editor/common/diff/diffComputer';", + "fileName": "./1.txt" + }, + "modified": { + "content": "import { IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider';\nimport { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer';", + "fileName": "./2.txt" + }, "diffs": [ { "originalRange": "[1,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/smart.expected.diff.json index 7eca01a03c6..9259dbaf629 100644 --- a/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.txt", - "modifiedFileName": "./2.txt", + "original": { + "content": "import { IChange, IDiffComputationResult } from 'vs/editor/common/diff/diffComputer';", + "fileName": "./1.txt" + }, + "modified": { + "content": "import { IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider';\nimport { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer';", + "fileName": "./2.txt" + }, "diffs": [ { "originalRange": "[1,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/random-match-1/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/random-match-1/experimental.expected.diff.json index 753a7c75cbc..b3038a8d2b7 100644 --- a/src/vs/editor/test/node/diffing/fixtures/random-match-1/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/random-match-1/experimental.expected.diff.json @@ -1,14 +1,20 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "const sourceActions = notebookKernelService.getSourceActions(notebook, editor.scopedContextKeyService);\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "const sourceActions = notebookKernelService.getSourceActions(notebookTextModel, scopedContextKeyService);\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[1,2)", "modifiedRange": "[1,2)", "innerChanges": [ { - "originalRange": "[1,70 -> 1,79]", - "modifiedRange": "[1,70 -> 1,81]" + "originalRange": "[1,62 -> 1,79]", + "modifiedRange": "[1,62 -> 1,81]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/random-match-1/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/random-match-1/smart.expected.diff.json index 753a7c75cbc..e2af26dcae3 100644 --- a/src/vs/editor/test/node/diffing/fixtures/random-match-1/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/random-match-1/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "const sourceActions = notebookKernelService.getSourceActions(notebook, editor.scopedContextKeyService);\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "const sourceActions = notebookKernelService.getSourceActions(notebookTextModel, scopedContextKeyService);\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[1,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/random-match-2/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/random-match-2/experimental.expected.diff.json index 6b84b4c6209..337c2637132 100644 --- a/src/vs/editor/test/node/diffing/fixtures/random-match-2/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/random-match-2/experimental.expected.diff.json @@ -1,14 +1,20 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "if (!all.length && !sourceActions.length) {\n\tconst activeNotebookModel = getNotebookEditorFromEditorPane(editorService.activeEditorPane)?.textModel;\n\tif (activeNotebookModel) {\n\t\tconst language = this.getSuggestedLanguage(activeNotebookModel);\n\t\tsuggestedExtension = language ? this.getSuggestedKernelFromLanguage(activeNotebookModel.viewType, language) : undefined;\n\t}\n\tif (suggestedExtension) {\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "if (!all.length && !sourceActions.length) {\n\tconst language = this.getSuggestedLanguage(notebookTextModel);\n\tsuggestedExtension = language ? this.getSuggestedKernelFromLanguage(notebookTextModel.viewType, language) : undefined;\n\tif (suggestedExtension) {\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,7)", "modifiedRange": "[2,4)", "innerChanges": [ { - "originalRange": "[2,8 -> 4,11]", - "modifiedRange": "[2,8 -> 2,10]" + "originalRange": "[2,8 -> 4,17]", + "modifiedRange": "[2,8 -> 2,16]" }, { "originalRange": "[4,46 -> 4,53]", diff --git a/src/vs/editor/test/node/diffing/fixtures/random-match-2/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/random-match-2/smart.expected.diff.json index d727a596dd4..7d0d8ed1629 100644 --- a/src/vs/editor/test/node/diffing/fixtures/random-match-2/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/random-match-2/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "if (!all.length && !sourceActions.length) {\n\tconst activeNotebookModel = getNotebookEditorFromEditorPane(editorService.activeEditorPane)?.textModel;\n\tif (activeNotebookModel) {\n\t\tconst language = this.getSuggestedLanguage(activeNotebookModel);\n\t\tsuggestedExtension = language ? this.getSuggestedKernelFromLanguage(activeNotebookModel.viewType, language) : undefined;\n\t}\n\tif (suggestedExtension) {\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "if (!all.length && !sourceActions.length) {\n\tconst language = this.getSuggestedLanguage(notebookTextModel);\n\tsuggestedExtension = language ? this.getSuggestedKernelFromLanguage(notebookTextModel.viewType, language) : undefined;\n\tif (suggestedExtension) {\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,7)", diff --git a/src/vs/editor/test/node/diffing/fixtures/random-match-3/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/random-match-3/experimental.expected.diff.json index 5c70300bec8..869c81350b7 100644 --- a/src/vs/editor/test/node/diffing/fixtures/random-match-3/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/random-match-3/experimental.expected.diff.json @@ -1,18 +1,20 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "const { selected, all, suggestions, hidden } = notebookKernelService.getMatchingKernel(notebook);\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "const scopedContextKeyService = editor.scopedContextKeyService;\nconst matchResult = notebookKernelService.getMatchingKernel(notebook);\nconst { selected, all } = matchResult;\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[1,2)", "modifiedRange": "[1,4)", "innerChanges": [ { - "originalRange": "[1,6 -> 1,32]", - "modifiedRange": "[1,6 -> 2,2]" - }, - { - "originalRange": "[1,35 -> 1,45]", - "modifiedRange": "[2,5 -> 2,18]" + "originalRange": "[1,6 -> 1,45]", + "modifiedRange": "[1,6 -> 2,18]" }, { "originalRange": "[2,1 -> 2,1]", diff --git a/src/vs/editor/test/node/diffing/fixtures/random-match-3/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/random-match-3/smart.expected.diff.json index f5d18c303e1..a1f2e8db4a5 100644 --- a/src/vs/editor/test/node/diffing/fixtures/random-match-3/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/random-match-3/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "const { selected, all, suggestions, hidden } = notebookKernelService.getMatchingKernel(notebook);\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "const scopedContextKeyService = editor.scopedContextKeyService;\nconst matchResult = notebookKernelService.getMatchingKernel(notebook);\nconst { selected, all } = matchResult;\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[1,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/subword/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/subword/experimental.expected.diff.json index d1e2aa57bee..c8a5000a54c 100644 --- a/src/vs/editor/test/node/diffing/fixtures/subword/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/subword/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker';\nimport { IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker';\nimport { IModelService } from 'vs/editor/common/services/model';\n\nlet x: [IEditorWorkerService, EditorSimpleWorker, IModelService, IUnicodeHighlightsResult];", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker';\nimport { IDiffComputationResult, IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker';\nimport { IModelService } from 'vs/editor/common/services/model';\n\nlet x: [IEditorWorkerService, EditorSimpleWorker, IModelService, IUnicodeHighlightsResult];\nlet y: IDiffComputationResult;", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,3)", @@ -17,8 +23,8 @@ "modifiedRange": "[6,7)", "innerChanges": [ { - "originalRange": "[6,1 -> 6,1]", - "modifiedRange": "[6,1 -> 7,1]" + "originalRange": "[5,92 -> 5,92]", + "modifiedRange": "[5,92 -> 6,31]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/subword/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/subword/smart.expected.diff.json index 795a5a1d248..ed40ca24537 100644 --- a/src/vs/editor/test/node/diffing/fixtures/subword/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/subword/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker';\nimport { IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker';\nimport { IModelService } from 'vs/editor/common/services/model';\n\nlet x: [IEditorWorkerService, EditorSimpleWorker, IModelService, IUnicodeHighlightsResult];", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker';\nimport { IDiffComputationResult, IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker';\nimport { IModelService } from 'vs/editor/common/services/model';\n\nlet x: [IEditorWorkerService, EditorSimpleWorker, IModelService, IUnicodeHighlightsResult];\nlet y: IDiffComputationResult;", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,3)", diff --git a/src/vs/editor/test/node/diffing/fixtures/trivial/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/trivial/experimental.expected.diff.json index 82196225144..b88bd08c021 100644 --- a/src/vs/editor/test/node/diffing/fixtures/trivial/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/trivial/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.txt", - "modifiedFileName": "./2.txt", + "original": { + "content": "", + "fileName": "./1.txt" + }, + "modified": { + "content": "x", + "fileName": "./2.txt" + }, "diffs": [ { "originalRange": "[1,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/trivial/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/trivial/smart.expected.diff.json index 6068fbfd5b1..e4d8e0713df 100644 --- a/src/vs/editor/test/node/diffing/fixtures/trivial/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/trivial/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.txt", - "modifiedFileName": "./2.txt", + "original": { + "content": "", + "fileName": "./1.txt" + }, + "modified": { + "content": "x", + "fileName": "./2.txt" + }, "diffs": [ { "originalRange": "[1,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-class/1.tst b/src/vs/editor/test/node/diffing/fixtures/ts-class/1.tst new file mode 100644 index 00000000000..926e9102e77 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/ts-class/1.tst @@ -0,0 +1,32 @@ + +class Slice implements ISequence { + private readonly elements: Int32Array; + private readonly firstCharOnLineOffsets: Int32Array; + + constructor(public readonly lines: string[], public readonly lineRange: OffsetRange) { + let chars = 0; + this.firstCharOnLineOffsets = new Int32Array(lineRange.length); + + for (let i = lineRange.start; i < lineRange.endExclusive; i++) { + const line = lines[i]; + chars += line.length; + this.firstCharOnLineOffsets[i - lineRange.start] = chars + 1; + chars++; + } + + this.elements = new Int32Array(chars); + let offset = 0; + for (let i = lineRange.start; i < lineRange.endExclusive; i++) { + const line = lines[i]; + + for (let i = 0; i < line.length; i++) { + this.elements[offset + i] = line.charCodeAt(i); + } + offset += line.length; + if (i < lines.length - 1) { + this.elements[offset] = '\n'.charCodeAt(0); + offset += 1; + } + } + } +} diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-class/2.tst b/src/vs/editor/test/node/diffing/fixtures/ts-class/2.tst new file mode 100644 index 00000000000..f929ce3c1ef --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/ts-class/2.tst @@ -0,0 +1,23 @@ +class Slice implements ISequence { + private readonly elements: number[] = []; + private readonly firstCharOnLineOffsets: number[] = []; + private readonly trimStartLength: number[] = []; + + constructor(public readonly lines: string[], public readonly lineRange: OffsetRange, public readonly considerWhitespaceChanges: boolean) { + for (let i = lineRange.start; i < lineRange.endExclusive; i++) { + const l = lines[i]; + const l1 = considerWhitespaceChanges ? l : l.trimStart(); + const line = considerWhitespaceChanges ? l1 : l1.trimEnd(); + this.trimStartLength.push(l.length - l1.length); + + for (let i = 0; i < line.length; i++) { + this.elements.push(line.charCodeAt(i)); + } + if (i < lines.length - 1) { + this.elements.push('\n'.charCodeAt(0)); + } + + this.firstCharOnLineOffsets[i - lineRange.start] = this.elements.length; + } + } +} diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-class/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-class/experimental.expected.diff.json new file mode 100644 index 00000000000..85e7beaa072 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/ts-class/experimental.expected.diff.json @@ -0,0 +1,116 @@ +{ + "original": { + "content": "\nclass Slice implements ISequence {\n\tprivate readonly elements: Int32Array;\n\tprivate readonly firstCharOnLineOffsets: Int32Array;\n\n\tconstructor(public readonly lines: string[], public readonly lineRange: OffsetRange) {\n\t\tlet chars = 0;\n\t\tthis.firstCharOnLineOffsets = new Int32Array(lineRange.length);\n\n\t\tfor (let i = lineRange.start; i < lineRange.endExclusive; i++) {\n\t\t\tconst line = lines[i];\n\t\t\tchars += line.length;\n\t\t\tthis.firstCharOnLineOffsets[i - lineRange.start] = chars + 1;\n\t\t\tchars++;\n\t\t}\n\n\t\tthis.elements = new Int32Array(chars);\n\t\tlet offset = 0;\n\t\tfor (let i = lineRange.start; i < lineRange.endExclusive; i++) {\n\t\t\tconst line = lines[i];\n\n\t\t\tfor (let i = 0; i < line.length; i++) {\n\t\t\t\tthis.elements[offset + i] = line.charCodeAt(i);\n\t\t\t}\n\t\t\toffset += line.length;\n\t\t\tif (i < lines.length - 1) {\n\t\t\t\tthis.elements[offset] = '\\n'.charCodeAt(0);\n\t\t\t\toffset += 1;\n\t\t\t}\n\t\t}\n\t}\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "class Slice implements ISequence {\n\tprivate readonly elements: number[] = [];\n\tprivate readonly firstCharOnLineOffsets: number[] = [];\n\tprivate readonly trimStartLength: number[] = [];\n\n\tconstructor(public readonly lines: string[], public readonly lineRange: OffsetRange, public readonly considerWhitespaceChanges: boolean) {\n\t\tfor (let i = lineRange.start; i < lineRange.endExclusive; i++) {\n\t\t\tconst l = lines[i];\n\t\t\tconst l1 = considerWhitespaceChanges ? l : l.trimStart();\n\t\t\tconst line = considerWhitespaceChanges ? l1 : l1.trimEnd();\n\t\t\tthis.trimStartLength.push(l.length - l1.length);\n\n\t\t\tfor (let i = 0; i < line.length; i++) {\n\t\t\t\tthis.elements.push(line.charCodeAt(i));\n\t\t\t}\n\t\t\tif (i < lines.length - 1) {\n\t\t\t\tthis.elements.push('\\n'.charCodeAt(0));\n\t\t\t}\n\n\t\t\tthis.firstCharOnLineOffsets[i - lineRange.start] = this.elements.length;\n\t\t}\n\t}\n}\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[1,2)", + "modifiedRange": "[1,1)", + "innerChanges": [ + { + "originalRange": "[1,1 -> 2,1]", + "modifiedRange": "[1,1 -> 1,1]" + } + ] + }, + { + "originalRange": "[3,5)", + "modifiedRange": "[2,5)", + "innerChanges": [ + { + "originalRange": "[3,29 -> 3,39]", + "modifiedRange": "[2,29 -> 2,42]" + }, + { + "originalRange": "[4,43 -> 4,53]", + "modifiedRange": "[3,43 -> 4,49]" + } + ] + }, + { + "originalRange": "[6,10)", + "modifiedRange": "[6,7)", + "innerChanges": [ + { + "originalRange": "[6,85 -> 9,1]", + "modifiedRange": "[6,85 -> 6,140]" + } + ] + }, + { + "originalRange": "[11,21)", + "modifiedRange": "[8,12)", + "innerChanges": [ + { + "originalRange": "[11,10 -> 11,14]", + "modifiedRange": "[8,10 -> 8,11]" + }, + { + "originalRange": "[12,4 -> 13,52]", + "modifiedRange": "[9,4 -> 9,12]" + }, + { + "originalRange": "[13,55 -> 19,67]", + "modifiedRange": "[9,15 -> 9,61]" + }, + { + "originalRange": "[20,17 -> 20,25]", + "modifiedRange": "[10,17 -> 11,51]" + } + ] + }, + { + "originalRange": "[23,24)", + "modifiedRange": "[14,15)", + "innerChanges": [ + { + "originalRange": "[23,18 -> 23,33]", + "modifiedRange": "[14,18 -> 14,24]" + }, + { + "originalRange": "[23,50 -> 23,50]", + "modifiedRange": "[14,41 -> 14,42]" + } + ] + }, + { + "originalRange": "[25,26)", + "modifiedRange": "[16,16)", + "innerChanges": [ + { + "originalRange": "[25,1 -> 26,1]", + "modifiedRange": "[16,1 -> 16,1]" + } + ] + }, + { + "originalRange": "[27,29)", + "modifiedRange": "[17,18)", + "innerChanges": [ + { + "originalRange": "[27,18 -> 27,29]", + "modifiedRange": "[17,18 -> 17,24]" + }, + { + "originalRange": "[27,47 -> 28,16]", + "modifiedRange": "[17,42 -> 17,43]" + } + ] + }, + { + "originalRange": "[30,30)", + "modifiedRange": "[19,21)", + "innerChanges": [ + { + "originalRange": "[30,1 -> 30,1]", + "modifiedRange": "[19,1 -> 21,1]" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-class/experimental.human.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-class/experimental.human.diff.json new file mode 100644 index 00000000000..1601892786e --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/ts-class/experimental.human.diff.json @@ -0,0 +1,100 @@ +{ + "original": { + "content": "\nclass Slice implements ISequence {\n\tprivate readonly elements: Int32Array;\n\tprivate readonly firstCharOnLineOffsets: Int32Array;\n\n\tconstructor(public readonly lines: string[], public readonly lineRange: OffsetRange) {\n\t\tlet chars = 0;\n\t\tthis.firstCharOnLineOffsets = new Int32Array(lineRange.length);\n\n\t\tfor (let i = lineRange.start; i < lineRange.endExclusive; i++) {\n\t\t\tconst line = lines[i];\n\t\t\tchars += line.length;\n\t\t\tthis.firstCharOnLineOffsets[i - lineRange.start] = chars + 1;\n\t\t\tchars++;\n\t\t}\n\n\t\tthis.elements = new Int32Array(chars);\n\t\tlet offset = 0;\n\t\tfor (let i = lineRange.start; i < lineRange.endExclusive; i++) {\n\t\t\tconst line = lines[i];\n\n\t\t\tfor (let i = 0; i < line.length; i++) {\n\t\t\t\tthis.elements[offset + i] = line.charCodeAt(i);\n\t\t\t}\n\t\t\toffset += line.length;\n\t\t\tif (i < lines.length - 1) {\n\t\t\t\tthis.elements[offset] = '\\n'.charCodeAt(0);\n\t\t\t\toffset += 1;\n\t\t\t}\n\t\t}\n\t}\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "class Slice implements ISequence {\n\tprivate readonly elements: number[] = [];\n\tprivate readonly firstCharOnLineOffsets: number[] = [];\n\tprivate readonly trimStartLength: number[] = [];\n\n\tconstructor(public readonly lines: string[], public readonly lineRange: OffsetRange, public readonly considerWhitespaceChanges: boolean) {\n\t\tfor (let i = lineRange.start; i < lineRange.endExclusive; i++) {\n\t\t\tconst l = lines[i];\n\t\t\tconst l1 = considerWhitespaceChanges ? l : l.trimStart();\n\t\t\tconst line = considerWhitespaceChanges ? l1 : l1.trimEnd();\n\t\t\tthis.trimStartLength.push(l.length - l1.length);\n\n\t\t\tfor (let i = 0; i < line.length; i++) {\n\t\t\t\tthis.elements.push(line.charCodeAt(i));\n\t\t\t}\n\t\t\tif (i < lines.length - 1) {\n\t\t\t\tthis.elements.push('\\n'.charCodeAt(0));\n\t\t\t}\n\n\t\t\tthis.firstCharOnLineOffsets[i - lineRange.start] = this.elements.length;\n\t\t}\n\t}\n}\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[1,2)", + "modifiedRange": "[1,1)", + "innerChanges": null + }, + { + "originalRange": "[3,5)", + "modifiedRange": "[2,5)", + "innerChanges": [ + { + "originalRange": "[3,29 -> 3,39]", + "modifiedRange": "[2,29 -> 2,42]" + }, + { + "originalRange": "[4,43 -> 4,53]", + "modifiedRange": "[3,43 -> 4,49]" + } + ] + }, + + { + "originalRange": "[6,7)", + "modifiedRange": "[6,7)", + "innerChanges": [ + { + "originalRange": "[6,85 -> 6,85]", + "modifiedRange": "[6,85 -> 6,137]" + } + ] + }, + { + "originalRange": "[7,10)", + "modifiedRange": "[7,7)", + "innerChanges": null + }, + { + "originalRange": "[11,12)", + "modifiedRange": "[8,9)", + "innerChanges": [ + { + "originalRange": "[11,11 -> 11,14]", + "modifiedRange": "[8,11 -> 8,11]" + } + ] + }, + { + "originalRange": "[12,21)", + "modifiedRange": "[9,12)", + "innerChanges": null + }, + { + "originalRange": "[23,24)", + "modifiedRange": "[14,15)", + "innerChanges": [ + { + "originalRange": "[23,18 -> 23,33]", + "modifiedRange": "[14,18 -> 14,24]" + }, + { + "originalRange": "[23,51 -> 23,51]", + "modifiedRange": "[14,42 -> 14,43]" + } + ] + }, + { + "originalRange": "[25,26)", + "modifiedRange": "[16,16)", + "innerChanges": null + }, + { + "originalRange": "[27,29)", + "modifiedRange": "[17,18)", + "innerChanges": [ + { + "originalRange": "[27,18 -> 27,29]", + "modifiedRange": "[17,18 -> 17,24]" + }, + { + "originalRange": "[27,47 -> 28,16]", + "modifiedRange": "[17,42 -> 17,43]" + } + ] + }, + { + "originalRange": "[30,30)", + "modifiedRange": "[19,21)", + "innerChanges": null + } + ] +} diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-class/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-class/smart.expected.diff.json new file mode 100644 index 00000000000..bfb1d8aa5dc --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/ts-class/smart.expected.diff.json @@ -0,0 +1,113 @@ +{ + "original": { + "content": "\nclass Slice implements ISequence {\n\tprivate readonly elements: Int32Array;\n\tprivate readonly firstCharOnLineOffsets: Int32Array;\n\n\tconstructor(public readonly lines: string[], public readonly lineRange: OffsetRange) {\n\t\tlet chars = 0;\n\t\tthis.firstCharOnLineOffsets = new Int32Array(lineRange.length);\n\n\t\tfor (let i = lineRange.start; i < lineRange.endExclusive; i++) {\n\t\t\tconst line = lines[i];\n\t\t\tchars += line.length;\n\t\t\tthis.firstCharOnLineOffsets[i - lineRange.start] = chars + 1;\n\t\t\tchars++;\n\t\t}\n\n\t\tthis.elements = new Int32Array(chars);\n\t\tlet offset = 0;\n\t\tfor (let i = lineRange.start; i < lineRange.endExclusive; i++) {\n\t\t\tconst line = lines[i];\n\n\t\t\tfor (let i = 0; i < line.length; i++) {\n\t\t\t\tthis.elements[offset + i] = line.charCodeAt(i);\n\t\t\t}\n\t\t\toffset += line.length;\n\t\t\tif (i < lines.length - 1) {\n\t\t\t\tthis.elements[offset] = '\\n'.charCodeAt(0);\n\t\t\t\toffset += 1;\n\t\t\t}\n\t\t}\n\t}\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "class Slice implements ISequence {\n\tprivate readonly elements: number[] = [];\n\tprivate readonly firstCharOnLineOffsets: number[] = [];\n\tprivate readonly trimStartLength: number[] = [];\n\n\tconstructor(public readonly lines: string[], public readonly lineRange: OffsetRange, public readonly considerWhitespaceChanges: boolean) {\n\t\tfor (let i = lineRange.start; i < lineRange.endExclusive; i++) {\n\t\t\tconst l = lines[i];\n\t\t\tconst l1 = considerWhitespaceChanges ? l : l.trimStart();\n\t\t\tconst line = considerWhitespaceChanges ? l1 : l1.trimEnd();\n\t\t\tthis.trimStartLength.push(l.length - l1.length);\n\n\t\t\tfor (let i = 0; i < line.length; i++) {\n\t\t\t\tthis.elements.push(line.charCodeAt(i));\n\t\t\t}\n\t\t\tif (i < lines.length - 1) {\n\t\t\t\tthis.elements.push('\\n'.charCodeAt(0));\n\t\t\t}\n\n\t\t\tthis.firstCharOnLineOffsets[i - lineRange.start] = this.elements.length;\n\t\t}\n\t}\n}\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[1,2)", + "modifiedRange": "[1,1)", + "innerChanges": null + }, + { + "originalRange": "[3,5)", + "modifiedRange": "[2,5)", + "innerChanges": [ + { + "originalRange": "[3,29 -> 3,39]", + "modifiedRange": "[2,29 -> 2,42]" + }, + { + "originalRange": "[4,43 -> 4,53]", + "modifiedRange": "[3,43 -> 4,49]" + } + ] + }, + { + "originalRange": "[6,10)", + "modifiedRange": "[6,7)", + "innerChanges": [ + { + "originalRange": "[6,85 -> 8,53]", + "modifiedRange": "[6,85 -> 6,123]" + }, + { + "originalRange": "[8,57 -> 9,1]", + "modifiedRange": "[6,127 -> 6,140]" + } + ] + }, + { + "originalRange": "[11,21)", + "modifiedRange": "[8,12)", + "innerChanges": [ + { + "originalRange": "[11,11 -> 11,14]", + "modifiedRange": "[8,11 -> 8,11]" + }, + { + "originalRange": "[12,5 -> 13,14]", + "modifiedRange": "[9,5 -> 9,33]" + }, + { + "originalRange": "[13,17 -> 13,64]", + "modifiedRange": "[9,36 -> 9,60]" + }, + { + "originalRange": "[14,5 -> 17,39]", + "modifiedRange": "[10,5 -> 10,61]" + }, + { + "originalRange": "[18,3 -> 19,27]", + "modifiedRange": "[11,3 -> 11,14]" + }, + { + "originalRange": "[19,31 -> 20,25]", + "modifiedRange": "[11,18 -> 11,51]" + } + ] + }, + { + "originalRange": "[23,24)", + "modifiedRange": "[14,15)", + "innerChanges": [ + { + "originalRange": "[23,18 -> 23,33]", + "modifiedRange": "[14,18 -> 14,24]" + }, + { + "originalRange": "[23,51 -> 23,51]", + "modifiedRange": "[14,42 -> 14,43]" + } + ] + }, + { + "originalRange": "[25,26)", + "modifiedRange": "[16,16)", + "innerChanges": null + }, + { + "originalRange": "[27,29)", + "modifiedRange": "[17,18)", + "innerChanges": [ + { + "originalRange": "[27,18 -> 27,29]", + "modifiedRange": "[17,18 -> 17,24]" + }, + { + "originalRange": "[27,47 -> 28,16]", + "modifiedRange": "[17,42 -> 17,43]" + } + ] + }, + { + "originalRange": "[30,30)", + "modifiedRange": "[19,21)", + "innerChanges": null + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-comments/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-comments/experimental.expected.diff.json index 6bdd24212ff..29e3fc1bfe1 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-comments/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-comments/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "interface Test {\n /**\n * Render +/- indicators for added/deleted changes.\n * Defaults to true.\n */\n renderIndicators?: boolean;\n /**\n * Original model should be editable?\n * Defaults to false.\n */\n originalEditable?: boolean;\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "interface Test {\n /**\n * Render +/- indicators for added/deleted changes.\n * Defaults to true.\n */\n renderIndicators?: boolean;\n /**\n * Shows icons in the glyph margin to revert changes.\n * Default to true.\n */\n renderMarginRevertIcon?: boolean;\n /**\n * Original model should be editable?\n * Defaults to false.\n */\n originalEditable?: boolean;\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[7,7)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-comments/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-comments/smart.expected.diff.json index e5fb2b96111..a1903d21727 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-comments/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-comments/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "interface Test {\n /**\n * Render +/- indicators for added/deleted changes.\n * Defaults to true.\n */\n renderIndicators?: boolean;\n /**\n * Original model should be editable?\n * Defaults to false.\n */\n originalEditable?: boolean;\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "interface Test {\n /**\n * Render +/- indicators for added/deleted changes.\n * Defaults to true.\n */\n renderIndicators?: boolean;\n /**\n * Shows icons in the glyph margin to revert changes.\n * Default to true.\n */\n renderMarginRevertIcon?: boolean;\n /**\n * Original model should be editable?\n * Defaults to false.\n */\n originalEditable?: boolean;\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[8,8)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/experimental.expected.diff.json index 37bf0534f87..07656313cdc 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "class Test {\n // ---- BEGIN diff --------------------------------------------------------------------------\n\n\tpublic async computeDiff(originalUrl: string, modifiedUrl: string, ignoreTrimWhitespace: boolean, maxComputationTime: number): Promise {\n\t\tconst original = this._getModel(originalUrl);\n\t\tconst modified = this._getModel(modifiedUrl);\n\t\tif (!original || !modified) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn EditorSimpleWorker.computeDiff(original, modified, ignoreTrimWhitespace, maxComputationTime);\n\t}\n\n\tpublic static computeDiff(originalTextModel: ICommonModel | ITextModel, modifiedTextModel: ICommonModel | ITextModel, ignoreTrimWhitespace: boolean, maxComputationTime: number): IDiffComputationResult | null {\n\t\tconst originalLines = originalTextModel.getLinesContent();\n\t\tconst modifiedLines = modifiedTextModel.getLinesContent();\n\t\tconst diffComputer = new DiffComputer(originalLines, modifiedLines, {\n\t\t\tshouldComputeCharChanges: true,\n\t\t\tshouldPostProcessCharChanges: true,\n\t\t\tshouldIgnoreTrimWhitespace: ignoreTrimWhitespace,\n\t\t\tshouldMakePrettyDiff: true,\n\t\t\tmaxComputationTime: maxComputationTime\n\t\t});\n\n\t\tconst diffResult = diffComputer.computeDiff();\n\t\tconst identical = (diffResult.changes.length > 0 ? false : this._modelsAreIdentical(originalTextModel, modifiedTextModel));\n\t\treturn {\n\t\t\tquitEarly: diffResult.quitEarly,\n\t\t\tidentical: identical,\n\t\t\tchanges: diffResult.changes\n\t\t};\n\t}\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "class Test {\n\t// ---- BEGIN diff --------------------------------------------------------------------------\n\n\tpublic async computeDiff(originalUrl: string, modifiedUrl: string, options: ILinesDiffComputerOptions): Promise {\n\t\tconst original = this._getModel(originalUrl);\n\t\tconst modified = this._getModel(modifiedUrl);\n\t\tif (!original || !modified) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn EditorSimpleWorker.computeDiff(original, modified, options);\n\t}\n\n\tpublic static computeDiff(originalTextModel: ICommonModel | ITextModel, modifiedTextModel: ICommonModel | ITextModel, options: ILinesDiffComputerOptions): IDiffComputationResult {\n\n\t\tconst diffAlgorithm: ILinesDiffComputer = options.diffAlgorithm === 'experimental' ? linesDiffComputers.experimental : linesDiffComputers.smart;\n\n\t\tconst originalLines = originalTextModel.getLinesContent();\n\t\tconst modifiedLines = modifiedTextModel.getLinesContent();\n\n\t\tconst result = diffAlgorithm.computeDiff(originalLines, modifiedLines, options);\n\n\t\tconst identical = (result.changes.length > 0 ? false : this._modelsAreIdentical(originalTextModel, modifiedTextModel));\n\n\t\treturn {\n\t\t\tidentical,\n\t\t\tquitEarly: result.quitEarly,\n\t\t\tchanges: result.changes.map(m => ([m.originalRange.startLineNumber, m.originalRange.endLineNumberExclusive, m.modifiedRange.startLineNumber, m.modifiedRange.endLineNumberExclusive, m.innerChanges?.map(m => [\n\t\t\t\tm.originalRange.startLineNumber,\n\t\t\t\tm.originalRange.startColumn,\n\t\t\t\tm.originalRange.endLineNumber,\n\t\t\t\tm.originalRange.endColumn,\n\t\t\t\tm.modifiedRange.startLineNumber,\n\t\t\t\tm.modifiedRange.startColumn,\n\t\t\t\tm.modifiedRange.endLineNumber,\n\t\t\t\tm.modifiedRange.endColumn,\n\t\t\t])]))\n\t\t};\n\t}\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,3)", @@ -17,16 +23,8 @@ "modifiedRange": "[4,5)", "innerChanges": [ { - "originalRange": "[4,69 -> 4,103]", - "modifiedRange": "[4,69 -> 4,88]" - }, - { - "originalRange": "[4,109 -> 4,110]", - "modifiedRange": "[4,94 -> 4,98]" - }, - { - "originalRange": "[4,114 -> 4,126]", - "modifiedRange": "[4,102 -> 4,103]" + "originalRange": "[4,69 -> 4,126]", + "modifiedRange": "[4,69 -> 4,103]" } ] }, @@ -35,12 +33,8 @@ "modifiedRange": "[11,12)", "innerChanges": [ { - "originalRange": "[11,61 -> 11,93]", - "modifiedRange": "[11,61 -> 11,63]" - }, - { - "originalRange": "[11,97 -> 11,101]", - "modifiedRange": "[11,67 -> 11,68]" + "originalRange": "[11,61 -> 11,101]", + "modifiedRange": "[11,61 -> 11,68]" } ] }, @@ -53,20 +47,8 @@ "modifiedRange": "[14,120 -> 14,162]" }, { - "originalRange": "[14,165 -> 14,178]", - "modifiedRange": "[14,173 -> 16,22]" - }, - { - "originalRange": "[14,181 -> 14,181]", - "modifiedRange": "[16,25 -> 16,30]" - }, - { - "originalRange": "[14,191 -> 14,192]", - "modifiedRange": "[16,40 -> 16,47]" - }, - { - "originalRange": "[14,196 -> 14,211]", - "modifiedRange": "[16,51 -> 17,1]" + "originalRange": "[14,165 -> 14,211]", + "modifiedRange": "[14,173 -> 17,1]" } ] }, @@ -79,36 +61,16 @@ "modifiedRange": "[20,1 -> 21,1]" }, { - "originalRange": "[17,8 -> 17,8]", - "modifiedRange": "[21,8 -> 21,17]" - }, - { - "originalRange": "[17,13 -> 17,14]", - "modifiedRange": "[21,22 -> 21,33]" - }, - { - "originalRange": "[17,20 -> 17,28]", - "modifiedRange": "[21,39 -> 21,39]" - }, - { - "originalRange": "[17,32 -> 17,40]", - "modifiedRange": "[21,43 -> 21,43]" + "originalRange": "[17,8 -> 17,40]", + "modifiedRange": "[21,8 -> 21,43]" }, { "originalRange": "[17,71 -> 17,72]", "modifiedRange": "[21,74 -> 22,1]" }, { - "originalRange": "[18,3 -> 19,26]", - "modifiedRange": "[23,3 -> 23,30]" - }, - { - "originalRange": "[19,32 -> 19,32]", - "modifiedRange": "[23,36 -> 23,56]" - }, - { - "originalRange": "[19,35 -> 23,4]", - "modifiedRange": "[23,59 -> 23,120]" + "originalRange": "[18,3 -> 23,4]", + "modifiedRange": "[23,3 -> 23,120]" } ] }, @@ -139,16 +101,8 @@ "modifiedRange": "[28,4 -> 29,36]" }, { - "originalRange": "[30,4 -> 30,6]", - "modifiedRange": "[30,4 -> 30,16]" - }, - { - "originalRange": "[30,10 -> 30,26]", - "modifiedRange": "[30,20 -> 34,16]" - }, - { - "originalRange": "[30,30 -> 30,31]", - "modifiedRange": "[34,20 -> 37,9]" + "originalRange": "[30,4 -> 30,31]", + "modifiedRange": "[30,4 -> 37,9]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/smart.expected.diff.json index a1e0ab440f9..f011be41a70 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "class Test {\n // ---- BEGIN diff --------------------------------------------------------------------------\n\n\tpublic async computeDiff(originalUrl: string, modifiedUrl: string, ignoreTrimWhitespace: boolean, maxComputationTime: number): Promise {\n\t\tconst original = this._getModel(originalUrl);\n\t\tconst modified = this._getModel(modifiedUrl);\n\t\tif (!original || !modified) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn EditorSimpleWorker.computeDiff(original, modified, ignoreTrimWhitespace, maxComputationTime);\n\t}\n\n\tpublic static computeDiff(originalTextModel: ICommonModel | ITextModel, modifiedTextModel: ICommonModel | ITextModel, ignoreTrimWhitespace: boolean, maxComputationTime: number): IDiffComputationResult | null {\n\t\tconst originalLines = originalTextModel.getLinesContent();\n\t\tconst modifiedLines = modifiedTextModel.getLinesContent();\n\t\tconst diffComputer = new DiffComputer(originalLines, modifiedLines, {\n\t\t\tshouldComputeCharChanges: true,\n\t\t\tshouldPostProcessCharChanges: true,\n\t\t\tshouldIgnoreTrimWhitespace: ignoreTrimWhitespace,\n\t\t\tshouldMakePrettyDiff: true,\n\t\t\tmaxComputationTime: maxComputationTime\n\t\t});\n\n\t\tconst diffResult = diffComputer.computeDiff();\n\t\tconst identical = (diffResult.changes.length > 0 ? false : this._modelsAreIdentical(originalTextModel, modifiedTextModel));\n\t\treturn {\n\t\t\tquitEarly: diffResult.quitEarly,\n\t\t\tidentical: identical,\n\t\t\tchanges: diffResult.changes\n\t\t};\n\t}\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "class Test {\n\t// ---- BEGIN diff --------------------------------------------------------------------------\n\n\tpublic async computeDiff(originalUrl: string, modifiedUrl: string, options: ILinesDiffComputerOptions): Promise {\n\t\tconst original = this._getModel(originalUrl);\n\t\tconst modified = this._getModel(modifiedUrl);\n\t\tif (!original || !modified) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn EditorSimpleWorker.computeDiff(original, modified, options);\n\t}\n\n\tpublic static computeDiff(originalTextModel: ICommonModel | ITextModel, modifiedTextModel: ICommonModel | ITextModel, options: ILinesDiffComputerOptions): IDiffComputationResult {\n\n\t\tconst diffAlgorithm: ILinesDiffComputer = options.diffAlgorithm === 'experimental' ? linesDiffComputers.experimental : linesDiffComputers.smart;\n\n\t\tconst originalLines = originalTextModel.getLinesContent();\n\t\tconst modifiedLines = modifiedTextModel.getLinesContent();\n\n\t\tconst result = diffAlgorithm.computeDiff(originalLines, modifiedLines, options);\n\n\t\tconst identical = (result.changes.length > 0 ? false : this._modelsAreIdentical(originalTextModel, modifiedTextModel));\n\n\t\treturn {\n\t\t\tidentical,\n\t\t\tquitEarly: result.quitEarly,\n\t\t\tchanges: result.changes.map(m => ([m.originalRange.startLineNumber, m.originalRange.endLineNumberExclusive, m.modifiedRange.startLineNumber, m.modifiedRange.endLineNumberExclusive, m.innerChanges?.map(m => [\n\t\t\t\tm.originalRange.startLineNumber,\n\t\t\t\tm.originalRange.startColumn,\n\t\t\t\tm.originalRange.endLineNumber,\n\t\t\t\tm.originalRange.endColumn,\n\t\t\t\tm.modifiedRange.startLineNumber,\n\t\t\t\tm.modifiedRange.startColumn,\n\t\t\t\tm.modifiedRange.endLineNumber,\n\t\t\t\tm.modifiedRange.endColumn,\n\t\t\t])]))\n\t\t};\n\t}\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,3)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-confusing/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-confusing/experimental.expected.diff.json index 0845c2f7fe0..ae0eb5c7342 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-confusing/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-confusing/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { URI } from 'vs/base/common/uri';\nimport { IRange } from 'vs/editor/common/core/range';\nimport { IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker';\nimport { TextEdit, IInplaceReplaceSupportResult } from 'vs/editor/common/languages';\nimport { IChange, IDiffComputationResult } from 'vs/editor/common/diff/diffComputer';\n\nexport class TestEditorWorkerService implements IEditorWorkerService {\n\n\tdeclare readonly _serviceBrand: undefined;\n\n\tcanComputeUnicodeHighlights(uri: URI): boolean { return false; }\n\tasync computedUnicodeHighlights(uri: URI): Promise { return { ranges: [], hasMore: false, ambiguousCharacterCount: 0, invisibleCharacterCount: 0, nonBasicAsciiCharacterCount: 0 }; }\n\tasync computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean, maxComputationTime: number): Promise { return null; }\n\tcanComputeDirtyDiff(original: URI, modified: URI): boolean { return false; }\n\tasync computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise { return null; }\n\tasync computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise { return undefined; }\n\tcanComputeWordRanges(resource: URI): boolean { return false; }\n\tasync computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] } | null> { return null; }\n\tcanNavigateValueSet(resource: URI): boolean { return false; }\n\tasync navigateValueSet(resource: URI, range: IRange, up: boolean): Promise { return null; }\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { URI } from 'vs/base/common/uri';\nimport { IRange } from 'vs/editor/common/core/range';\nimport { IDiffComputationResult, IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker';\nimport { TextEdit, IInplaceReplaceSupportResult } from 'vs/editor/common/languages';\nimport { IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider';\nimport { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer';\n\nexport class TestEditorWorkerService implements IEditorWorkerService {\n\n\tdeclare readonly _serviceBrand: undefined;\n\n\tcanComputeUnicodeHighlights(uri: URI): boolean { return false; }\n\tasync computedUnicodeHighlights(uri: URI): Promise { return { ranges: [], hasMore: false, ambiguousCharacterCount: 0, invisibleCharacterCount: 0, nonBasicAsciiCharacterCount: 0 }; }\n\tasync computeDiff(original: URI, modified: URI, options: IDocumentDiffProviderOptions): Promise { return null; }\n\tcanComputeDirtyDiff(original: URI, modified: URI): boolean { return false; }\n\tasync computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise { return null; }\n\tasync computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise { return undefined; }\n\tcanComputeWordRanges(resource: URI): boolean { return false; }\n\tasync computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] } | null> { return null; }\n\tcanNavigateValueSet(resource: URI): boolean { return false; }\n\tasync navigateValueSet(resource: URI, range: IRange, up: boolean): Promise { return null; }\n}\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[8,9)", @@ -35,12 +41,8 @@ "modifiedRange": "[19,20)", "innerChanges": [ { - "originalRange": "[18,50 -> 18,91]", - "modifiedRange": "[19,50 -> 19,82]" - }, - { - "originalRange": "[18,95 -> 18,107]", - "modifiedRange": "[19,86 -> 19,87]" + "originalRange": "[18,50 -> 18,107]", + "modifiedRange": "[19,50 -> 19,87]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-confusing/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-confusing/smart.expected.diff.json index 7ad5e5e6604..30bf9bae1ec 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-confusing/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-confusing/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { URI } from 'vs/base/common/uri';\nimport { IRange } from 'vs/editor/common/core/range';\nimport { IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker';\nimport { TextEdit, IInplaceReplaceSupportResult } from 'vs/editor/common/languages';\nimport { IChange, IDiffComputationResult } from 'vs/editor/common/diff/diffComputer';\n\nexport class TestEditorWorkerService implements IEditorWorkerService {\n\n\tdeclare readonly _serviceBrand: undefined;\n\n\tcanComputeUnicodeHighlights(uri: URI): boolean { return false; }\n\tasync computedUnicodeHighlights(uri: URI): Promise { return { ranges: [], hasMore: false, ambiguousCharacterCount: 0, invisibleCharacterCount: 0, nonBasicAsciiCharacterCount: 0 }; }\n\tasync computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean, maxComputationTime: number): Promise { return null; }\n\tcanComputeDirtyDiff(original: URI, modified: URI): boolean { return false; }\n\tasync computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise { return null; }\n\tasync computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise { return undefined; }\n\tcanComputeWordRanges(resource: URI): boolean { return false; }\n\tasync computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] } | null> { return null; }\n\tcanNavigateValueSet(resource: URI): boolean { return false; }\n\tasync navigateValueSet(resource: URI, range: IRange, up: boolean): Promise { return null; }\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { URI } from 'vs/base/common/uri';\nimport { IRange } from 'vs/editor/common/core/range';\nimport { IDiffComputationResult, IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker';\nimport { TextEdit, IInplaceReplaceSupportResult } from 'vs/editor/common/languages';\nimport { IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider';\nimport { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer';\n\nexport class TestEditorWorkerService implements IEditorWorkerService {\n\n\tdeclare readonly _serviceBrand: undefined;\n\n\tcanComputeUnicodeHighlights(uri: URI): boolean { return false; }\n\tasync computedUnicodeHighlights(uri: URI): Promise { return { ranges: [], hasMore: false, ambiguousCharacterCount: 0, invisibleCharacterCount: 0, nonBasicAsciiCharacterCount: 0 }; }\n\tasync computeDiff(original: URI, modified: URI, options: IDocumentDiffProviderOptions): Promise { return null; }\n\tcanComputeDirtyDiff(original: URI, modified: URI): boolean { return false; }\n\tasync computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise { return null; }\n\tasync computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise { return undefined; }\n\tcanComputeWordRanges(resource: URI): boolean { return false; }\n\tasync computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] } | null> { return null; }\n\tcanNavigateValueSet(resource: URI): boolean { return false; }\n\tasync navigateValueSet(resource: URI, range: IRange, up: boolean): Promise { return null; }\n}\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[8,9)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-diff-word-split/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-diff-word-split/experimental.expected.diff.json index 7a03e3e2009..9abcad4a94b 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-diff-word-split/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-diff-word-split/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { findLast } from 'vs/base/common/arrays';\nimport { Disposable } from 'vs/base/common/lifecycle';\nimport { ITransaction, observableValue, transaction } from 'vs/base/common/observable';\nimport { Range } from 'vs/editor/common/core/range';\nimport { ScrollType } from 'vs/editor/common/editorCommon';\nimport { IFooBar, IFoo } from 'foo';\n\nconsole.log(observableValue);\n\nconsole.log(observableValue);\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { findLast } from 'vs/base/common/arrays';\nimport { Disposable } from 'vs/base/common/lifecycle';\nimport { ITransaction, observableFromEvent, observableValue, transaction } from 'vs/base/common/observable';\nimport { Range } from 'vs/editor/common/core/range';\nimport { ScrollType } from 'vs/editor/common/editorCommon';\nimport { IFooBar, IBar, IFoo } from 'foo';\n\nconsole.log(observableFromEvent, observableValue);\n\nconsole.log(observableValue, observableFromEvent);\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[3,4)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-diff-word-split/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-diff-word-split/smart.expected.diff.json index ac0383a456b..3a111eefaca 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-diff-word-split/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-diff-word-split/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { findLast } from 'vs/base/common/arrays';\nimport { Disposable } from 'vs/base/common/lifecycle';\nimport { ITransaction, observableValue, transaction } from 'vs/base/common/observable';\nimport { Range } from 'vs/editor/common/core/range';\nimport { ScrollType } from 'vs/editor/common/editorCommon';\nimport { IFooBar, IFoo } from 'foo';\n\nconsole.log(observableValue);\n\nconsole.log(observableValue);\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { findLast } from 'vs/base/common/arrays';\nimport { Disposable } from 'vs/base/common/lifecycle';\nimport { ITransaction, observableFromEvent, observableValue, transaction } from 'vs/base/common/observable';\nimport { Range } from 'vs/editor/common/core/range';\nimport { ScrollType } from 'vs/editor/common/editorCommon';\nimport { IFooBar, IBar, IFoo } from 'foo';\n\nconsole.log(observableFromEvent, observableValue);\n\nconsole.log(observableValue, observableFromEvent);\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[3,4)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-example1/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-example1/experimental.expected.diff.json index d55f8972311..cc5f77b5dc8 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-example1/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-example1/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "export class EditorWorkerServiceDiffComputer implements IDiffComputer {\n\tconstructor(@IEditorWorkerService private readonly editorWorkerService: IEditorWorkerService) { }\n\n\tasync computeDiff(textModel1: ITextModel, textModel2: ITextModel): Promise {\n\t\tconst diffs = await this.editorWorkerService.computeDiff(textModel1.uri, textModel2.uri, false, 1000);\n\t\tif (!diffs || diffs.quitEarly) {\n\t\t\treturn null;\n\t\t}\n\t\treturn diffs.changes.map((c) => LineDiff.fromLineChange(c, textModel1, textModel2));\n\t}\n}\n\nfunction wait(ms: number): Promise {\n\treturn new Promise(r => setTimeout(r, ms));\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "export class EditorWorkerServiceDiffComputer implements IDiffComputer {\n\tconstructor(@IEditorWorkerService private readonly editorWorkerService: IEditorWorkerService) { }\n\n\tasync computeDiff(textModel1: ITextModel, textModel2: ITextModel): Promise {\n\t\tconst diffs = await this.editorWorkerService.computeDiff(textModel1.uri, textModel2.uri, false, 1000);\n\t\tif (!diffs || diffs.quitEarly) {\n\t\t\treturn null;\n\t\t}\n\t\treturn EditorWorkerServiceDiffComputer.fromDiffComputationResult(diffs, textModel1, textModel2);\n\t}\n\n\tpublic static fromDiffComputationResult(result: IDiffComputationResult, textModel1: ITextModel, textModel2: ITextModel): LineDiff[] {\n\t\treturn result.changes.map((c) => fromLineChange(c, textModel1, textModel2));\n\t}\n}\n\nfunction fromLineChange(lineChange: ILineChange, originalTextModel: ITextModel, modifiedTextModel: ITextModel): LineDiff {\n\tlet originalRange: LineRange;\n\tif (lineChange.originalEndLineNumber === 0) {\n\t\t// Insertion\n\t\toriginalRange = new LineRange(lineChange.originalStartLineNumber + 1, 0);\n\t} else {\n\t\toriginalRange = new LineRange(lineChange.originalStartLineNumber, lineChange.originalEndLineNumber - lineChange.originalStartLineNumber + 1);\n\t}\n\n\tlet modifiedRange: LineRange;\n\tif (lineChange.modifiedEndLineNumber === 0) {\n\t\t// Deletion\n\t\tmodifiedRange = new LineRange(lineChange.modifiedStartLineNumber + 1, 0);\n\t} else {\n\t\tmodifiedRange = new LineRange(lineChange.modifiedStartLineNumber, lineChange.modifiedEndLineNumber - lineChange.modifiedStartLineNumber + 1);\n\t}\n\n\tlet innerDiffs = lineChange.charChanges?.map(c => fromCharChange(c));\n\tif (!innerDiffs) {\n\t\tinnerDiffs = [diffFromLineRanges(originalRange, modifiedRange)];\n\t}\n\n\treturn new LineDiff(\n\t\toriginalTextModel,\n\t\toriginalRange,\n\t\tmodifiedTextModel,\n\t\tmodifiedRange,\n\t\tinnerDiffs\n\t);\n}\n\nfunction diffFromLineRanges(originalRange: LineRange, modifiedRange: LineRange): Diff {\n\t// [1,1) -> [100, 101)\n\n\tif (originalRange.startLineNumber !== 1 && modifiedRange.startLineNumber !== 1) {\n\n\t}\n\n\tlet original = new Range(\n\t\toriginalRange.startLineNumber - 1,\n\t\tNumber.MAX_SAFE_INTEGER,\n\t\toriginalRange.endLineNumberExclusive - 1,\n\t\tNumber.MAX_SAFE_INTEGER,\n\t);\n\n\tlet modified = new Range(\n\t\tmodifiedRange.startLineNumber - 1,\n\t\tNumber.MAX_SAFE_INTEGER,\n\t\tmodifiedRange.endLineNumberExclusive - 1,\n\t\tNumber.MAX_SAFE_INTEGER,\n\t);\n\n\treturn new Diff(\n\t\toriginal,\n\t\tmodified\n\t);\n}\n\nfunction fromCharChange(charChange: ICharChange): Diff {\n\treturn new Diff(\n\t\tnew Range(charChange.originalStartLineNumber, charChange.originalStartColumn, charChange.originalEndLineNumber, charChange.originalEndColumn),\n\t\tnew Range(charChange.modifiedStartLineNumber, charChange.modifiedStartColumn, charChange.modifiedEndLineNumber, charChange.modifiedEndColumn)\n\t);\n}\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[9,10)", @@ -25,16 +31,12 @@ "modifiedRange": "[17,80)", "innerChanges": [ { - "originalRange": "[13,10 -> 13,20]", - "modifiedRange": "[17,10 -> 21,62]" + "originalRange": "[13,10 -> 13,41]", + "modifiedRange": "[17,10 -> 35,18]" }, { - "originalRange": "[13,25 -> 13,41]", - "modifiedRange": "[21,67 -> 35,18]" - }, - { - "originalRange": "[14,2 -> 14,3]", - "modifiedRange": "[36,2 -> 39,3]" + "originalRange": "[14,2 -> 14,8]", + "modifiedRange": "[36,2 -> 39,8]" }, { "originalRange": "[14,13 -> 14,43]", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-example1/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-example1/smart.expected.diff.json index e865b3fa365..790a6dc2e6b 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-example1/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-example1/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "export class EditorWorkerServiceDiffComputer implements IDiffComputer {\n\tconstructor(@IEditorWorkerService private readonly editorWorkerService: IEditorWorkerService) { }\n\n\tasync computeDiff(textModel1: ITextModel, textModel2: ITextModel): Promise {\n\t\tconst diffs = await this.editorWorkerService.computeDiff(textModel1.uri, textModel2.uri, false, 1000);\n\t\tif (!diffs || diffs.quitEarly) {\n\t\t\treturn null;\n\t\t}\n\t\treturn diffs.changes.map((c) => LineDiff.fromLineChange(c, textModel1, textModel2));\n\t}\n}\n\nfunction wait(ms: number): Promise {\n\treturn new Promise(r => setTimeout(r, ms));\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "export class EditorWorkerServiceDiffComputer implements IDiffComputer {\n\tconstructor(@IEditorWorkerService private readonly editorWorkerService: IEditorWorkerService) { }\n\n\tasync computeDiff(textModel1: ITextModel, textModel2: ITextModel): Promise {\n\t\tconst diffs = await this.editorWorkerService.computeDiff(textModel1.uri, textModel2.uri, false, 1000);\n\t\tif (!diffs || diffs.quitEarly) {\n\t\t\treturn null;\n\t\t}\n\t\treturn EditorWorkerServiceDiffComputer.fromDiffComputationResult(diffs, textModel1, textModel2);\n\t}\n\n\tpublic static fromDiffComputationResult(result: IDiffComputationResult, textModel1: ITextModel, textModel2: ITextModel): LineDiff[] {\n\t\treturn result.changes.map((c) => fromLineChange(c, textModel1, textModel2));\n\t}\n}\n\nfunction fromLineChange(lineChange: ILineChange, originalTextModel: ITextModel, modifiedTextModel: ITextModel): LineDiff {\n\tlet originalRange: LineRange;\n\tif (lineChange.originalEndLineNumber === 0) {\n\t\t// Insertion\n\t\toriginalRange = new LineRange(lineChange.originalStartLineNumber + 1, 0);\n\t} else {\n\t\toriginalRange = new LineRange(lineChange.originalStartLineNumber, lineChange.originalEndLineNumber - lineChange.originalStartLineNumber + 1);\n\t}\n\n\tlet modifiedRange: LineRange;\n\tif (lineChange.modifiedEndLineNumber === 0) {\n\t\t// Deletion\n\t\tmodifiedRange = new LineRange(lineChange.modifiedStartLineNumber + 1, 0);\n\t} else {\n\t\tmodifiedRange = new LineRange(lineChange.modifiedStartLineNumber, lineChange.modifiedEndLineNumber - lineChange.modifiedStartLineNumber + 1);\n\t}\n\n\tlet innerDiffs = lineChange.charChanges?.map(c => fromCharChange(c));\n\tif (!innerDiffs) {\n\t\tinnerDiffs = [diffFromLineRanges(originalRange, modifiedRange)];\n\t}\n\n\treturn new LineDiff(\n\t\toriginalTextModel,\n\t\toriginalRange,\n\t\tmodifiedTextModel,\n\t\tmodifiedRange,\n\t\tinnerDiffs\n\t);\n}\n\nfunction diffFromLineRanges(originalRange: LineRange, modifiedRange: LineRange): Diff {\n\t// [1,1) -> [100, 101)\n\n\tif (originalRange.startLineNumber !== 1 && modifiedRange.startLineNumber !== 1) {\n\n\t}\n\n\tlet original = new Range(\n\t\toriginalRange.startLineNumber - 1,\n\t\tNumber.MAX_SAFE_INTEGER,\n\t\toriginalRange.endLineNumberExclusive - 1,\n\t\tNumber.MAX_SAFE_INTEGER,\n\t);\n\n\tlet modified = new Range(\n\t\tmodifiedRange.startLineNumber - 1,\n\t\tNumber.MAX_SAFE_INTEGER,\n\t\tmodifiedRange.endLineNumberExclusive - 1,\n\t\tNumber.MAX_SAFE_INTEGER,\n\t);\n\n\treturn new Diff(\n\t\toriginal,\n\t\tmodified\n\t);\n}\n\nfunction fromCharChange(charChange: ICharChange): Diff {\n\treturn new Diff(\n\t\tnew Range(charChange.originalStartLineNumber, charChange.originalStartColumn, charChange.originalEndLineNumber, charChange.originalEndColumn),\n\t\tnew Range(charChange.modifiedStartLineNumber, charChange.modifiedStartColumn, charChange.modifiedEndLineNumber, charChange.modifiedEndColumn)\n\t);\n}\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[9,10)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-example2-ts/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-example2-ts/experimental.expected.diff.json index a6bbd84c362..647fee613e5 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-example2-ts/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-example2-ts/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "function cloneTypeReference(source: TypeReference): TypeReference {\n const type = createType(source.flags);\n type.symbol = source.symbol;\n type.objectFlags = source.objectFlags;\n type.target = source.target;\n type.typeArguments = source.typeArguments;\n return type;\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "function cloneTypeReference(source: TypeReference): TypeReference {\n const type = createType(source.flags);\n type.symbol = source.symbol;\n type.objectFlags = source.objectFlags;\n type.target = source.target;\n type.resolvedTypeArguments = source.resolvedTypeArguments;\n return type;\n}\n\nfunction createDeferredTypeReference(): DeferredTypeReference {\n const aliasSymbol = getAliasSymbolForTypeNode(node);\n const aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);\n type.target = target;\n type.node = node;\n type.mapper = mapper;\n type.aliasSymbol = aliasSymbol;\n return type;\n}\n\nfunction getTypeArguments(type: TypeReference): ReadonlyArray {\n if (!type.resolvedTypeArguments) {\n const node = type.node;\n }\n return type.resolvedTypeArguments;\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[6,7)", @@ -25,8 +31,8 @@ "modifiedRange": "[19,26)", "innerChanges": [ { - "originalRange": "[9,1 -> 9,1]", - "modifiedRange": "[19,1 -> 26,1]" + "originalRange": "[8,2 -> 8,2]", + "modifiedRange": "[18,2 -> 25,2]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-example2-ts/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-example2-ts/smart.expected.diff.json index 9f38ce0b43c..9f5bbc5b267 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-example2-ts/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-example2-ts/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "function cloneTypeReference(source: TypeReference): TypeReference {\n const type = createType(source.flags);\n type.symbol = source.symbol;\n type.objectFlags = source.objectFlags;\n type.target = source.target;\n type.typeArguments = source.typeArguments;\n return type;\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "function cloneTypeReference(source: TypeReference): TypeReference {\n const type = createType(source.flags);\n type.symbol = source.symbol;\n type.objectFlags = source.objectFlags;\n type.target = source.target;\n type.resolvedTypeArguments = source.resolvedTypeArguments;\n return type;\n}\n\nfunction createDeferredTypeReference(): DeferredTypeReference {\n const aliasSymbol = getAliasSymbolForTypeNode(node);\n const aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);\n type.target = target;\n type.node = node;\n type.mapper = mapper;\n type.aliasSymbol = aliasSymbol;\n return type;\n}\n\nfunction getTypeArguments(type: TypeReference): ReadonlyArray {\n if (!type.resolvedTypeArguments) {\n const node = type.node;\n }\n return type.resolvedTypeArguments;\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[6,7)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-experimental-bug/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-experimental-bug/experimental.expected.diff.json index 8e1cddecad9..a1f9f55cf07 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-experimental-bug/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-experimental-bug/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "function compileProgram(): ExitStatus {\n // First get any syntactic errors. \n var diagnostics = program.getSyntacticDiagnostics();\n reportDiagnostics(diagnostics);\n\n // If we didn't have any syntactic errors, then also try getting the global and\n // semantic errors.\n if (diagnostics.length === 0) ", + "fileName": "./1.tst" + }, + "modified": { + "content": "function compileProgram(): ExitStatus {\n let diagnostics: Diagnostic[];\n \n // First get and report any syntactic errors.\n diagnostics = program.getSyntacticDiagnostics();\n\n // If we didn't have any syntactic errors, then also try getting the global and\n // semantic errors.\n if (diagnostics.length === 0) {", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,5)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-experimental-bug/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-experimental-bug/smart.expected.diff.json index ab6e1d63356..3411d7fbc1a 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-experimental-bug/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-experimental-bug/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "function compileProgram(): ExitStatus {\n // First get any syntactic errors. \n var diagnostics = program.getSyntacticDiagnostics();\n reportDiagnostics(diagnostics);\n\n // If we didn't have any syntactic errors, then also try getting the global and\n // semantic errors.\n if (diagnostics.length === 0) ", + "fileName": "./1.tst" + }, + "modified": { + "content": "function compileProgram(): ExitStatus {\n let diagnostics: Diagnostic[];\n \n // First get and report any syntactic errors.\n diagnostics = program.getSyntacticDiagnostics();\n\n // If we didn't have any syntactic errors, then also try getting the global and\n // semantic errors.\n if (diagnostics.length === 0) {", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,5)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing/experimental.expected.diff.json index 43782bc601f..14bfbbd115a 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IHistoryNavigationWidget } from 'vs/base/browser/history';\nimport { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';\nimport { FindInput, IFindInputOptions } from 'vs/base/browser/ui/findinput/findInput';\nimport { IReplaceInputOptions, ReplaceInput } from 'vs/base/browser/ui/findinput/replaceInput';\nimport { HistoryInputBox, IHistoryInputOptions } from 'vs/base/browser/ui/inputbox/inputBox';\nimport { KeyCode, KeyMod } from 'vs/base/common/keyCodes';\nimport { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';\nimport { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';\nimport { localize } from 'vs/nls';\nimport { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';\n\nexport const historyNavigationVisible = new RawContextKey('suggestWidgetVisible', false, localize('suggestWidgetVisible', \"Whether suggestion are visible\"));\n\nconst HistoryNavigationWidgetFocusContext = 'historyNavigationWidgetFocus';\nconst HistoryNavigationForwardsEnablementContext = 'historyNavigationForwardsEnabled';\nconst HistoryNavigationBackwardsEnablementContext = 'historyNavigationBackwardsEnabled';\n\nexport interface IHistoryNavigationContext extends IDisposable {\n\tscopedContextKeyService: IContextKeyService;\n\thistoryNavigationForwardsEnablement: IContextKey;\n\thistoryNavigationBackwardsEnablement: IContextKey;\n}\n\nlet lastFocusedWidget: IHistoryNavigationWidget | undefined = undefined;\nconst widgets: IHistoryNavigationWidget[] = [];\n\nexport function registerAndCreateHistoryNavigationContext(contextKeyService: IContextKeyService, widget: IHistoryNavigationWidget): IHistoryNavigationContext {\n\tif (widgets.includes(widget)) {\n\t\tthrow new Error('Cannot register the same widget multiple times');\n\t}\n\n\twidgets.push(widget);\n\tconst disposableStore = new DisposableStore();\n\tconst scopedContextKeyService = disposableStore.add(contextKeyService.createScoped(widget.element));\n\tconst historyNavigationWidgetFocus = new RawContextKey(HistoryNavigationWidgetFocusContext, false).bindTo(scopedContextKeyService);\n\tconst historyNavigationForwardsEnablement = new RawContextKey(HistoryNavigationForwardsEnablementContext, true).bindTo(scopedContextKeyService);\n\tconst historyNavigationBackwardsEnablement = new RawContextKey(HistoryNavigationBackwardsEnablementContext, true).bindTo(scopedContextKeyService);\n\n\tconst onDidFocus = () => {\n\t\thistoryNavigationWidgetFocus.set(true);\n\t\tlastFocusedWidget = widget;\n\t};\n\n\tconst onDidBlur = () => {\n\t\thistoryNavigationWidgetFocus.set(false);\n\t\tif (lastFocusedWidget === widget) {\n\t\t\tlastFocusedWidget = undefined;\n\t\t}\n\t};\n\n\t// Check for currently being focused\n\tif (widget.element === document.activeElement) {\n\t\tonDidFocus();\n\t}\n\n\tdisposableStore.add(widget.onDidFocus(() => onDidFocus()));\n\tdisposableStore.add(widget.onDidBlur(() => onDidBlur()));\n\tdisposableStore.add(toDisposable(() => {\n\t\twidgets.splice(widgets.indexOf(widget), 1);\n\t\tonDidBlur();\n\t}));\n\n\treturn {\n\t\tscopedContextKeyService,\n\t\thistoryNavigationForwardsEnablement,\n\t\thistoryNavigationBackwardsEnablement,\n\t\tdispose() {\n\t\t\tdisposableStore.dispose();\n\t\t}\n\t};\n}\n\nexport class ContextScopedHistoryInputBox extends HistoryInputBox {\n\n\tconstructor(container: HTMLElement, contextViewProvider: IContextViewProvider | undefined, options: IHistoryInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService\n\t) {\n\t\tsuper(container, contextViewProvider, options);\n\t\tthis._register(registerAndCreateHistoryNavigationContext(contextKeyService, this));\n\t}\n\n}\n\nexport class ContextScopedFindInput extends FindInput {\n\n\tconstructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider, options: IFindInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService\n\t) {\n\t\tsuper(container, contextViewProvider, options);\n\t\tthis._register(registerAndCreateHistoryNavigationContext(contextKeyService, this.inputBox));\n\t}\n}\n\nexport class ContextScopedReplaceInput extends ReplaceInput {\n\n\tconstructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider | undefined, options: IReplaceInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService, showReplaceOptions: boolean = false\n\t) {\n\t\tsuper(container, contextViewProvider, showReplaceOptions, options);\n\t\tthis._register(registerAndCreateHistoryNavigationContext(contextKeyService, this.inputBox));\n\t}\n\n}\n\nKeybindingsRegistry.registerCommandAndKeybindingRule({\n\tid: 'history.showPrevious',\n\tweight: KeybindingWeight.WorkbenchContrib,\n\twhen: ContextKeyExpr.and(\n\t\tContextKeyExpr.has(HistoryNavigationWidgetFocusContext),\n\t\tContextKeyExpr.equals(HistoryNavigationBackwardsEnablementContext, true),\n\t\thistoryNavigationVisible.isEqualTo(false),\n\t),\n\tprimary: KeyCode.UpArrow,\n\tsecondary: [KeyMod.Alt | KeyCode.UpArrow],\n\thandler: (accessor) => {\n\t\tlastFocusedWidget?.showPreviousValue();\n\t}\n});\n\nKeybindingsRegistry.registerCommandAndKeybindingRule({\n\tid: 'history.showNext',\n\tweight: KeybindingWeight.WorkbenchContrib,\n\twhen: ContextKeyExpr.and(\n\t\tContextKeyExpr.has(HistoryNavigationWidgetFocusContext),\n\t\tContextKeyExpr.equals(HistoryNavigationForwardsEnablementContext, true),\n\t\thistoryNavigationVisible.isEqualTo(false),\n\t),\n\tprimary: KeyCode.DownArrow,\n\tsecondary: [KeyMod.Alt | KeyCode.DownArrow],\n\thandler: (accessor) => {\n\t\tlastFocusedWidget?.showNextValue();\n\t}\n});\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IHistoryNavigationWidget } from 'vs/base/browser/history';\nimport { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';\nimport { FindInput, IFindInputOptions } from 'vs/base/browser/ui/findinput/findInput';\nimport { IReplaceInputOptions, ReplaceInput } from 'vs/base/browser/ui/findinput/replaceInput';\nimport { HistoryInputBox, IHistoryInputOptions } from 'vs/base/browser/ui/inputbox/inputBox';\nimport { KeyCode, KeyMod } from 'vs/base/common/keyCodes';\nimport { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';\nimport { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';\nimport { localize } from 'vs/nls';\nimport { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';\n\nexport const historyNavigationVisible = new RawContextKey('suggestWidgetVisible', false, localize('suggestWidgetVisible', \"Whether suggestion are visible\"));\n\nconst HistoryNavigationWidgetFocusContext = 'historyNavigationWidgetFocus';\nconst HistoryNavigationForwardsEnablementContext = 'historyNavigationForwardsEnabled';\nconst HistoryNavigationBackwardsEnablementContext = 'historyNavigationBackwardsEnabled';\n\nexport interface IHistoryNavigationContext extends IDisposable {\n\thistoryNavigationForwardsEnablement: IContextKey;\n\thistoryNavigationBackwardsEnablement: IContextKey;\n}\n\nlet lastFocusedWidget: IHistoryNavigationWidget | undefined = undefined;\nconst widgets: IHistoryNavigationWidget[] = [];\n\nexport function registerAndCreateHistoryNavigationContext(scopedContextKeyService: IContextKeyService, widget: IHistoryNavigationWidget): IHistoryNavigationContext {\n\tif (widgets.includes(widget)) {\n\t\tthrow new Error('Cannot register the same widget multiple times');\n\t}\n\n\twidgets.push(widget);\n\tconst disposableStore = new DisposableStore();\n\tconst historyNavigationWidgetFocus = new RawContextKey(HistoryNavigationWidgetFocusContext, false).bindTo(scopedContextKeyService);\n\tconst historyNavigationForwardsEnablement = new RawContextKey(HistoryNavigationForwardsEnablementContext, true).bindTo(scopedContextKeyService);\n\tconst historyNavigationBackwardsEnablement = new RawContextKey(HistoryNavigationBackwardsEnablementContext, true).bindTo(scopedContextKeyService);\n\n\tconst onDidFocus = () => {\n\t\thistoryNavigationWidgetFocus.set(true);\n\t\tlastFocusedWidget = widget;\n\t};\n\n\tconst onDidBlur = () => {\n\t\thistoryNavigationWidgetFocus.set(false);\n\t\tif (lastFocusedWidget === widget) {\n\t\t\tlastFocusedWidget = undefined;\n\t\t}\n\t};\n\n\t// Check for currently being focused\n\tif (widget.element === document.activeElement) {\n\t\tonDidFocus();\n\t}\n\n\tdisposableStore.add(widget.onDidFocus(() => onDidFocus()));\n\tdisposableStore.add(widget.onDidBlur(() => onDidBlur()));\n\tdisposableStore.add(toDisposable(() => {\n\t\twidgets.splice(widgets.indexOf(widget), 1);\n\t\tonDidBlur();\n\t}));\n\n\treturn {\n\t\thistoryNavigationForwardsEnablement,\n\t\thistoryNavigationBackwardsEnablement,\n\t\tdispose() {\n\t\t\tdisposableStore.dispose();\n\t\t}\n\t};\n}\n\nexport class ContextScopedHistoryInputBox extends HistoryInputBox {\n\n\tconstructor(container: HTMLElement, contextViewProvider: IContextViewProvider | undefined, options: IHistoryInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService\n\t) {\n\t\tsuper(container, contextViewProvider, options);\n\t\tconst scopedContextKeyService = this._register(contextKeyService.createScoped(this.element));\n\t\tthis._register(registerAndCreateHistoryNavigationContext(scopedContextKeyService, this));\n\t}\n\n}\n\nexport class ContextScopedFindInput extends FindInput {\n\n\tconstructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider, options: IFindInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService\n\t) {\n\t\tsuper(container, contextViewProvider, options);\n\t\tconst scopedContextKeyService = this._register(contextKeyService.createScoped(this.inputBox.element));\n\t\tthis._register(registerAndCreateHistoryNavigationContext(scopedContextKeyService, this.inputBox));\n\t}\n}\n\nexport class ContextScopedReplaceInput extends ReplaceInput {\n\n\tconstructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider | undefined, options: IReplaceInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService, showReplaceOptions: boolean = false\n\t) {\n\t\tsuper(container, contextViewProvider, showReplaceOptions, options);\n\t\tconst scopedContextKeyService = this._register(contextKeyService.createScoped(this.inputBox.element));\n\t\tthis._register(registerAndCreateHistoryNavigationContext(scopedContextKeyService, this.inputBox));\n\t}\n\n}\n\nKeybindingsRegistry.registerCommandAndKeybindingRule({\n\tid: 'history.showPrevious',\n\tweight: KeybindingWeight.WorkbenchContrib,\n\twhen: ContextKeyExpr.and(\n\t\tContextKeyExpr.has(HistoryNavigationWidgetFocusContext),\n\t\tContextKeyExpr.equals(HistoryNavigationBackwardsEnablementContext, true),\n\t\thistoryNavigationVisible.isEqualTo(false),\n\t),\n\tprimary: KeyCode.UpArrow,\n\tsecondary: [KeyMod.Alt | KeyCode.UpArrow],\n\thandler: (accessor) => {\n\t\tlastFocusedWidget?.showPreviousValue();\n\t}\n});\n\nKeybindingsRegistry.registerCommandAndKeybindingRule({\n\tid: 'history.showNext',\n\tweight: KeybindingWeight.WorkbenchContrib,\n\twhen: ContextKeyExpr.and(\n\t\tContextKeyExpr.has(HistoryNavigationWidgetFocusContext),\n\t\tContextKeyExpr.equals(HistoryNavigationForwardsEnablementContext, true),\n\t\thistoryNavigationVisible.isEqualTo(false),\n\t),\n\tprimary: KeyCode.DownArrow,\n\tsecondary: [KeyMod.Alt | KeyCode.DownArrow],\n\thandler: (accessor) => {\n\t\tlastFocusedWidget?.showNextValue();\n\t}\n});\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[24,25)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing/smart.expected.diff.json index 239c6fd8899..c7c0530ca5e 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IHistoryNavigationWidget } from 'vs/base/browser/history';\nimport { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';\nimport { FindInput, IFindInputOptions } from 'vs/base/browser/ui/findinput/findInput';\nimport { IReplaceInputOptions, ReplaceInput } from 'vs/base/browser/ui/findinput/replaceInput';\nimport { HistoryInputBox, IHistoryInputOptions } from 'vs/base/browser/ui/inputbox/inputBox';\nimport { KeyCode, KeyMod } from 'vs/base/common/keyCodes';\nimport { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';\nimport { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';\nimport { localize } from 'vs/nls';\nimport { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';\n\nexport const historyNavigationVisible = new RawContextKey('suggestWidgetVisible', false, localize('suggestWidgetVisible', \"Whether suggestion are visible\"));\n\nconst HistoryNavigationWidgetFocusContext = 'historyNavigationWidgetFocus';\nconst HistoryNavigationForwardsEnablementContext = 'historyNavigationForwardsEnabled';\nconst HistoryNavigationBackwardsEnablementContext = 'historyNavigationBackwardsEnabled';\n\nexport interface IHistoryNavigationContext extends IDisposable {\n\tscopedContextKeyService: IContextKeyService;\n\thistoryNavigationForwardsEnablement: IContextKey;\n\thistoryNavigationBackwardsEnablement: IContextKey;\n}\n\nlet lastFocusedWidget: IHistoryNavigationWidget | undefined = undefined;\nconst widgets: IHistoryNavigationWidget[] = [];\n\nexport function registerAndCreateHistoryNavigationContext(contextKeyService: IContextKeyService, widget: IHistoryNavigationWidget): IHistoryNavigationContext {\n\tif (widgets.includes(widget)) {\n\t\tthrow new Error('Cannot register the same widget multiple times');\n\t}\n\n\twidgets.push(widget);\n\tconst disposableStore = new DisposableStore();\n\tconst scopedContextKeyService = disposableStore.add(contextKeyService.createScoped(widget.element));\n\tconst historyNavigationWidgetFocus = new RawContextKey(HistoryNavigationWidgetFocusContext, false).bindTo(scopedContextKeyService);\n\tconst historyNavigationForwardsEnablement = new RawContextKey(HistoryNavigationForwardsEnablementContext, true).bindTo(scopedContextKeyService);\n\tconst historyNavigationBackwardsEnablement = new RawContextKey(HistoryNavigationBackwardsEnablementContext, true).bindTo(scopedContextKeyService);\n\n\tconst onDidFocus = () => {\n\t\thistoryNavigationWidgetFocus.set(true);\n\t\tlastFocusedWidget = widget;\n\t};\n\n\tconst onDidBlur = () => {\n\t\thistoryNavigationWidgetFocus.set(false);\n\t\tif (lastFocusedWidget === widget) {\n\t\t\tlastFocusedWidget = undefined;\n\t\t}\n\t};\n\n\t// Check for currently being focused\n\tif (widget.element === document.activeElement) {\n\t\tonDidFocus();\n\t}\n\n\tdisposableStore.add(widget.onDidFocus(() => onDidFocus()));\n\tdisposableStore.add(widget.onDidBlur(() => onDidBlur()));\n\tdisposableStore.add(toDisposable(() => {\n\t\twidgets.splice(widgets.indexOf(widget), 1);\n\t\tonDidBlur();\n\t}));\n\n\treturn {\n\t\tscopedContextKeyService,\n\t\thistoryNavigationForwardsEnablement,\n\t\thistoryNavigationBackwardsEnablement,\n\t\tdispose() {\n\t\t\tdisposableStore.dispose();\n\t\t}\n\t};\n}\n\nexport class ContextScopedHistoryInputBox extends HistoryInputBox {\n\n\tconstructor(container: HTMLElement, contextViewProvider: IContextViewProvider | undefined, options: IHistoryInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService\n\t) {\n\t\tsuper(container, contextViewProvider, options);\n\t\tthis._register(registerAndCreateHistoryNavigationContext(contextKeyService, this));\n\t}\n\n}\n\nexport class ContextScopedFindInput extends FindInput {\n\n\tconstructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider, options: IFindInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService\n\t) {\n\t\tsuper(container, contextViewProvider, options);\n\t\tthis._register(registerAndCreateHistoryNavigationContext(contextKeyService, this.inputBox));\n\t}\n}\n\nexport class ContextScopedReplaceInput extends ReplaceInput {\n\n\tconstructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider | undefined, options: IReplaceInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService, showReplaceOptions: boolean = false\n\t) {\n\t\tsuper(container, contextViewProvider, showReplaceOptions, options);\n\t\tthis._register(registerAndCreateHistoryNavigationContext(contextKeyService, this.inputBox));\n\t}\n\n}\n\nKeybindingsRegistry.registerCommandAndKeybindingRule({\n\tid: 'history.showPrevious',\n\tweight: KeybindingWeight.WorkbenchContrib,\n\twhen: ContextKeyExpr.and(\n\t\tContextKeyExpr.has(HistoryNavigationWidgetFocusContext),\n\t\tContextKeyExpr.equals(HistoryNavigationBackwardsEnablementContext, true),\n\t\thistoryNavigationVisible.isEqualTo(false),\n\t),\n\tprimary: KeyCode.UpArrow,\n\tsecondary: [KeyMod.Alt | KeyCode.UpArrow],\n\thandler: (accessor) => {\n\t\tlastFocusedWidget?.showPreviousValue();\n\t}\n});\n\nKeybindingsRegistry.registerCommandAndKeybindingRule({\n\tid: 'history.showNext',\n\tweight: KeybindingWeight.WorkbenchContrib,\n\twhen: ContextKeyExpr.and(\n\t\tContextKeyExpr.has(HistoryNavigationWidgetFocusContext),\n\t\tContextKeyExpr.equals(HistoryNavigationForwardsEnablementContext, true),\n\t\thistoryNavigationVisible.isEqualTo(false),\n\t),\n\tprimary: KeyCode.DownArrow,\n\tsecondary: [KeyMod.Alt | KeyCode.DownArrow],\n\thandler: (accessor) => {\n\t\tlastFocusedWidget?.showNextValue();\n\t}\n});\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IHistoryNavigationWidget } from 'vs/base/browser/history';\nimport { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';\nimport { FindInput, IFindInputOptions } from 'vs/base/browser/ui/findinput/findInput';\nimport { IReplaceInputOptions, ReplaceInput } from 'vs/base/browser/ui/findinput/replaceInput';\nimport { HistoryInputBox, IHistoryInputOptions } from 'vs/base/browser/ui/inputbox/inputBox';\nimport { KeyCode, KeyMod } from 'vs/base/common/keyCodes';\nimport { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';\nimport { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';\nimport { localize } from 'vs/nls';\nimport { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';\n\nexport const historyNavigationVisible = new RawContextKey('suggestWidgetVisible', false, localize('suggestWidgetVisible', \"Whether suggestion are visible\"));\n\nconst HistoryNavigationWidgetFocusContext = 'historyNavigationWidgetFocus';\nconst HistoryNavigationForwardsEnablementContext = 'historyNavigationForwardsEnabled';\nconst HistoryNavigationBackwardsEnablementContext = 'historyNavigationBackwardsEnabled';\n\nexport interface IHistoryNavigationContext extends IDisposable {\n\thistoryNavigationForwardsEnablement: IContextKey;\n\thistoryNavigationBackwardsEnablement: IContextKey;\n}\n\nlet lastFocusedWidget: IHistoryNavigationWidget | undefined = undefined;\nconst widgets: IHistoryNavigationWidget[] = [];\n\nexport function registerAndCreateHistoryNavigationContext(scopedContextKeyService: IContextKeyService, widget: IHistoryNavigationWidget): IHistoryNavigationContext {\n\tif (widgets.includes(widget)) {\n\t\tthrow new Error('Cannot register the same widget multiple times');\n\t}\n\n\twidgets.push(widget);\n\tconst disposableStore = new DisposableStore();\n\tconst historyNavigationWidgetFocus = new RawContextKey(HistoryNavigationWidgetFocusContext, false).bindTo(scopedContextKeyService);\n\tconst historyNavigationForwardsEnablement = new RawContextKey(HistoryNavigationForwardsEnablementContext, true).bindTo(scopedContextKeyService);\n\tconst historyNavigationBackwardsEnablement = new RawContextKey(HistoryNavigationBackwardsEnablementContext, true).bindTo(scopedContextKeyService);\n\n\tconst onDidFocus = () => {\n\t\thistoryNavigationWidgetFocus.set(true);\n\t\tlastFocusedWidget = widget;\n\t};\n\n\tconst onDidBlur = () => {\n\t\thistoryNavigationWidgetFocus.set(false);\n\t\tif (lastFocusedWidget === widget) {\n\t\t\tlastFocusedWidget = undefined;\n\t\t}\n\t};\n\n\t// Check for currently being focused\n\tif (widget.element === document.activeElement) {\n\t\tonDidFocus();\n\t}\n\n\tdisposableStore.add(widget.onDidFocus(() => onDidFocus()));\n\tdisposableStore.add(widget.onDidBlur(() => onDidBlur()));\n\tdisposableStore.add(toDisposable(() => {\n\t\twidgets.splice(widgets.indexOf(widget), 1);\n\t\tonDidBlur();\n\t}));\n\n\treturn {\n\t\thistoryNavigationForwardsEnablement,\n\t\thistoryNavigationBackwardsEnablement,\n\t\tdispose() {\n\t\t\tdisposableStore.dispose();\n\t\t}\n\t};\n}\n\nexport class ContextScopedHistoryInputBox extends HistoryInputBox {\n\n\tconstructor(container: HTMLElement, contextViewProvider: IContextViewProvider | undefined, options: IHistoryInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService\n\t) {\n\t\tsuper(container, contextViewProvider, options);\n\t\tconst scopedContextKeyService = this._register(contextKeyService.createScoped(this.element));\n\t\tthis._register(registerAndCreateHistoryNavigationContext(scopedContextKeyService, this));\n\t}\n\n}\n\nexport class ContextScopedFindInput extends FindInput {\n\n\tconstructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider, options: IFindInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService\n\t) {\n\t\tsuper(container, contextViewProvider, options);\n\t\tconst scopedContextKeyService = this._register(contextKeyService.createScoped(this.inputBox.element));\n\t\tthis._register(registerAndCreateHistoryNavigationContext(scopedContextKeyService, this.inputBox));\n\t}\n}\n\nexport class ContextScopedReplaceInput extends ReplaceInput {\n\n\tconstructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider | undefined, options: IReplaceInputOptions,\n\t\t@IContextKeyService contextKeyService: IContextKeyService, showReplaceOptions: boolean = false\n\t) {\n\t\tsuper(container, contextViewProvider, showReplaceOptions, options);\n\t\tconst scopedContextKeyService = this._register(contextKeyService.createScoped(this.inputBox.element));\n\t\tthis._register(registerAndCreateHistoryNavigationContext(scopedContextKeyService, this.inputBox));\n\t}\n\n}\n\nKeybindingsRegistry.registerCommandAndKeybindingRule({\n\tid: 'history.showPrevious',\n\tweight: KeybindingWeight.WorkbenchContrib,\n\twhen: ContextKeyExpr.and(\n\t\tContextKeyExpr.has(HistoryNavigationWidgetFocusContext),\n\t\tContextKeyExpr.equals(HistoryNavigationBackwardsEnablementContext, true),\n\t\thistoryNavigationVisible.isEqualTo(false),\n\t),\n\tprimary: KeyCode.UpArrow,\n\tsecondary: [KeyMod.Alt | KeyCode.UpArrow],\n\thandler: (accessor) => {\n\t\tlastFocusedWidget?.showPreviousValue();\n\t}\n});\n\nKeybindingsRegistry.registerCommandAndKeybindingRule({\n\tid: 'history.showNext',\n\tweight: KeybindingWeight.WorkbenchContrib,\n\twhen: ContextKeyExpr.and(\n\t\tContextKeyExpr.has(HistoryNavigationWidgetFocusContext),\n\t\tContextKeyExpr.equals(HistoryNavigationForwardsEnablementContext, true),\n\t\thistoryNavigationVisible.isEqualTo(false),\n\t),\n\tprimary: KeyCode.DownArrow,\n\tsecondary: [KeyMod.Alt | KeyCode.DownArrow],\n\thandler: (accessor) => {\n\t\tlastFocusedWidget?.showNextValue();\n\t}\n});\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[24,25)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing2/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing2/experimental.expected.diff.json index e77975d759a..eb1bd1ed77d 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing2/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing2/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { assertIsDefined } from 'vs/base/common/types';\nimport { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';\nimport { MenuId, Action2, IAction2Options, IMenuService, SubmenuItemAction } from 'vs/platform/actions/common/actions';\nimport { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';\nimport { parseLinkedText } from 'vs/base/common/linkedText';\nimport { IOpenerService } from 'vs/platform/opener/common/opener';", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { assertIsDefined } from 'vs/base/common/types';\nimport { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';\nimport { MenuId, Action2, IAction2Options, SubmenuItemAction } from 'vs/platform/actions/common/actions';\nimport { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';\nimport { parseLinkedText } from 'vs/base/common/linkedText';\nimport { IOpenerService } from 'vs/platform/opener/common/opener';", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[3,4)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing2/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing2/smart.expected.diff.json index 396591fc4dc..c8bb3f44a34 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing2/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing2/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { assertIsDefined } from 'vs/base/common/types';\nimport { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';\nimport { MenuId, Action2, IAction2Options, IMenuService, SubmenuItemAction } from 'vs/platform/actions/common/actions';\nimport { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';\nimport { parseLinkedText } from 'vs/base/common/linkedText';\nimport { IOpenerService } from 'vs/platform/opener/common/opener';", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { assertIsDefined } from 'vs/base/common/types';\nimport { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';\nimport { MenuId, Action2, IAction2Options, SubmenuItemAction } from 'vs/platform/actions/common/actions';\nimport { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';\nimport { parseLinkedText } from 'vs/base/common/linkedText';\nimport { IOpenerService } from 'vs/platform/opener/common/opener';", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[3,4)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing3/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing3/experimental.expected.diff.json index af483c2217d..93657f71909 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing3/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing3/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { assertIsDefined } from 'vs/base/common/types';\nimport { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';\nimport { MenuId, Action2, IAction2Options, IMenuServiceFooManager, ServiceManagerLocator } from 'vs/platform/actions/common/actions';\nimport { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';\nimport { parseLinkedText } from 'vs/base/common/linkedText';\nimport { IOpenerService } from 'vs/platform/opener/common/opener';\nISFM,SML,SFMKL\n\nconsole.log(MenuId, Action2, IAction2Options, IMenuServiceFooManager, ServiceManagerLocator);", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { assertIsDefined } from 'vs/base/common/types';\nimport { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';\nimport { MenuId, Action2, IAction2Options, ServiceManagerLocator } from 'vs/platform/actions/common/actions';\nimport { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';\nimport { parseLinkedText } from 'vs/base/common/linkedText';\nimport { IOpenerService } from 'vs/platform/opener/common/opener';\nSML\n\nconsole.log(MenuId, Action2, IAction2Options, ServiceManagerLocator);", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[3,4)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing3/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing3/smart.expected.diff.json index e8211fc3870..2c2c64d2b9c 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing3/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-fragmented-eager-diffing3/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { assertIsDefined } from 'vs/base/common/types';\nimport { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';\nimport { MenuId, Action2, IAction2Options, IMenuServiceFooManager, ServiceManagerLocator } from 'vs/platform/actions/common/actions';\nimport { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';\nimport { parseLinkedText } from 'vs/base/common/linkedText';\nimport { IOpenerService } from 'vs/platform/opener/common/opener';\nISFM,SML,SFMKL\n\nconsole.log(MenuId, Action2, IAction2Options, IMenuServiceFooManager, ServiceManagerLocator);", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { assertIsDefined } from 'vs/base/common/types';\nimport { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';\nimport { MenuId, Action2, IAction2Options, ServiceManagerLocator } from 'vs/platform/actions/common/actions';\nimport { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';\nimport { parseLinkedText } from 'vs/base/common/linkedText';\nimport { IOpenerService } from 'vs/platform/opener/common/opener';\nSML\n\nconsole.log(MenuId, Action2, IAction2Options, ServiceManagerLocator);", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[3,4)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-import-ws-affinity/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-import-ws-affinity/experimental.expected.diff.json index 322bb5fc3be..ff460a11892 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-import-ws-affinity/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-import-ws-affinity/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors';\nimport { EditorGutter, IGutterItemInfo, IGutterItemView } from '../editorGutter';\nimport { CodeEditorView } from './codeEditorView';\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors';\nimport { EditorGutter, IGutterItemInfo, IGutterItemView } from '../editorGutter';\nimport { CodeEditorView, TitleMenu } from './codeEditorView';\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[3,4)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-import-ws-affinity/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-import-ws-affinity/smart.expected.diff.json index 322bb5fc3be..ff460a11892 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-import-ws-affinity/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-import-ws-affinity/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors';\nimport { EditorGutter, IGutterItemInfo, IGutterItemView } from '../editorGutter';\nimport { CodeEditorView } from './codeEditorView';\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors';\nimport { EditorGutter, IGutterItemInfo, IGutterItemView } from '../editorGutter';\nimport { CodeEditorView, TitleMenu } from './codeEditorView';\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[3,4)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-insert/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-insert/experimental.expected.diff.json index d7b3e05ef3a..0b90a245ff9 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-insert/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-insert/experimental.expected.diff.json @@ -1,18 +1,20 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "const sequence2 = new SequenceFromIntArray(tgtDocLines);", + "fileName": "./1.tst" + }, + "modified": { + "content": "const sequence2 = new LineSequence(tgtDocLines, modifiedLines);", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[1,2)", "modifiedRange": "[1,2)", "innerChanges": [ { - "originalRange": "[1,23 -> 1,23]", - "modifiedRange": "[1,23 -> 1,27]" - }, - { - "originalRange": "[1,31 -> 1,43]", - "modifiedRange": "[1,35 -> 1,35]" + "originalRange": "[1,23 -> 1,43]", + "modifiedRange": "[1,23 -> 1,35]" }, { "originalRange": "[1,55 -> 1,55]", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-insert/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-insert/smart.expected.diff.json index d7b3e05ef3a..9e056decc6b 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-insert/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-insert/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "const sequence2 = new SequenceFromIntArray(tgtDocLines);", + "fileName": "./1.tst" + }, + "modified": { + "content": "const sequence2 = new LineSequence(tgtDocLines, modifiedLines);", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[1,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-methods/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-methods/experimental.expected.diff.json index c66254e9399..87ad9d8d82f 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-methods/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-methods/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "interface Test {\n getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[];\n\tgetViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData;\n getViewLineData(lineNumber: number): ViewLineData;\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "interface Test {\n getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[];\n getViewportViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData;\n getViewLineRenderingData(lineNumber: number): ViewLineRenderingData;\n getViewLineData(lineNumber: number): ViewLineData;\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[3,4)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-methods/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-methods/smart.expected.diff.json index 69e0286f34d..5034a4b336a 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-methods/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-methods/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "interface Test {\n getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[];\n\tgetViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData;\n getViewLineData(lineNumber: number): ViewLineData;\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "interface Test {\n getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[];\n getViewportViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData;\n getViewLineRenderingData(lineNumber: number): ViewLineRenderingData;\n getViewLineData(lineNumber: number): ViewLineData;\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[3,4)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-shift-to-ws/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-shift-to-ws/experimental.expected.diff.json index 807bbb2dcd9..01310ad5a3a 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-shift-to-ws/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-shift-to-ws/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "const childEndsAfterEnd = lengthGreaterThanEqual(nodeOffsetEnd, endOffset);\nif (childEndsAfterEnd) {\n // No child after this child in the requested window, don't recurse\n node = child;\n level++;\n continue whileLoop;\n}\n\nconst shouldContinue = collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, push, level + 1, levelPerBracketType);\nif (!shouldContinue) {\n return false;\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "const childEndsAfterEnd = lengthGreaterThanEqual(nodeOffsetEnd, endOffset);\nif (childEndsAfterEnd) {\n // No child after this child in the requested window, don't recurse\n node = child;\n level++;\n continue whileLoop;\n}\n\nconst shouldContinue = collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, push, level + 1, levelPerBracket + 1, levelPerBracketType);\nif (!shouldContinue) {\n return false;\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[9,10)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-shift-to-ws/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-shift-to-ws/smart.expected.diff.json index e155ae69309..70fb45226f8 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-shift-to-ws/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-shift-to-ws/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "const childEndsAfterEnd = lengthGreaterThanEqual(nodeOffsetEnd, endOffset);\nif (childEndsAfterEnd) {\n // No child after this child in the requested window, don't recurse\n node = child;\n level++;\n continue whileLoop;\n}\n\nconst shouldContinue = collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, push, level + 1, levelPerBracketType);\nif (!shouldContinue) {\n return false;\n}", + "fileName": "./1.tst" + }, + "modified": { + "content": "const childEndsAfterEnd = lengthGreaterThanEqual(nodeOffsetEnd, endOffset);\nif (childEndsAfterEnd) {\n // No child after this child in the requested window, don't recurse\n node = child;\n level++;\n continue whileLoop;\n}\n\nconst shouldContinue = collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, push, level + 1, levelPerBracket + 1, levelPerBracketType);\nif (!shouldContinue) {\n return false;\n}", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[9,10)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-shifting/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-shifting/experimental.expected.diff.json index 7cae68fdc45..20e487ad163 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-shifting/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-shifting/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "[\n\t{\n\t\t\"identifier\": {\n\t\t\t\"id\": \"pflannery.vscode-versionlens\",\n\t\t\t\"uuid\": \"07fc4a0a-11fc-4121-ba9a-f0d534c729d8\"\n\t\t},\n\t\t\"preRelease\": false,\n\t\t\"version\": \"1.0.9\",\n\t\t\"installed\": true\n\t},\n\t{\n\t\t\"identifier\": {\n\t\t\t\"id\": \"sumneko.lua\",\n\t\t\t\"uuid\": \"3a15b5a7-be12-47e3-8445-88ee3eabc8b2\"\n\t\t},\n\t\t\"preRelease\": false,\n\t\t\"version\": \"3.5.6\",\n\t\t\"installed\": true\n\t},\n\t{\n\t\t\"identifier\": {\n\t\t\t\"id\": \"vscode.bat\",\n\t\t\t\"uuid\": \"5ef96c58-076f-4167-8e40-62c9deb00496\"\n\t\t},\n\t\t\"preRelease\": false,\n\t\t\"version\": \"1.0.0\"\n\t}\n]", + "fileName": "./1.tst" + }, + "modified": { + "content": "[\n\t{\n\t\t\"identifier\": {\n\t\t\t\"id\": \"pflannery.vscode-versionlens\",\n\t\t\t\"uuid\": \"07fc4a0a-11fc-4121-ba9a-f0d534c729d8\"\n\t\t},\n\t\t\"preRelease\": false,\n\t\t\"version\": \"1.0.9\",\n\t\t\"installed\": true\n\t},\n\t{\n\t\t\"identifier\": {\n\t\t\t\"id\": \"vscode.bat\",\n\t\t\t\"uuid\": \"5ef96c58-076f-4167-8e40-62c9deb00496\"\n\t\t},\n\t\t\"preRelease\": false,\n\t\t\"version\": \"1.0.0\"\n\t}\n]", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[11,20)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-shifting/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-shifting/smart.expected.diff.json index 32fdb9dbdd9..ec24fdf0386 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-shifting/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-shifting/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "[\n\t{\n\t\t\"identifier\": {\n\t\t\t\"id\": \"pflannery.vscode-versionlens\",\n\t\t\t\"uuid\": \"07fc4a0a-11fc-4121-ba9a-f0d534c729d8\"\n\t\t},\n\t\t\"preRelease\": false,\n\t\t\"version\": \"1.0.9\",\n\t\t\"installed\": true\n\t},\n\t{\n\t\t\"identifier\": {\n\t\t\t\"id\": \"sumneko.lua\",\n\t\t\t\"uuid\": \"3a15b5a7-be12-47e3-8445-88ee3eabc8b2\"\n\t\t},\n\t\t\"preRelease\": false,\n\t\t\"version\": \"3.5.6\",\n\t\t\"installed\": true\n\t},\n\t{\n\t\t\"identifier\": {\n\t\t\t\"id\": \"vscode.bat\",\n\t\t\t\"uuid\": \"5ef96c58-076f-4167-8e40-62c9deb00496\"\n\t\t},\n\t\t\"preRelease\": false,\n\t\t\"version\": \"1.0.0\"\n\t}\n]", + "fileName": "./1.tst" + }, + "modified": { + "content": "[\n\t{\n\t\t\"identifier\": {\n\t\t\t\"id\": \"pflannery.vscode-versionlens\",\n\t\t\t\"uuid\": \"07fc4a0a-11fc-4121-ba9a-f0d534c729d8\"\n\t\t},\n\t\t\"preRelease\": false,\n\t\t\"version\": \"1.0.9\",\n\t\t\"installed\": true\n\t},\n\t{\n\t\t\"identifier\": {\n\t\t\t\"id\": \"vscode.bat\",\n\t\t\t\"uuid\": \"5ef96c58-076f-4167-8e40-62c9deb00496\"\n\t\t},\n\t\t\"preRelease\": false,\n\t\t\"version\": \"1.0.0\"\n\t}\n]", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[13,22)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-strings/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-strings/experimental.expected.diff.json index 1781d792519..163b0d65445 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-strings/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-strings/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "interface Test {\n /**\n * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter.\n * Defaults to 'mouseover'.\n */\n showFoldingControls?: 'always' | 'mouseover';\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "interface Test {\n /**\n * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter.\n * Defaults to 'mouseover'.\n */\n showFoldingControls?: 'always' | 'never' | 'mouseover';\n}\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[6,7)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-strings/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-strings/smart.expected.diff.json index eccec9997d5..0d9f51ff952 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-strings/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-strings/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "interface Test {\n /**\n * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter.\n * Defaults to 'mouseover'.\n */\n showFoldingControls?: 'always' | 'mouseover';\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "interface Test {\n /**\n * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter.\n * Defaults to 'mouseover'.\n */\n showFoldingControls?: 'always' | 'never' | 'mouseover';\n}\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[6,7)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/experimental.expected.diff.json index 7edda326b75..aa65f823a85 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "class Test {\n protected readonly checkboxesVisible = observableFromEvent(\n this.configurationService.onDidChangeConfiguration,\n () => /** @description checkboxesVisible */ this.configurationService.getValue('mergeEditor.showCheckboxes') ?? false\n );\n\n protected readonly showDeletionMarkers = observableFromEvent(\n this.configurationService.onDidChangeConfiguration,\n () => /** @description showDeletionMarkers */ this.configurationService.getValue('mergeEditor.showDeletionMarkers')\n );\n\n public readonly editor = this.instantiationService.createInstance(\n CodeEditorWidget,\n this.htmlElements.editor,\n {},\n {\n contributions: this.getEditorContributions(),\n }\n );\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "class Test {\n protected readonly checkboxesVisible = observableFromEvent(\n this.configurationService.onDidChangeConfiguration,\n () => /** @description checkboxesVisible */ this.configurationService.getValue('mergeEditor.showCheckboxes') ?? false\n );\n\n protected readonly showDeletionMarkers = observableFromEvent(\n this.configurationService.onDidChangeConfiguration,\n () => /** @description showDeletionMarkers */ this.configurationService.getValue('mergeEditor.showDeletionMarkers') ?? true\n );\n\n protected readonly useSimplifiedDecorations = observableFromEvent(\n this.configurationService.onDidChangeConfiguration,\n () => /** @description useSimplifiedDecorations */ this.configurationService.getValue('mergeEditor.useSimplifiedDecorations') ?? false\n );\n\n public readonly editor = this.instantiationService.createInstance(\n CodeEditorWidget,\n this.htmlElements.editor,\n {},\n {\n contributions: this.getEditorContributions(),\n }\n );\n}\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[9,10)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/smart.expected.diff.json index 7edda326b75..aa65f823a85 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-too-much-minimization/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "class Test {\n protected readonly checkboxesVisible = observableFromEvent(\n this.configurationService.onDidChangeConfiguration,\n () => /** @description checkboxesVisible */ this.configurationService.getValue('mergeEditor.showCheckboxes') ?? false\n );\n\n protected readonly showDeletionMarkers = observableFromEvent(\n this.configurationService.onDidChangeConfiguration,\n () => /** @description showDeletionMarkers */ this.configurationService.getValue('mergeEditor.showDeletionMarkers')\n );\n\n public readonly editor = this.instantiationService.createInstance(\n CodeEditorWidget,\n this.htmlElements.editor,\n {},\n {\n contributions: this.getEditorContributions(),\n }\n );\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "class Test {\n protected readonly checkboxesVisible = observableFromEvent(\n this.configurationService.onDidChangeConfiguration,\n () => /** @description checkboxesVisible */ this.configurationService.getValue('mergeEditor.showCheckboxes') ?? false\n );\n\n protected readonly showDeletionMarkers = observableFromEvent(\n this.configurationService.onDidChangeConfiguration,\n () => /** @description showDeletionMarkers */ this.configurationService.getValue('mergeEditor.showDeletionMarkers') ?? true\n );\n\n protected readonly useSimplifiedDecorations = observableFromEvent(\n this.configurationService.onDidChangeConfiguration,\n () => /** @description useSimplifiedDecorations */ this.configurationService.getValue('mergeEditor.useSimplifiedDecorations') ?? false\n );\n\n public readonly editor = this.instantiationService.createInstance(\n CodeEditorWidget,\n this.htmlElements.editor,\n {},\n {\n contributions: this.getEditorContributions(),\n }\n );\n}\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[9,10)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-unfragmented-diffing/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-unfragmented-diffing/experimental.expected.diff.json index c6d9f203ae5..9817a241a71 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-unfragmented-diffing/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-unfragmented-diffing/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';\nimport { Disposable } from 'vs/base/common/lifecycle';\nimport { ICodeEditor } from 'vs/editor/browser/editorBrowser';\nimport { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions';\nimport { IEditorContribution } from 'vs/editor/common/editorCommon';\nimport { EditorContextKeys } from 'vs/editor/common/editorContextKeys';\nimport * as languages from 'vs/editor/common/languages';\nimport { TriggerContext } from 'vs/editor/contrib/parameterHints/browser/parameterHintsModel';\nimport { Context } from 'vs/editor/contrib/parameterHints/browser/provideSignatureHelp';\nimport * as nls from 'vs/nls';\nimport { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';\nimport { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';\nimport { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';\nimport { ParameterHintsWidget } from './parameterHintsWidget';\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';\nimport { Lazy } from 'vs/base/common/lazy';\nimport { Disposable } from 'vs/base/common/lifecycle';\nimport { ICodeEditor } from 'vs/editor/browser/editorBrowser';\nimport { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions';\nimport { IEditorContribution } from 'vs/editor/common/editorCommon';\nimport { EditorContextKeys } from 'vs/editor/common/editorContextKeys';\nimport * as languages from 'vs/editor/common/languages';\nimport { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';\nimport { ParameterHintsModel, TriggerContext } from 'vs/editor/contrib/parameterHints/browser/parameterHintsModel';\nimport { Context } from 'vs/editor/contrib/parameterHints/browser/provideSignatureHelp';\nimport * as nls from 'vs/nls';\nimport { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';\nimport { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';\nimport { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';\nimport { ParameterHintsWidget } from './parameterHintsWidget';\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-unfragmented-diffing/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-unfragmented-diffing/smart.expected.diff.json index 9f3b700c75e..9bd86ea7b59 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-unfragmented-diffing/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-unfragmented-diffing/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';\nimport { Disposable } from 'vs/base/common/lifecycle';\nimport { ICodeEditor } from 'vs/editor/browser/editorBrowser';\nimport { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions';\nimport { IEditorContribution } from 'vs/editor/common/editorCommon';\nimport { EditorContextKeys } from 'vs/editor/common/editorContextKeys';\nimport * as languages from 'vs/editor/common/languages';\nimport { TriggerContext } from 'vs/editor/contrib/parameterHints/browser/parameterHintsModel';\nimport { Context } from 'vs/editor/contrib/parameterHints/browser/provideSignatureHelp';\nimport * as nls from 'vs/nls';\nimport { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';\nimport { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';\nimport { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';\nimport { ParameterHintsWidget } from './parameterHintsWidget';\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';\nimport { Lazy } from 'vs/base/common/lazy';\nimport { Disposable } from 'vs/base/common/lifecycle';\nimport { ICodeEditor } from 'vs/editor/browser/editorBrowser';\nimport { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions';\nimport { IEditorContribution } from 'vs/editor/common/editorCommon';\nimport { EditorContextKeys } from 'vs/editor/common/editorContextKeys';\nimport * as languages from 'vs/editor/common/languages';\nimport { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';\nimport { ParameterHintsModel, TriggerContext } from 'vs/editor/contrib/parameterHints/browser/parameterHintsModel';\nimport { Context } from 'vs/editor/contrib/parameterHints/browser/provideSignatureHelp';\nimport * as nls from 'vs/nls';\nimport { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';\nimport { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';\nimport { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';\nimport { ParameterHintsWidget } from './parameterHintsWidget';\n", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[2,2)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-unit-test/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-unit-test/experimental.expected.diff.json index a37e3ebe187..c14aaa445f8 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-unit-test/experimental.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-unit-test/experimental.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "test(() => {\n it(() => {\n console.log(1);\n })\n\n it(() => {\n })\n});\n\ntest(() => {\n it(() => {\n console.log(1);\n })\n\n it(() => {\n })\n});", + "fileName": "./1.tst" + }, + "modified": { + "content": "test(() => {\n it(() => {\n console.log(1);\n })\n\n it(() => {\n2 console.log(2);\n })\n\n it(() => {\n \n })\n});\n\ntest(() => {\n it(() => {\n console.log(1);\n })\n\n it(() => {\n })\n\n it(() => {\n \n })\n});", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[7,7)", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-unit-test/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-unit-test/smart.expected.diff.json index 4c25222b3b4..92390d02f61 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-unit-test/smart.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-unit-test/smart.expected.diff.json @@ -1,6 +1,12 @@ { - "originalFileName": "./1.tst", - "modifiedFileName": "./2.tst", + "original": { + "content": "test(() => {\n it(() => {\n console.log(1);\n })\n\n it(() => {\n })\n});\n\ntest(() => {\n it(() => {\n console.log(1);\n })\n\n it(() => {\n })\n});", + "fileName": "./1.tst" + }, + "modified": { + "content": "test(() => {\n it(() => {\n console.log(1);\n })\n\n it(() => {\n2 console.log(2);\n })\n\n it(() => {\n \n })\n});\n\ntest(() => {\n it(() => {\n console.log(1);\n })\n\n it(() => {\n })\n\n it(() => {\n \n })\n});", + "fileName": "./2.tst" + }, "diffs": [ { "originalRange": "[7,7)", diff --git a/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/1.tst b/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/1.tst new file mode 100644 index 00000000000..d4975329f03 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/1.tst @@ -0,0 +1,79 @@ +// test case 1: +{ + const abc = 1; +} + +// test case 2: +{ + const private = 1; +} + +// test case 3: +{ + const abc1 = 1; +} + +// test case 4: +{ + const index = 1; +} + +// test case 5: +{ + const InlineDecoration = 1; +} + +// test case 6: +{ + const _getDecorationsInRange = 1; +} + +// test case 7: +{ + const lord = 1; +} + +// test case 8: +{ + const abc1 = 1; +} + +// test case 1: +{ + // hello world +} + +// test case 2: +{ + // optimizeSequenceDiffs +} + +// test case 3: +{ + const optequffs = 1; +} + +// test case 4: +{ + const abc = 1; +} + +// test case 5: +{ + const abc = 1; +} + +// test case 6: +{ + const abc = 1; +} + +// test case 7: +{ + const abc = 1; +} + +// test case 8: +{ + const abc = 1; +} diff --git a/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/2.tst b/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/2.tst new file mode 100644 index 00000000000..7dc1e732506 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/2.tst @@ -0,0 +1,79 @@ +// test case 1: +{ + const asciiLower = 1; +} + +// test case 2: +{ + const protected = 1; +} + +// test case 3: +{ + const abc2 = 1; +} + +// test case 4: +{ + const undefined = 1; +} + +// test case 5: +{ + const IDecorationsViewportData = 1; +} + +// test case 6: +{ + const configuration = 1; +} + +// test case 7: +{ + const helloWorld = 1; +} + +// test case 8: +{ + const abc1 = 1; +} + +// test case 1: +{ + // helwor +} + +// test case 2: +{ + // optimize Sequence Diffs +} + +// test case 3: +{ + const optimize Sequence Diffs = 1; +} + +// test case 4: +{ + const abc = 1; +} + +// test case 5: +{ + const abc = 1; +} + +// test case 6: +{ + const abc = 1; +} + +// test case 7: +{ + const abc = 1; +} + +// test case 8: +{ + const abc = 1; +} diff --git a/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/experimental.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/experimental.expected.diff.json new file mode 100644 index 00000000000..5742291665d --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/experimental.expected.diff.json @@ -0,0 +1,116 @@ +{ + "original": { + "content": "// test case 1:\n{\n\tconst abc = 1;\n}\n\n// test case 2:\n{\n\tconst private = 1;\n}\n\n// test case 3:\n{\n\tconst abc1 = 1;\n}\n\n// test case 4:\n{\n\tconst index = 1;\n}\n\n// test case 5:\n{\n\tconst InlineDecoration = 1;\n}\n\n// test case 6:\n{\n\tconst _getDecorationsInRange = 1;\n}\n\n// test case 7:\n{\n\tconst lord = 1;\n}\n\n// test case 8:\n{\n\tconst abc1 = 1;\n}\n\n// test case 1:\n{\n\t// hello world\n}\n\n// test case 2:\n{\n\t// optimizeSequenceDiffs\n}\n\n// test case 3:\n{\n\tconst optequffs = 1;\n}\n\n// test case 4:\n{\n\tconst abc = 1;\n}\n\n// test case 5:\n{\n\tconst abc = 1;\n}\n\n// test case 6:\n{\n\tconst abc = 1;\n}\n\n// test case 7:\n{\n\tconst abc = 1;\n}\n\n// test case 8:\n{\n\tconst abc = 1;\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "// test case 1:\n{\n\tconst asciiLower = 1;\n}\n\n// test case 2:\n{\n\tconst protected = 1;\n}\n\n// test case 3:\n{\n\tconst abc2 = 1;\n}\n\n// test case 4:\n{\n\tconst undefined = 1;\n}\n\n// test case 5:\n{\n\tconst IDecorationsViewportData = 1;\n}\n\n// test case 6:\n{\n\tconst configuration = 1;\n}\n\n// test case 7:\n{\n\tconst helloWorld = 1;\n}\n\n// test case 8:\n{\n\tconst abc1 = 1;\n}\n\n// test case 1:\n{\n\t// helwor\n}\n\n// test case 2:\n{\n\t// optimize Sequence Diffs\n}\n\n// test case 3:\n{\n\tconst optimize Sequence Diffs = 1;\n}\n\n// test case 4:\n{\n\tconst abc = 1;\n}\n\n// test case 5:\n{\n\tconst abc = 1;\n}\n\n// test case 6:\n{\n\tconst abc = 1;\n}\n\n// test case 7:\n{\n\tconst abc = 1;\n}\n\n// test case 8:\n{\n\tconst abc = 1;\n}\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[3,4)", + "modifiedRange": "[3,4)", + "innerChanges": [ + { + "originalRange": "[3,8 -> 3,11]", + "modifiedRange": "[3,8 -> 3,18]" + } + ] + }, + { + "originalRange": "[8,9)", + "modifiedRange": "[8,9)", + "innerChanges": [ + { + "originalRange": "[8,8 -> 8,15]", + "modifiedRange": "[8,8 -> 8,17]" + } + ] + }, + { + "originalRange": "[13,14)", + "modifiedRange": "[13,14)", + "innerChanges": [ + { + "originalRange": "[13,11 -> 13,12]", + "modifiedRange": "[13,11 -> 13,12]" + } + ] + }, + { + "originalRange": "[18,19)", + "modifiedRange": "[18,19)", + "innerChanges": [ + { + "originalRange": "[18,8 -> 18,13]", + "modifiedRange": "[18,8 -> 18,17]" + } + ] + }, + { + "originalRange": "[23,24)", + "modifiedRange": "[23,24)", + "innerChanges": [ + { + "originalRange": "[23,8 -> 23,24]", + "modifiedRange": "[23,8 -> 23,32]" + } + ] + }, + { + "originalRange": "[28,29)", + "modifiedRange": "[28,29)", + "innerChanges": [ + { + "originalRange": "[28,8 -> 28,30]", + "modifiedRange": "[28,8 -> 28,21]" + } + ] + }, + { + "originalRange": "[33,34)", + "modifiedRange": "[33,34)", + "innerChanges": [ + { + "originalRange": "[33,8 -> 33,12]", + "modifiedRange": "[33,8 -> 33,18]" + } + ] + }, + { + "originalRange": "[43,44)", + "modifiedRange": "[43,44)", + "innerChanges": [ + { + "originalRange": "[43,5 -> 43,16]", + "modifiedRange": "[43,5 -> 43,11]" + } + ] + }, + { + "originalRange": "[48,49)", + "modifiedRange": "[48,49)", + "innerChanges": [ + { + "originalRange": "[48,13 -> 48,13]", + "modifiedRange": "[48,13 -> 48,14]" + }, + { + "originalRange": "[48,21 -> 48,21]", + "modifiedRange": "[48,22 -> 48,23]" + } + ] + }, + { + "originalRange": "[53,54)", + "modifiedRange": "[53,54)", + "innerChanges": [ + { + "originalRange": "[53,8 -> 53,17]", + "modifiedRange": "[53,8 -> 53,31]" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/smart.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/smart.expected.diff.json new file mode 100644 index 00000000000..8f9a20db404 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/smart.expected.diff.json @@ -0,0 +1,132 @@ +{ + "original": { + "content": "// test case 1:\n{\n\tconst abc = 1;\n}\n\n// test case 2:\n{\n\tconst private = 1;\n}\n\n// test case 3:\n{\n\tconst abc1 = 1;\n}\n\n// test case 4:\n{\n\tconst index = 1;\n}\n\n// test case 5:\n{\n\tconst InlineDecoration = 1;\n}\n\n// test case 6:\n{\n\tconst _getDecorationsInRange = 1;\n}\n\n// test case 7:\n{\n\tconst lord = 1;\n}\n\n// test case 8:\n{\n\tconst abc1 = 1;\n}\n\n// test case 1:\n{\n\t// hello world\n}\n\n// test case 2:\n{\n\t// optimizeSequenceDiffs\n}\n\n// test case 3:\n{\n\tconst optequffs = 1;\n}\n\n// test case 4:\n{\n\tconst abc = 1;\n}\n\n// test case 5:\n{\n\tconst abc = 1;\n}\n\n// test case 6:\n{\n\tconst abc = 1;\n}\n\n// test case 7:\n{\n\tconst abc = 1;\n}\n\n// test case 8:\n{\n\tconst abc = 1;\n}\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "// test case 1:\n{\n\tconst asciiLower = 1;\n}\n\n// test case 2:\n{\n\tconst protected = 1;\n}\n\n// test case 3:\n{\n\tconst abc2 = 1;\n}\n\n// test case 4:\n{\n\tconst undefined = 1;\n}\n\n// test case 5:\n{\n\tconst IDecorationsViewportData = 1;\n}\n\n// test case 6:\n{\n\tconst configuration = 1;\n}\n\n// test case 7:\n{\n\tconst helloWorld = 1;\n}\n\n// test case 8:\n{\n\tconst abc1 = 1;\n}\n\n// test case 1:\n{\n\t// helwor\n}\n\n// test case 2:\n{\n\t// optimize Sequence Diffs\n}\n\n// test case 3:\n{\n\tconst optimize Sequence Diffs = 1;\n}\n\n// test case 4:\n{\n\tconst abc = 1;\n}\n\n// test case 5:\n{\n\tconst abc = 1;\n}\n\n// test case 6:\n{\n\tconst abc = 1;\n}\n\n// test case 7:\n{\n\tconst abc = 1;\n}\n\n// test case 8:\n{\n\tconst abc = 1;\n}\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[3,4)", + "modifiedRange": "[3,4)", + "innerChanges": [ + { + "originalRange": "[3,9 -> 3,11]", + "modifiedRange": "[3,9 -> 3,18]" + } + ] + }, + { + "originalRange": "[8,9)", + "modifiedRange": "[8,9)", + "innerChanges": [ + { + "originalRange": "[8,10 -> 8,15]", + "modifiedRange": "[8,10 -> 8,17]" + } + ] + }, + { + "originalRange": "[13,14)", + "modifiedRange": "[13,14)", + "innerChanges": [ + { + "originalRange": "[13,11 -> 13,12]", + "modifiedRange": "[13,11 -> 13,12]" + } + ] + }, + { + "originalRange": "[18,19)", + "modifiedRange": "[18,19)", + "innerChanges": [ + { + "originalRange": "[18,8 -> 18,13]", + "modifiedRange": "[18,8 -> 18,17]" + } + ] + }, + { + "originalRange": "[23,24)", + "modifiedRange": "[23,24)", + "innerChanges": [ + { + "originalRange": "[23,9 -> 23,14]", + "modifiedRange": "[23,9 -> 23,9]" + }, + { + "originalRange": "[23,24 -> 23,24]", + "modifiedRange": "[23,19 -> 23,32]" + } + ] + }, + { + "originalRange": "[28,29)", + "modifiedRange": "[28,29)", + "innerChanges": [ + { + "originalRange": "[28,8 -> 28,16]", + "modifiedRange": "[28,8 -> 28,15]" + }, + { + "originalRange": "[28,22 -> 28,30]", + "modifiedRange": "[28,21 -> 28,21]" + } + ] + }, + { + "originalRange": "[33,34)", + "modifiedRange": "[33,34)", + "innerChanges": [ + { + "originalRange": "[33,8 -> 33,11]", + "modifiedRange": "[33,8 -> 33,17]" + } + ] + }, + { + "originalRange": "[43,44)", + "modifiedRange": "[43,44)", + "innerChanges": [ + { + "originalRange": "[43,8 -> 43,11]", + "modifiedRange": "[43,8 -> 43,8]" + }, + { + "originalRange": "[43,14 -> 43,16]", + "modifiedRange": "[43,11 -> 43,11]" + } + ] + }, + { + "originalRange": "[48,49)", + "modifiedRange": "[48,49)", + "innerChanges": [ + { + "originalRange": "[48,13 -> 48,13]", + "modifiedRange": "[48,13 -> 48,14]" + }, + { + "originalRange": "[48,21 -> 48,21]", + "modifiedRange": "[48,22 -> 48,23]" + } + ] + }, + { + "originalRange": "[53,54)", + "modifiedRange": "[53,54)", + "innerChanges": [ + { + "originalRange": "[53,11 -> 53,11]", + "modifiedRange": "[53,11 -> 53,18]" + }, + { + "originalRange": "[53,14 -> 53,14]", + "modifiedRange": "[53,21 -> 53,28]" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts b/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts new file mode 100644 index 00000000000..9b2fd2181a0 --- /dev/null +++ b/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as 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'; + +suite('lineRangeMapping', () => { + test('lineRangeMapping', () => { + // {[2,1 -> 3,1]->[2,1 -> 2,1]} + assert.deepStrictEqual( + getLineRangeMapping( + new RangeMapping( + new Range(2, 1, 3, 1), + new Range(2, 1, 2, 1) + ), + [ + 'const abc = "helloworld".split("");', + '', + '' + ], + [ + 'const asciiLower = "helloworld".split("");', + '' + ] + ).toString(), + "{[3,4)->[3,3)}" + ); + }); +}); diff --git a/src/vs/loader.js b/src/vs/loader.js index 67ef8665099..5c71e7aacf5 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -18,13 +18,33 @@ *--------------------------------------------------------------------------------------------- *--------------------------------------------------------------------------------------------- *--------------------------------------------------------------------------------------------*/ -var _amdLoaderGlobal = this; -var _commonjsGlobal = typeof global === 'object' ? global : {}; +const _amdLoaderGlobal = this; +const _commonjsGlobal = typeof global === 'object' ? global : {}; var AMDLoader; (function (AMDLoader) { AMDLoader.global = _amdLoaderGlobal; - var Environment = /** @class */ (function () { - function Environment() { + class Environment { + get isWindows() { + this._detect(); + return this._isWindows; + } + get isNode() { + this._detect(); + return this._isNode; + } + get isElectronRenderer() { + this._detect(); + return this._isElectronRenderer; + } + get isWebWorker() { + this._detect(); + return this._isWebWorker; + } + get isElectronNodeIntegrationWebWorker() { + this._detect(); + return this._isElectronNodeIntegrationWebWorker; + } + constructor() { this._detected = false; this._isWindows = false; this._isNode = false; @@ -32,47 +52,7 @@ var AMDLoader; this._isWebWorker = false; this._isElectronNodeIntegrationWebWorker = false; } - Object.defineProperty(Environment.prototype, "isWindows", { - get: function () { - this._detect(); - return this._isWindows; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Environment.prototype, "isNode", { - get: function () { - this._detect(); - return this._isNode; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Environment.prototype, "isElectronRenderer", { - get: function () { - this._detect(); - return this._isElectronRenderer; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Environment.prototype, "isWebWorker", { - get: function () { - this._detect(); - return this._isWebWorker; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Environment.prototype, "isElectronNodeIntegrationWebWorker", { - get: function () { - this._detect(); - return this._isElectronNodeIntegrationWebWorker; - }, - enumerable: false, - configurable: true - }); - Environment.prototype._detect = function () { + _detect() { if (this._detected) { return; } @@ -82,8 +62,8 @@ var AMDLoader; this._isElectronRenderer = (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer'); this._isWebWorker = (typeof AMDLoader.global.importScripts === 'function'); this._isElectronNodeIntegrationWebWorker = this._isWebWorker && (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'worker'); - }; - Environment._isWindows = function () { + } + static _isWindows() { if (typeof navigator !== 'undefined') { if (navigator.userAgent && navigator.userAgent.indexOf('Windows') >= 0) { return true; @@ -93,9 +73,8 @@ var AMDLoader; return (process.platform === 'win32'); } return false; - }; - return Environment; - }()); + } + } AMDLoader.Environment = Environment; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- @@ -104,40 +83,35 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - var LoaderEvent = /** @class */ (function () { - function LoaderEvent(type, detail, timestamp) { + class LoaderEvent { + constructor(type, detail, timestamp) { this.type = type; this.detail = detail; this.timestamp = timestamp; } - return LoaderEvent; - }()); + } AMDLoader.LoaderEvent = LoaderEvent; - var LoaderEventRecorder = /** @class */ (function () { - function LoaderEventRecorder(loaderAvailableTimestamp) { - this._events = [new LoaderEvent(1 /* LoaderAvailable */, '', loaderAvailableTimestamp)]; + class LoaderEventRecorder { + constructor(loaderAvailableTimestamp) { + this._events = [new LoaderEvent(1 /* LoaderEventType.LoaderAvailable */, '', loaderAvailableTimestamp)]; } - LoaderEventRecorder.prototype.record = function (type, detail) { + record(type, detail) { this._events.push(new LoaderEvent(type, detail, AMDLoader.Utilities.getHighPerformanceTimestamp())); - }; - LoaderEventRecorder.prototype.getEvents = function () { - return this._events; - }; - return LoaderEventRecorder; - }()); - AMDLoader.LoaderEventRecorder = LoaderEventRecorder; - var NullLoaderEventRecorder = /** @class */ (function () { - function NullLoaderEventRecorder() { } - NullLoaderEventRecorder.prototype.record = function (type, detail) { + getEvents() { + return this._events; + } + } + AMDLoader.LoaderEventRecorder = LoaderEventRecorder; + class NullLoaderEventRecorder { + record(type, detail) { // Nothing to do - }; - NullLoaderEventRecorder.prototype.getEvents = function () { + } + getEvents() { return []; - }; - NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); - return NullLoaderEventRecorder; - }()); + } + } + NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- @@ -146,13 +120,11 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - var Utilities = /** @class */ (function () { - function Utilities() { - } + class Utilities { /** * This method does not take care of / vs \ */ - Utilities.fileUriToFilePath = function (isWindows, uri) { + static fileUriToFilePath(isWindows, uri) { uri = decodeURI(uri).replace(/%23/g, '#'); if (isWindows) { if (/^file:\/\/\//.test(uri)) { @@ -170,41 +142,41 @@ var AMDLoader; } // Not sure... return uri; - }; - Utilities.startsWith = function (haystack, needle) { + } + static startsWith(haystack, needle) { return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; - }; - Utilities.endsWith = function (haystack, needle) { + } + static endsWith(haystack, needle) { return haystack.length >= needle.length && haystack.substr(haystack.length - needle.length) === needle; - }; + } // only check for "?" before "#" to ensure that there is a real Query-String - Utilities.containsQueryString = function (url) { + static containsQueryString(url) { return /^[^\#]*\?/gi.test(url); - }; + } /** * Does `url` start with http:// or https:// or file:// or / ? */ - Utilities.isAbsolutePath = function (url) { + static isAbsolutePath(url) { return /^((http:\/\/)|(https:\/\/)|(file:\/\/)|(\/))/.test(url); - }; - Utilities.forEachProperty = function (obj, callback) { + } + static forEachProperty(obj, callback) { if (obj) { - var key = void 0; + let key; for (key in obj) { if (obj.hasOwnProperty(key)) { callback(key, obj[key]); } } } - }; - Utilities.isEmpty = function (obj) { - var isEmpty = true; - Utilities.forEachProperty(obj, function () { + } + static isEmpty(obj) { + let isEmpty = true; + Utilities.forEachProperty(obj, () => { isEmpty = false; }); return isEmpty; - }; - Utilities.recursiveClone = function (obj) { + } + static recursiveClone(obj) { if (!obj || typeof obj !== 'object' || obj instanceof RegExp) { return obj; } @@ -212,8 +184,8 @@ var AMDLoader; // only clone "simple" objects return obj; } - var result = Array.isArray(obj) ? [] : {}; - Utilities.forEachProperty(obj, function (key, value) { + let result = Array.isArray(obj) ? [] : {}; + Utilities.forEachProperty(obj, (key, value) => { if (value && typeof value === 'object') { result[key] = Utilities.recursiveClone(value); } @@ -222,25 +194,24 @@ var AMDLoader; } }); return result; - }; - Utilities.generateAnonymousModule = function () { + } + static generateAnonymousModule() { return '===anonymous' + (Utilities.NEXT_ANONYMOUS_ID++) + '==='; - }; - Utilities.isAnonymousModule = function (id) { + } + static isAnonymousModule(id) { return Utilities.startsWith(id, '===anonymous'); - }; - Utilities.getHighPerformanceTimestamp = function () { + } + static getHighPerformanceTimestamp() { if (!this.PERFORMANCE_NOW_PROBED) { this.PERFORMANCE_NOW_PROBED = true; this.HAS_PERFORMANCE_NOW = (AMDLoader.global.performance && typeof AMDLoader.global.performance.now === 'function'); } return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now()); - }; - Utilities.NEXT_ANONYMOUS_ID = 1; - Utilities.PERFORMANCE_NOW_PROBED = false; - Utilities.HAS_PERFORMANCE_NOW = false; - return Utilities; - }()); + } + } + Utilities.NEXT_ANONYMOUS_ID = 1; + Utilities.PERFORMANCE_NOW_PROBED = false; + Utilities.HAS_PERFORMANCE_NOW = false; AMDLoader.Utilities = Utilities; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- @@ -253,7 +224,7 @@ var AMDLoader; if (err instanceof Error) { return err; } - var result = new Error(err.message || String(err) || 'Unknown Error'); + const result = new Error(err.message || String(err) || 'Unknown Error'); if (err.stack) { result.stack = err.stack; } @@ -261,13 +232,11 @@ var AMDLoader; } AMDLoader.ensureError = ensureError; ; - var ConfigurationOptionsUtil = /** @class */ (function () { - function ConfigurationOptionsUtil() { - } + class ConfigurationOptionsUtil { /** * Ensure configuration options make sense */ - ConfigurationOptionsUtil.validateConfigurationOptions = function (options) { + static validateConfigurationOptions(options) { function defaultOnError(err) { if (err.phase === 'loading') { console.error('Loading "' + err.moduleId + '" failed'); @@ -331,138 +300,134 @@ var AMDLoader; options.nodeCachedData.writeDelay = 1000 * 7; } if (!options.nodeCachedData.path || typeof options.nodeCachedData.path !== 'string') { - var err = ensureError(new Error('INVALID cached data configuration, \'path\' MUST be set')); + const err = ensureError(new Error('INVALID cached data configuration, \'path\' MUST be set')); err.phase = 'configuration'; options.onError(err); options.nodeCachedData = undefined; } } return options; - }; - ConfigurationOptionsUtil.mergeConfigurationOptions = function (overwrite, base) { - if (overwrite === void 0) { overwrite = null; } - if (base === void 0) { base = null; } - var result = AMDLoader.Utilities.recursiveClone(base || {}); + } + static mergeConfigurationOptions(overwrite = null, base = null) { + let result = AMDLoader.Utilities.recursiveClone(base || {}); // Merge known properties and overwrite the unknown ones - AMDLoader.Utilities.forEachProperty(overwrite, function (key, value) { + AMDLoader.Utilities.forEachProperty(overwrite, (key, value) => { if (key === 'ignoreDuplicateModules' && typeof result.ignoreDuplicateModules !== 'undefined') { result.ignoreDuplicateModules = result.ignoreDuplicateModules.concat(value); } else if (key === 'paths' && typeof result.paths !== 'undefined') { - AMDLoader.Utilities.forEachProperty(value, function (key2, value2) { return result.paths[key2] = value2; }); + AMDLoader.Utilities.forEachProperty(value, (key2, value2) => result.paths[key2] = value2); } else if (key === 'config' && typeof result.config !== 'undefined') { - AMDLoader.Utilities.forEachProperty(value, function (key2, value2) { return result.config[key2] = value2; }); + AMDLoader.Utilities.forEachProperty(value, (key2, value2) => result.config[key2] = value2); } else { result[key] = AMDLoader.Utilities.recursiveClone(value); } }); return ConfigurationOptionsUtil.validateConfigurationOptions(result); - }; - return ConfigurationOptionsUtil; - }()); + } + } AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil; - var Configuration = /** @class */ (function () { - function Configuration(env, options) { + class Configuration { + constructor(env, options) { this._env = env; this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options); this._createIgnoreDuplicateModulesMap(); this._createSortedPathsRules(); if (this.options.baseUrl === '') { if (this.options.nodeRequire && this.options.nodeRequire.main && this.options.nodeRequire.main.filename && this._env.isNode) { - var nodeMain = this.options.nodeRequire.main.filename; - var dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\')); + let nodeMain = this.options.nodeRequire.main.filename; + let dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\')); this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1); } } } - Configuration.prototype._createIgnoreDuplicateModulesMap = function () { + _createIgnoreDuplicateModulesMap() { // Build a map out of the ignoreDuplicateModules array this.ignoreDuplicateModulesMap = {}; - for (var i = 0; i < this.options.ignoreDuplicateModules.length; i++) { + for (let i = 0; i < this.options.ignoreDuplicateModules.length; i++) { this.ignoreDuplicateModulesMap[this.options.ignoreDuplicateModules[i]] = true; } - }; - Configuration.prototype._createSortedPathsRules = function () { - var _this = this; + } + _createSortedPathsRules() { // Create an array our of the paths rules, sorted descending by length to // result in a more specific -> less specific order this.sortedPathsRules = []; - AMDLoader.Utilities.forEachProperty(this.options.paths, function (from, to) { + AMDLoader.Utilities.forEachProperty(this.options.paths, (from, to) => { if (!Array.isArray(to)) { - _this.sortedPathsRules.push({ + this.sortedPathsRules.push({ from: from, to: [to] }); } else { - _this.sortedPathsRules.push({ + this.sortedPathsRules.push({ from: from, to: to }); } }); - this.sortedPathsRules.sort(function (a, b) { + this.sortedPathsRules.sort((a, b) => { return b.from.length - a.from.length; }); - }; + } /** * Clone current configuration and overwrite options selectively. * @param options The selective options to overwrite with. * @result A new configuration */ - Configuration.prototype.cloneAndMerge = function (options) { + cloneAndMerge(options) { return new Configuration(this._env, ConfigurationOptionsUtil.mergeConfigurationOptions(options, this.options)); - }; + } /** * Get current options bag. Useful for passing it forward to plugins. */ - Configuration.prototype.getOptionsLiteral = function () { + getOptionsLiteral() { return this.options; - }; - Configuration.prototype._applyPaths = function (moduleId) { - var pathRule; - for (var i = 0, len = this.sortedPathsRules.length; i < len; i++) { + } + _applyPaths(moduleId) { + let pathRule; + for (let i = 0, len = this.sortedPathsRules.length; i < len; i++) { pathRule = this.sortedPathsRules[i]; if (AMDLoader.Utilities.startsWith(moduleId, pathRule.from)) { - var result = []; - for (var j = 0, lenJ = pathRule.to.length; j < lenJ; j++) { + let result = []; + for (let j = 0, lenJ = pathRule.to.length; j < lenJ; j++) { result.push(pathRule.to[j] + moduleId.substr(pathRule.from.length)); } return result; } } return [moduleId]; - }; - Configuration.prototype._addUrlArgsToUrl = function (url) { + } + _addUrlArgsToUrl(url) { if (AMDLoader.Utilities.containsQueryString(url)) { return url + '&' + this.options.urlArgs; } else { return url + '?' + this.options.urlArgs; } - }; - Configuration.prototype._addUrlArgsIfNecessaryToUrl = function (url) { + } + _addUrlArgsIfNecessaryToUrl(url) { if (this.options.urlArgs) { return this._addUrlArgsToUrl(url); } return url; - }; - Configuration.prototype._addUrlArgsIfNecessaryToUrls = function (urls) { + } + _addUrlArgsIfNecessaryToUrls(urls) { if (this.options.urlArgs) { - for (var i = 0, len = urls.length; i < len; i++) { + for (let i = 0, len = urls.length; i < len; i++) { urls[i] = this._addUrlArgsToUrl(urls[i]); } } return urls; - }; + } /** * Transform a module id to a location. Appends .js to module ids */ - Configuration.prototype.moduleIdToPaths = function (moduleId) { + moduleIdToPaths(moduleId) { if (this._env.isNode) { - var isNodeModule = (this.options.amdModulesPattern instanceof RegExp + const isNodeModule = (this.options.amdModulesPattern instanceof RegExp && !this.options.amdModulesPattern.test(moduleId)); if (isNodeModule) { // This is a node module... @@ -476,11 +441,11 @@ var AMDLoader; } } } - var result = moduleId; - var results; + let result = moduleId; + let results; if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.isAbsolutePath(result)) { results = this._applyPaths(result); - for (var i = 0, len = results.length; i < len; i++) { + for (let i = 0, len = results.length; i < len; i++) { if (this.isBuild() && results[i] === 'empty:') { continue; } @@ -499,12 +464,12 @@ var AMDLoader; results = [result]; } return this._addUrlArgsIfNecessaryToUrls(results); - }; + } /** * Transform a module id or url to a location. */ - Configuration.prototype.requireToUrl = function (url) { - var result = url; + requireToUrl(url) { + let result = url; if (!AMDLoader.Utilities.isAbsolutePath(result)) { result = this._applyPaths(result)[0]; if (!AMDLoader.Utilities.isAbsolutePath(result)) { @@ -512,14 +477,14 @@ var AMDLoader; } } return this._addUrlArgsIfNecessaryToUrl(result); - }; + } /** * Flag to indicate if current execution is as part of a build. */ - Configuration.prototype.isBuild = function () { + isBuild() { return this.options.isBuild; - }; - Configuration.prototype.shouldInvokeFactory = function (strModuleId) { + } + shouldInvokeFactory(strModuleId) { if (!this.options.isBuild) { // outside of a build, all factories should be invoked return true; @@ -532,41 +497,40 @@ var AMDLoader; return true; } return false; - }; + } /** * Test if module `moduleId` is expected to be defined multiple times */ - Configuration.prototype.isDuplicateMessageIgnoredFor = function (moduleId) { + isDuplicateMessageIgnoredFor(moduleId) { return this.ignoreDuplicateModulesMap.hasOwnProperty(moduleId); - }; + } /** * Get the configuration settings for the provided module id */ - Configuration.prototype.getConfigForModule = function (moduleId) { + getConfigForModule(moduleId) { if (this.options.config) { return this.options.config[moduleId]; } - }; + } /** * Should errors be caught when executing module factories? */ - Configuration.prototype.shouldCatchError = function () { + shouldCatchError() { return this.options.catchError; - }; + } /** * Should statistics be recorded? */ - Configuration.prototype.shouldRecordStats = function () { + shouldRecordStats() { return this.options.recordStats; - }; + } /** * Forward an error to the error handler. */ - Configuration.prototype.onError = function (err) { + onError(err) { this.options.onError(err); - }; - return Configuration; - }()); + } + } AMDLoader.Configuration = Configuration; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- @@ -578,20 +542,19 @@ var AMDLoader; /** * Load `scriptSrc` only once (avoid multiple diff --git a/src/vs/workbench/contrib/webview/browser/pre/index.html b/src/vs/workbench/contrib/webview/browser/pre/index.html index dc31b55273f..514dfccb746 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index.html @@ -5,7 +5,7 @@ + content="default-src 'none'; script-src 'sha256-4A7BC3A+gc8e1t5I0rfDNtBiGlA0/GTojKdfdDHAWYw=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> navigator.serviceWorker.ready) .then(async registration => { /** * @param {MessageEvent} event @@ -247,7 +241,6 @@ // `unregister` and `register` here. return registration.unregister() .then(() => navigator.serviceWorker.register(swPath)) - .then(() => navigator.serviceWorker.ready) .finally(() => { resolve(); }); } }; @@ -266,6 +259,8 @@ // service worker already loaded & ready to receive messages postVersionMessage(currentController); } else { + console.log(`Found unexpected service worker controller. Found: ${currentController?.scriptURL}. Expected: ${swPath}`); + // either there's no controlling service worker, or it's an old one: // wait for it to change before posting the message const onControllerChange = () => { @@ -275,7 +270,10 @@ navigator.serviceWorker.addEventListener('controllerchange', onControllerChange); } }).catch(error => { - reject(new Error(`Could not register service workers: ${error}.`)); + if (!onElectron && error instanceof Error && error.message.includes('user denied permission')) { + return reject(new Error(`Could not register service worker. Please make sure third party cookies are enabled: ${error}`)); + } + return reject(new Error(`Could not register service worker: ${error}.`)); }); }); @@ -440,13 +438,13 @@ }; hostMessaging.onMessage('did-load-resource', (_event, data) => { - navigator.serviceWorker.ready.then(registration => { + navigator.serviceWorker.getRegistration().then(registration => { assertIsDefined(registration.active).postMessage({ channel: 'did-load-resource', data }, data.data?.buffer ? [data.data.buffer] : []); }); }); hostMessaging.onMessage('did-load-localhost', (_event, data) => { - navigator.serviceWorker.ready.then(registration => { + navigator.serviceWorker.getRegistration().then(registration => { assertIsDefined(registration.active).postMessage({ channel: 'did-load-localhost', data }); }); }); @@ -604,7 +602,7 @@ /** * @param {KeyboardEvent} e */ - const handleInnerUp = (e) => { + const handleInnerKeyup = (e) => { hostMessaging.postMessage('did-keyup', { key: e.key, keyCode: e.keyCode, @@ -833,6 +831,12 @@ return '\n' + newDocument.documentElement.outerHTML; } + // Also forward events before the contents of the webview have loaded + window.addEventListener('keydown', handleInnerKeydown); + window.addEventListener('keyup', handleInnerKeyup); + window.addEventListener('dragenter', handleInnerDragStartEvent); + window.addEventListener('dragover', handleInnerDragStartEvent); + onDomReady(() => { if (!document.body) { return; @@ -963,6 +967,9 @@ newFrame.style.cssText = 'display: block; margin: 0; overflow: hidden; position: absolute; width: 100%; height: 100%; visibility: hidden'; document.body.appendChild(newFrame); + newFrame.contentWindow.addEventListener('keydown', handleInnerKeydown); + newFrame.contentWindow.addEventListener('keyup', handleInnerKeyup); + /** * @param {Document} contentDocument */ @@ -1070,7 +1077,7 @@ contentWindow.addEventListener('click', handleInnerClick); contentWindow.addEventListener('auxclick', handleAuxClick); contentWindow.addEventListener('keydown', handleInnerKeydown); - contentWindow.addEventListener('keyup', handleInnerUp); + contentWindow.addEventListener('keyup', handleInnerKeyup); contentWindow.addEventListener('contextmenu', e => { if (e.defaultPrevented) { // Extension code has already handled this event @@ -1211,11 +1218,6 @@ } }; - // Also forward events before the contents of the webview have loaded - window.addEventListener('keydown', handleInnerKeydown); - window.addEventListener('dragenter', handleInnerDragStartEvent); - window.addEventListener('dragover', handleInnerDragStartEvent); - hostMessaging.signalReady(); }); diff --git a/src/vs/workbench/contrib/webview/browser/webview.ts b/src/vs/workbench/contrib/webview/browser/webview.ts index e6601363e3f..df3ceb8ace2 100644 --- a/src/vs/workbench/contrib/webview/browser/webview.ts +++ b/src/vs/workbench/contrib/webview/browser/webview.ts @@ -215,16 +215,27 @@ export interface IWebview extends IDisposable { readonly onDidFocus: Event; readonly onDidBlur: Event; + + /** + * Fired when the webview is disposed of. + */ readonly onDidDispose: Event; readonly onDidClickLink: Event; readonly onDidScroll: Event<{ readonly scrollYPercentage: number }>; readonly onDidWheel: Event; + readonly onDidUpdateState: Event; readonly onDidReload: Event; - readonly onMessage: Event; + + /** + * Fired when the webview cannot be loaded or is now in a non-functional state. + */ + readonly onFatalError: Event<{ readonly message: string }>; readonly onMissingCsp: Event; + readonly onMessage: Event; + postMessage(message: any, transfer?: readonly ArrayBuffer[]): Promise; focus(): void; diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 93f2b6bff57..5f34b6806d4 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -261,6 +261,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD this._register(this.on('fatal-error', (e) => { notificationService.error(localize('fatalErrorMessage', "Error loading webview: {0}", e.message)); + this._onFatalError.fire({ message: e.message }); })); this._register(this.on('did-keydown', (data) => { @@ -403,6 +404,9 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD private readonly _onDidBlur = this._register(new Emitter()); public readonly onDidBlur = this._onDidBlur.event; + private readonly _onFatalError = this._register(new Emitter<{ readonly message: string }>()); + public readonly onFatalError = this._onFatalError.event; + private readonly _onDidDispose = this._register(new Emitter()); public readonly onDidDispose = this._onDidDispose.event; diff --git a/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts b/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts index 396c9ce35b7..848fcd1fbe5 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts @@ -33,7 +33,7 @@ export class WebviewFindWidget extends SimpleFindWidget { @IContextKeyService contextKeyService: IContextKeyService, @IKeybindingService keybindingService: IKeybindingService ) { - super(undefined, { showCommonFindToggles: false, checkImeCompletionState: _delegate.checkImeCompletionState }, contextViewService, contextKeyService, keybindingService); + super({ showCommonFindToggles: false, checkImeCompletionState: _delegate.checkImeCompletionState }, contextViewService, contextKeyService, keybindingService); this._findWidgetFocused = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_FOCUSED.bindTo(contextKeyService); this._register(_delegate.hasFindResult(hasResult => { diff --git a/src/vs/workbench/contrib/webview/electron-sandbox/webviewCommands.ts b/src/vs/workbench/contrib/webview/electron-sandbox/webviewCommands.ts index 222d6088bfc..1e9eecf4ebd 100644 --- a/src/vs/workbench/contrib/webview/electron-sandbox/webviewCommands.ts +++ b/src/vs/workbench/contrib/webview/electron-sandbox/webviewCommands.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { Action2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { Categories } from 'vs/platform/action/common/actionCommonCategories'; export class OpenWebviewDeveloperToolsAction extends Action2 { diff --git a/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts index 0e62bf61d04..e10b2a6554c 100644 --- a/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts @@ -13,9 +13,9 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; +import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService'; import { ILogService } from 'vs/platform/log/common/log'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; diff --git a/src/vs/workbench/contrib/webview/electron-sandbox/windowIgnoreMenuShortcutsManager.ts b/src/vs/workbench/contrib/webview/electron-sandbox/windowIgnoreMenuShortcutsManager.ts index 6d6df9c1292..c3265219d37 100644 --- a/src/vs/workbench/contrib/webview/electron-sandbox/windowIgnoreMenuShortcutsManager.ts +++ b/src/vs/workbench/contrib/webview/electron-sandbox/windowIgnoreMenuShortcutsManager.ts @@ -6,8 +6,8 @@ import { isMacintosh } from 'vs/base/common/platform'; import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService'; export class WindowIgnoreMenuShortcutsManager { diff --git a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts index 5c828b5141f..a373e1f2e27 100644 --- a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts +++ b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts @@ -10,7 +10,7 @@ import { DisposableStore, IDisposable, MutableDisposable } from 'vs/base/common/ import { isWeb } from 'vs/base/common/platform'; import { generateUuid } from 'vs/base/common/uuid'; import * as nls from 'vs/nls'; -import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService, IScopedContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -50,7 +50,7 @@ export class WebviewEditor extends EditorPane { private readonly _onDidFocusWebview = this._register(new Emitter()); public override get onDidFocus(): Event { return this._onDidFocusWebview.event; } - private readonly _scopedContextKeyService = this._register(new MutableDisposable()); + private readonly _scopedContextKeyService = this._register(new MutableDisposable()); constructor( @ITelemetryService telemetryService: ITelemetryService, @@ -65,7 +65,12 @@ export class WebviewEditor extends EditorPane { ) { super(WebviewEditor.ID, telemetryService, themeService, storageService); - this._register(editorGroupsService.onDidScroll(() => { + this._register(Event.any( + editorGroupsService.onDidScroll, + editorGroupsService.onDidAddGroup, + editorGroupsService.onDidRemoveGroup, + editorGroupsService.onDidMoveGroup, + )(() => { if (this.webview && this._visible) { this.synchronizeWebviewContainerDimensions(this.webview); } @@ -192,7 +197,7 @@ export class WebviewEditor extends EditorPane { } private synchronizeWebviewContainerDimensions(webview: IOverlayWebview, dimension?: DOM.Dimension) { - if (!this._element) { + if (!this._element?.isConnected) { return; } const rootContainer = this._workbenchLayoutService.getContainer(Parts.EDITOR_PART); diff --git a/src/vs/workbench/contrib/welcomeDialog/browser/media/welcomeDialog.css b/src/vs/workbench/contrib/welcomeDialog/browser/media/welcomeDialog.css new file mode 100644 index 00000000000..63fb861a559 --- /dev/null +++ b/src/vs/workbench/contrib/welcomeDialog/browser/media/welcomeDialog.css @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +.monaco-dialog-box { + border-radius: 6px; +} + +.monaco-dialog-box .dialog-message-row .dialog-message-container .dialog-message-text { + font-size: 25px; + min-width: max-content; +} + +#monaco-dialog-message-body > div > p > .codicon[class*='codicon-']::before{ + padding-right: 8px; + max-width: 30px; + max-height: 30px; + position: relative; + top: auto; + color: var(--vscode-textLink-foreground); + padding-right: 20px; + font-size: 25px; +} + +#monaco-dialog-message-body > .message-body > p { + display: flex; + font-size: 16px; + background: var(--vscode-welcomePage-tileHoverBackground); + border-radius: 6px; + padding: 20px; + min-height: auto; + word-wrap: break-word; + overflow-wrap:break-word; +} + +#monaco-dialog-message-body > .link > p { + font-size: 16px; +} diff --git a/src/vs/workbench/contrib/welcomeDialog/browser/welcomeDialog.contribution.ts b/src/vs/workbench/contrib/welcomeDialog/browser/welcomeDialog.contribution.ts new file mode 100644 index 00000000000..5a9d7d1eb09 --- /dev/null +++ b/src/vs/workbench/contrib/welcomeDialog/browser/welcomeDialog.contribution.ts @@ -0,0 +1,53 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; +import { IWelcomeDialogService as IWelcomeDialogService } from 'vs/workbench/contrib/welcomeDialog/browser/welcomeDialogService'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; + +const configurationKey = 'welcome.experimental.dialog'; + +class WelcomeDialogContribution { + + private static readonly WELCOME_DIALOG_DISMISSED_KEY = 'workbench.dialog.welcome.dismissed'; + + constructor( + @IWelcomeDialogService welcomeDialogService: IWelcomeDialogService, + @IStorageService storageService: IStorageService, + @IBrowserWorkbenchEnvironmentService environmentService: IBrowserWorkbenchEnvironmentService, + @IConfigurationService configurationService: IConfigurationService + ) { + const setting = configurationService.inspect(configurationKey); + if (!setting.value) { + return; + } + + const welcomeDialog = environmentService.options?.welcomeDialog; + if (!welcomeDialog) { + return; + } + + if (storageService.getBoolean(WelcomeDialogContribution.WELCOME_DIALOG_DISMISSED_KEY + '#' + welcomeDialog.id, StorageScope.PROFILE, false)) { + return; + } + + welcomeDialogService.show({ + title: welcomeDialog.title, + buttonText: welcomeDialog.buttonText, + messages: welcomeDialog.messages, + action: welcomeDialog.action, + onClose: () => { + storageService.store(WelcomeDialogContribution.WELCOME_DIALOG_DISMISSED_KEY + '#' + welcomeDialog.id, true, StorageScope.PROFILE, StorageTarget.USER); + } + }); + } +} + +Registry.as(WorkbenchExtensions.Workbench) + .registerWorkbenchContribution(WelcomeDialogContribution, LifecyclePhase.Restored); diff --git a/src/vs/workbench/contrib/welcomeDialog/browser/welcomeDialogService.ts b/src/vs/workbench/contrib/welcomeDialog/browser/welcomeDialogService.ts new file mode 100644 index 00000000000..fadc29bb782 --- /dev/null +++ b/src/vs/workbench/contrib/welcomeDialog/browser/welcomeDialogService.ts @@ -0,0 +1,77 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/css!./media/welcomeDialog'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ILinkDescriptor } from 'vs/platform/opener/browser/link'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { MarkdownString } from 'vs/base/common/htmlContent'; +import { openLinkFromMarkdown } from 'vs/editor/contrib/markdownRenderer/browser/markdownRenderer'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; + +interface IWelcomeDialogItem { + readonly title: string; + readonly messages: { message: string; icon: string }[]; + readonly buttonText: string; + readonly action?: ILinkDescriptor; + readonly onClose?: () => void; +} + +export const IWelcomeDialogService = createDecorator('welcomeDialogService'); + +export interface IWelcomeDialogService { + readonly _serviceBrand: undefined; + + show(item: IWelcomeDialogItem): void; +} + +export class WelcomeDialogService implements IWelcomeDialogService { + declare readonly _serviceBrand: undefined; + + constructor( + @IDialogService private readonly dialogService: IDialogService, + @IOpenerService private readonly openerService: IOpenerService) { + } + + async show(welcomeDialogItem: IWelcomeDialogItem): Promise { + + const renderBody = (icon: string, message: string): MarkdownString => { + const mds = new MarkdownString(undefined, { supportThemeIcons: true, supportHtml: true }); + mds.appendMarkdown(`$(${icon})`); + mds.appendMarkdown(message); + return mds; + }; + + const hr = new MarkdownString(undefined, { supportThemeIcons: true, supportHtml: true }); + hr.appendMarkdown('
'); + + await this.dialogService.prompt({ + type: 'none', + message: welcomeDialogItem.title, + cancelButton: welcomeDialogItem.buttonText, + buttons: welcomeDialogItem.action ? [{ + label: welcomeDialogItem.action.label as string, + run: () => { + openLinkFromMarkdown(this.openerService, welcomeDialogItem.action?.href!, true); + welcomeDialogItem.onClose?.(); + } + + }] : undefined, + custom: { + disableCloseAction: true, + markdownDetails: [ + { markdown: hr, classes: ['hr'] }, + ...welcomeDialogItem.messages.map(value => { return { markdown: renderBody(value.icon, value.message), classes: ['message-body'] }; }) + ] + } + }); + + welcomeDialogItem.onClose?.(); + } +} + +registerSingleton(IWelcomeDialogService, WelcomeDialogService, InstantiationType.Eager); + diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/featuredExtensionService.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/featuredExtensionService.ts new file mode 100644 index 00000000000..e9063d4cb09 --- /dev/null +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/featuredExtensionService.ts @@ -0,0 +1,209 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { Disposable } from 'vs/base/common/lifecycle'; +import { IExtensionGalleryService, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { IFeaturedExtension } from 'vs/base/common/product'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { localize } from 'vs/nls'; +import { IWorkbenchAssignmentService } from 'vs/workbench/services/assignment/common/assignmentService'; +import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; + +type FeaturedExtensionTreatment = { extensions: string[]; showAsList?: string }; +type FeaturedExtensionStorageData = { title: string; description: string; imagePath: string; date: number }; + +export const IFeaturedExtensionsService = createDecorator('featuredExtensionsService'); + +export interface IFeaturedExtensionsService { + _serviceBrand: undefined; + + getExtensions(): Promise; + title: string; +} + +const enum FeaturedExtensionMetadataType { + Title, + Description, + ImagePath +} + +export class FeaturedExtensionsService extends Disposable implements IFeaturedExtensionsService { + declare readonly _serviceBrand: undefined; + + private ignoredExtensions: Set = new Set(); + private treatment: FeaturedExtensionTreatment | undefined; + private _isInitialized: boolean = false; + + private static readonly STORAGE_KEY = 'workbench.welcomePage.extensionMetadata'; + + constructor( + @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, + @IWorkbenchAssignmentService private readonly tasExperimentService: IWorkbenchAssignmentService, + @IStorageService private readonly storageService: IStorageService, + @IProductService private readonly productService: IProductService, + @IExtensionGalleryService private readonly galleryService: IExtensionGalleryService, + ) { + super(); + this.title = localize('gettingStarted.featuredTitle', 'Featured'); + } + + title: string; + + async getExtensions(): Promise { + + await this._init(); + + let treatments = this.treatment?.extensions?.filter(extension => !this.ignoredExtensions.has(extension)) ?? new Array(); + const featuredExtensions: IFeaturedExtension[] = new Array(); + + if (this.treatment?.showAsList !== 'true' && treatments.length > 0) { + // pick a random extensionId for display + const treatment = treatments[Math.floor(Math.random() * treatments.length)]; + treatments = [treatment]; + } + + for (const treatment of treatments) { + const extension = await this.resolveExtension(treatment); + if (extension) { + featuredExtensions.push(extension); + } + } + + return featuredExtensions; + } + + private async _init(): Promise { + + if (this._isInitialized) { + return; + } + + const extensions = await Promise.race([ + this.tasExperimentService?.getTreatment('welcome.featured.item'), + new Promise(resolve => setTimeout(() => resolve(''), 2000)) + ]); + + const extensionListTitle = await Promise.race([ + this.tasExperimentService?.getTreatment('welcome.featured.title'), + new Promise(resolve => setTimeout(() => resolve(''), 2000)) + ]); + + try { + this.treatment = extensions ? JSON.parse(extensions) : { extensions: [] }; + } catch { + } + + this.title = extensionListTitle ?? localize('gettingStarted.featuredTitle', 'Featured'); + + if (this.treatment?.extensions && Array.isArray(this.treatment.extensions)) { + const installed = await this.extensionManagementService.getInstalled(); + for (const extension of this.treatment.extensions) { + if (installed.some(e => ExtensionIdentifier.equals(e.identifier.id, extension))) { + this.ignoredExtensions.add(extension); + } + else { + const galleryExtension = (await this.galleryService.getExtensions([{ id: extension }], CancellationToken.None))[0]; + if (!await this.extensionManagementService.canInstall(galleryExtension)) { + this.ignoredExtensions.add(extension); + } + } + } + } + + this._isInitialized = true; + } + + private async resolveExtension(extensionId: string): Promise { + + const productMetadata = this.productService.featuredExtensions?.find(e => ExtensionIdentifier.equals(e.id, extensionId)); + + const title = productMetadata?.title ?? await this.getMetadata(extensionId, FeaturedExtensionMetadataType.Title); + const description = productMetadata?.description ?? await this.getMetadata(extensionId, FeaturedExtensionMetadataType.Description); + const imagePath = productMetadata?.imagePath ?? await this.getMetadata(extensionId, FeaturedExtensionMetadataType.ImagePath); + + if (title && description && imagePath) { + return { + id: extensionId, + title: title, + description: description, + imagePath: imagePath, + }; + } + return undefined; + } + + private async getMetadata(extensionId: string, key: FeaturedExtensionMetadataType): Promise { + + const storageMetadata = this.getStorageData(extensionId); + if (storageMetadata) { + switch (key) { + case FeaturedExtensionMetadataType.Title: { + return storageMetadata.title; + } + case FeaturedExtensionMetadataType.Description: { + return storageMetadata.description; + } + case FeaturedExtensionMetadataType.ImagePath: { + return storageMetadata.imagePath; + } + default: + return undefined; + } + } + + return await this.getGalleryMetadata(extensionId, key); + } + + private getStorageData(extensionId: string): FeaturedExtensionStorageData | undefined { + const metadata = this.storageService.get(FeaturedExtensionsService.STORAGE_KEY + '.' + extensionId, StorageScope.APPLICATION); + if (metadata) { + const value = JSON.parse(metadata) as FeaturedExtensionStorageData; + const lastUpdateDate = new Date().getTime() - value.date; + if (lastUpdateDate < 1000 * 60 * 60 * 24 * 7) { + return value; + } + } + return undefined; + } + + private async getGalleryMetadata(extensionId: string, key: FeaturedExtensionMetadataType): Promise { + + const storageKey = FeaturedExtensionsService.STORAGE_KEY + '.' + extensionId; + this.storageService.remove(storageKey, StorageScope.APPLICATION); + + const galleryExtension = (await this.galleryService.getExtensions([{ id: extensionId }], CancellationToken.None))[0]; + let metadata: string | undefined; + if (galleryExtension) { + switch (key) { + case FeaturedExtensionMetadataType.Title: { + metadata = galleryExtension.displayName; + break; + } + case FeaturedExtensionMetadataType.Description: { + metadata = galleryExtension.description; + break; + } + case FeaturedExtensionMetadataType.ImagePath: { + metadata = galleryExtension.assets.icon?.uri; + break; + } + } + + this.storageService.store(storageKey, JSON.stringify({ + title: galleryExtension.displayName, + description: galleryExtension.description, + imagePath: galleryExtension.assets.icon?.uri, + date: new Date().getTime() + }), StorageScope.APPLICATION, StorageTarget.MACHINE); + } + return metadata; + } +} + +registerSingleton(IFeaturedExtensionsService, FeaturedExtensionsService, InstantiationType.Delayed); diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts index 166921e8b6c..5b4255eabaa 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts @@ -32,7 +32,6 @@ import { StartupPageContribution, } from 'vs/workbench/contrib/welcomeGettingSta import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput'; import { Categories } from 'vs/platform/action/common/actionCommonCategories'; - export * as icons from 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedIcons'; registerAction2(class extends Action2 { @@ -299,18 +298,6 @@ configurationRegistry.registerConfiguration({ default: true, description: localize('workbench.welcomePage.walkthroughs.openOnInstall', "When enabled, an extension's walkthrough will open upon install of the extension.") }, - 'workbench.welcomePage.experimental.videoTutorials': { - scope: ConfigurationScope.MACHINE, - type: 'string', - enum: [ - 'off', - 'on', - 'experimental' - ], - tags: ['experimental'], - default: 'off', - description: localize('workbench.welcomePage.videoTutorials', "When enabled, the get started page has additional links to video tutorials.") - }, 'workbench.startupEditor': { 'scope': ConfigurationScope.RESOURCE, 'type': 'string', diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts index bf09fb17c71..1b409409e61 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts @@ -70,13 +70,16 @@ import { GettingStartedDetailsRenderer } from 'vs/workbench/contrib/welcomeGetti import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; import { defaultButtonStyles, defaultToggleStyles } from 'vs/platform/theme/browser/defaultStyles'; +import { IFeaturedExtensionsService } from 'vs/workbench/contrib/welcomeGettingStarted/browser/featuredExtensionService'; +import { IFeaturedExtension } from 'vs/base/common/product'; +import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; const SLIDE_TRANSITION_TIME_MS = 250; const configurationKey = 'workbench.startupEditor'; export const allWalkthroughsHiddenContext = new RawContextKey('allWalkthroughsHidden', false); export const inWelcomeContext = new RawContextKey('inWelcome', false); -export const embedderIdentifierContext = new RawContextKey('embedderIdentifier', undefined); export interface IWelcomePageStartEntry { id: string; @@ -127,6 +130,8 @@ export class GettingStartedPage extends EditorPane { private detailsPageDisposables: DisposableStore = new DisposableStore(); private gettingStartedCategories: IResolvedWalkthrough[]; + private featuredExtensions?: Promise; + private currentWalkthrough: IResolvedWalkthrough | undefined; private categoriesPageScrollbar: DomScrollableElement | undefined; @@ -145,6 +150,7 @@ export class GettingStartedPage extends EditorPane { private recentlyOpenedList?: GettingStartedIndexList; private startList?: GettingStartedIndexList; private gettingStartedList?: GettingStartedIndexList; + private featuredExtensionsList?: GettingStartedIndexList; private stepsSlide!: HTMLElement; private categoriesSlide!: HTMLElement; @@ -162,6 +168,7 @@ export class GettingStartedPage extends EditorPane { @IProductService private readonly productService: IProductService, @IKeybindingService private readonly keybindingService: IKeybindingService, @IWalkthroughsService private readonly gettingStartedService: IWalkthroughsService, + @IFeaturedExtensionsService private readonly featuredExtensionService: IFeaturedExtensionsService, @IConfigurationService private readonly configurationService: IConfigurationService, @ITelemetryService telemetryService: ITelemetryService, @ILanguageService private readonly languageService: ILanguageService, @@ -181,6 +188,7 @@ export class GettingStartedPage extends EditorPane { @IWebviewService private readonly webviewService: IWebviewService, @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, @IAccessibilityService private readonly accessibilityService: IAccessibilityService, + @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService ) { super(GettingStartedPage.ID, telemetryService, themeService, storageService); @@ -200,14 +208,17 @@ export class GettingStartedPage extends EditorPane { this.contextService = this._register(contextService.createScoped(this.container)); inWelcomeContext.bindTo(this.contextService).set(true); - embedderIdentifierContext.bindTo(this.contextService).set(productService.embedderIdentifier); this.gettingStartedCategories = this.gettingStartedService.getWalkthroughs(); + this.featuredExtensions = this.featuredExtensionService.getExtensions(); + this._register(this.dispatchListeners); this.buildSlideThrottle = new Throttler(); const rerender = () => { this.gettingStartedCategories = this.gettingStartedService.getWalkthroughs(); + this.featuredExtensions = this.featuredExtensionService.getExtensions(); + if (this.currentWalkthrough) { const existingSteps = this.currentWalkthrough.steps.map(step => step.id); const newCategory = this.gettingStartedCategories.find(category => this.currentWalkthrough?.id === category.id); @@ -222,6 +233,15 @@ export class GettingStartedPage extends EditorPane { } }; + this._register(this.extensionManagementService.onDidInstallExtensions(async (result) => { + for (const e of result) { + const installedFeaturedExtension = (await this.featuredExtensions)?.find(ext => ExtensionIdentifier.equals(ext.id, e.identifier.id)); + if (installedFeaturedExtension) { + this.hideExtension(e.identifier.id); + } + } + })); + this._register(this.gettingStartedService.onDidAddWalkthrough(rerender)); this._register(this.gettingStartedService.onDidRemoveWalkthrough(rerender)); @@ -420,6 +440,14 @@ export class GettingStartedPage extends EditorPane { } break; } + case 'openExtensionPage': { + this.commandService.executeCommand('extension.open', argument); + break; + } + case 'hideExtension': { + this.hideExtension(argument); + break; + } default: { console.error('Dispatch to', command, argument, 'not defined'); break; @@ -434,6 +462,12 @@ export class GettingStartedPage extends EditorPane { this.gettingStartedList?.rerender(); } + private hideExtension(extensionId: string) { + this.setHiddenCategories([...this.getHiddenCategories().add(extensionId)]); + this.featuredExtensionsList?.rerender(); + this.registerDispatchListeners(); + } + private markAllStepsComplete() { if (this.currentWalkthrough) { this.currentWalkthrough?.steps.forEach(step => { @@ -640,7 +674,10 @@ export class GettingStartedPage extends EditorPane { this.openerService.open(message, { allowCommands: true }); } else if (message.startsWith('setTheme:')) { this.configurationService.updateValue(ThemeSettings.COLOR_THEME, message.slice('setTheme:'.length), ConfigurationTarget.USER); - } else { + } else if (message === 'unloaded') { + this.buildMediaComponent(stepId); + } + else { console.error('Unexpected message', message); } })); @@ -657,8 +694,8 @@ export class GettingStartedPage extends EditorPane { } } - private async selectStep(id: string | undefined, delayFocus = true, forceRebuild = false) { - if (id && this.editorInput.selectedStep === id && !forceRebuild) { return; } + private async selectStep(id: string | undefined, delayFocus = true) { + if (id && this.editorInput.selectedStep === id) { return; } if (id) { let stepElement = this.container.querySelector(`[data-step-id="${id}"]`); @@ -721,7 +758,6 @@ export class GettingStartedPage extends EditorPane { this.categoriesPageScrollbar.scanDomNode(); this.detailsPageScrollbar.scanDomNode(); - parent.appendChild(this.container); } @@ -759,12 +795,12 @@ export class GettingStartedPage extends EditorPane { $('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved")) ); - const leftColumn = $('.categories-column.categories-column-left', {},); const rightColumn = $('.categories-column.categories-column-right', {},); const startList = this.buildStartList(); const recentList = this.buildRecentlyOpenedList(); + const featuredExtensionList = this.buildFeaturedExtensionsList(); const gettingStartedList = this.buildGettingStartedWalkthroughsList(); const footer = $('.footer', {}, @@ -773,22 +809,37 @@ export class GettingStartedPage extends EditorPane { showOnStartupLabel, )); + recentList.setLimit(5); const layoutLists = () => { if (gettingStartedList.itemCount) { this.container.classList.remove('noWalkthroughs'); reset(leftColumn, startList.getDomElement(), recentList.getDomElement()); - reset(rightColumn, gettingStartedList.getDomElement()); - recentList.setLimit(5); + reset(rightColumn, featuredExtensionList.getDomElement(), gettingStartedList.getDomElement()); } else { this.container.classList.add('noWalkthroughs'); - reset(leftColumn, startList.getDomElement()); - reset(rightColumn, recentList.getDomElement()); - recentList.setLimit(10); + reset(leftColumn, startList.getDomElement(), recentList.getDomElement()); + reset(rightColumn, featuredExtensionList.getDomElement()); } setTimeout(() => this.categoriesPageScrollbar?.scanDomNode(), 50); }; + const layoutFeaturedExtension = () => { + if (featuredExtensionList.itemCount) { + this.container.classList.remove('noExtensions'); + reset(leftColumn, startList.getDomElement(), recentList.getDomElement()); + reset(rightColumn, featuredExtensionList.getDomElement(), gettingStartedList.getDomElement()); + } + else { + this.container.classList.add('noExtensions'); + reset(leftColumn, startList.getDomElement(), recentList.getDomElement()); + reset(rightColumn, gettingStartedList.getDomElement()); + } + setTimeout(() => this.categoriesPageScrollbar?.scanDomNode(), 50); + }; + + featuredExtensionList.onDidChange(layoutFeaturedExtension); + layoutFeaturedExtension(); gettingStartedList.onDidChange(layoutLists); layoutLists(); @@ -1041,10 +1092,64 @@ export class GettingStartedPage extends EditorPane { gettingStartedList.setEntries(this.gettingStartedCategories); allWalkthroughsHiddenContext.bindTo(this.contextService).set(gettingStartedList.itemCount === 0); - return gettingStartedList; } + private buildFeaturedExtensionsList(): GettingStartedIndexList { + + const renderFeaturedExtensions = (entry: IFeaturedExtension): HTMLElement => { + + const descriptionContent = $('.featured-description-content', {},); + + reset(descriptionContent, ...renderLabelWithIcons(entry.description)); + + const titleContent = $('h3.category-title.max-lines-3', { 'x-category-title-for': entry.id }); + reset(titleContent, ...renderLabelWithIcons(entry.title)); + + return $('button.getting-started-category', + { + 'x-dispatch': 'openExtensionPage:' + entry.id, + 'title': entry.description + }, + $('.main-content', {}, + $('img.featured-icon.icon-widget', { src: entry.imagePath }), + titleContent, + $('a.codicon.codicon-close.hide-category-button', { + 'tabindex': 0, + 'x-dispatch': 'hideExtension:' + entry.id, + 'title': localize('close', "Hide"), + 'role': 'button', + 'aria-label': localize('closeAriaLabel', "Hide"), + }), + ), + descriptionContent); + }; + + if (this.featuredExtensionsList) { + this.featuredExtensionsList.dispose(); + } + + const featuredExtensionsList = this.featuredExtensionsList = new GettingStartedIndexList( + { + title: this.featuredExtensionService.title, + klass: 'featured-extensions', + limit: 5, + renderElement: renderFeaturedExtensions, + rankElement: (extension) => { if (this.getHiddenCategories().has(extension.id)) { return null; } return 0; }, + contextService: this.contextService, + }); + + this.featuredExtensions?.then(extensions => { + featuredExtensionsList.setEntries(extensions); + }); + + this.featuredExtensionsList?.onDidChange(() => { + + this.registerDispatchListeners(); + }); + return featuredExtensionsList; + } + layout(size: Dimension) { this.detailsScrollbar?.scanDomNode(); @@ -1053,6 +1158,7 @@ export class GettingStartedPage extends EditorPane { this.startList?.layout(size); this.gettingStartedList?.layout(size); + this.featuredExtensionsList?.layout(size); this.recentlyOpenedList?.layout(size); this.layoutMarkdown?.(); @@ -1077,7 +1183,6 @@ export class GettingStartedPage extends EditorPane { const progress = (stats.stepsComplete / stats.stepsTotal) * 100; bar.style.width = `${progress}%`; - (element.parentElement as HTMLElement).classList.toggle('no-progress', stats.stepsComplete === 0); if (stats.stepsTotal === stats.stepsComplete) { @@ -1239,7 +1344,9 @@ export class GettingStartedPage extends EditorPane { this.detailsPageDisposables.clear(); const category = this.gettingStartedCategories.find(category => category.id === categoryID); - if (!category) { throw Error('could not find category with ID ' + categoryID); } + if (!category) { + throw Error('could not find category with ID ' + categoryID); + } const categoryDescriptorComponent = $('.getting-started-category', @@ -1259,13 +1366,13 @@ export class GettingStartedPage extends EditorPane { if (event.keyCode === KeyCode.UpArrow) { const toExpand = category.steps.filter((step, index) => index < currentStepIndex() && this.contextService.contextMatchesRules(step.when)); if (toExpand.length) { - this.selectStep(toExpand[toExpand.length - 1].id, false, false); + this.selectStep(toExpand[toExpand.length - 1].id, false); } } if (event.keyCode === KeyCode.DownArrow) { const toExpand = category.steps.find((step, index) => index > currentStepIndex() && this.contextService.contextMatchesRules(step.when)); if (toExpand) { - this.selectStep(toExpand.id, false, false); + this.selectStep(toExpand.id, false); } } })); @@ -1275,6 +1382,8 @@ export class GettingStartedPage extends EditorPane { const contextKeysToWatch = new Set(category.steps.flatMap(step => step.when.keys())); const buildStepList = () => { + + category.steps.sort((a, b) => a.order - b.order); const toRender = category.steps .filter(step => this.contextService.contextMatchesRules(step.when)); @@ -1330,7 +1439,7 @@ export class GettingStartedPage extends EditorPane { if (e.affectsSome(contextKeysToWatch)) { buildStepList(); this.registerDispatchListeners(); - this.selectStep(this.editorInput.selectedStep, false, true); + this.selectStep(this.editorInput.selectedStep, false); } })); @@ -1357,7 +1466,7 @@ export class GettingStartedPage extends EditorPane { reset(this.stepsContent, categoryDescriptorComponent, stepListComponent, this.stepMediaComponent, categoryFooter); const toExpand = category.steps.find(step => this.contextService.contextMatchesRules(step.when) && !step.done) ?? category.steps[0]; - this.selectStep(selectedStep ?? toExpand.id, !selectedStep, true); + this.selectStep(selectedStep ?? toExpand.id, !selectedStep); this.detailsScrollbar.scanDomNode(); this.detailsPageScrollbar?.scanDomNode(); diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer.ts index 0c77dad4cb4..21b2c7b60ef 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer.ts @@ -20,8 +20,8 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten export class GettingStartedDetailsRenderer { - private mdCache = new ResourceMap>(); - private svgCache = new ResourceMap>(); + private mdCache = new ResourceMap(); + private svgCache = new ResourceMap(); constructor( @IFileService private readonly fileService: IFileService, @@ -125,6 +125,11 @@ export class GettingStartedDetailsRenderer { - - - - - - -

TypeScript

-
- - -
- - -
- -
Press 'run' to execute code...
-
...write your results into #results...
-
- - - diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem.txt deleted file mode 100644 index 9d348ac0901..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem.txt +++ /dev/null @@ -1,283 +0,0 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vulputate, ipsum quis interdum fermentum, lorem sem fermentum eros, vitae auctor neque lacus in nisi. Suspendisse potenti. Maecenas et scelerisque elit, in tincidunt quam. Sed eu tincidunt quam. Nullam justo ex, imperdiet a imperdiet et, fermentum sit amet eros. Aenean quis tempus sem. Pellentesque accumsan magna mi, ut mollis velit sagittis id. Etiam quis ipsum orci. Fusce purus ante, accumsan a lobortis at, venenatis eu nisl. Praesent ornare sed ante placerat accumsan. Suspendisse tempus dignissim fermentum. Nunc a leo ac lacus sodales iaculis eu vitae mi. In feugiat ante at massa finibus cursus. Suspendisse posuere fringilla ornare. Mauris elementum ac quam id convallis. Vestibulum non elit quis urna volutpat aliquam a eu lacus. - -Aliquam vestibulum imperdiet neque, suscipit aliquam elit ultrices bibendum. Suspendisse ultrices pulvinar cursus. Morbi risus nisi, cursus consequat rutrum vitae, molestie sed dui. Fusce posuere, augue quis dignissim aliquam, nisi ipsum porttitor ante, quis fringilla nisl turpis ac nisi. Nulla varius enim eget lorem vehicula gravida. Donec finibus malesuada leo nec semper. Proin ac enim eros. Vivamus non tincidunt nisi, vel tristique lorem. - -Nunc consequat ex id eros dignissim, id rutrum risus laoreet. Sed euismod non erat eu ultricies. Etiam vehicula gravida lacus ut porta. Vestibulum eu eros quis nunc aliquet luctus. Cras quis semper ligula. Nullam gravida vehicula quam sed porta. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In porta cursus vulputate. Quisque porta a nisi eget cursus. Aliquam risus leo, luctus ac magna in, efficitur cursus magna. In condimentum non mi id semper. Donec interdum ante eget commodo maximus. - -Vivamus sit amet vestibulum lectus. Fusce tincidunt mi sapien, dictum sollicitudin diam vulputate in. Integer fringilla consequat mollis. Cras aliquet consequat felis eget feugiat. Nunc tempor cursus arcu, vitae ornare nunc varius et. Vestibulum et tortor vel ante viverra porttitor. Nam at tortor ullamcorper, facilisis augue quis, tristique erat. Aenean ut euismod nibh. Quisque eu tincidunt est, nec euismod eros. - -Proin vehicula nibh non viverra egestas. Phasellus sem dolor, ultricies ac sagittis tristique, lacinia a purus. Vestibulum in ante eros. Pellentesque lacus nulla, tristique vitae interdum vel, malesuada ac diam. Aenean bibendum posuere turpis in accumsan. Ut est nulla, ullamcorper quis turpis at, viverra sagittis mauris. Sed in interdum purus. Praesent scelerisque nibh eget sem euismod, ut imperdiet mi venenatis. Vivamus pulvinar orci sed dapibus auctor. Nulla facilisi. Vestibulum tincidunt erat nec porttitor egestas. Mauris quis risus ante. Nulla facilisi. - -Aliquam ullamcorper ornare lobortis. Phasellus quis sem et ipsum mollis malesuada sed in ex. Ut aliquam ex eget metus finibus maximus. Proin suscipit mauris eu nibh lacinia, quis feugiat dui dapibus. Nam sed libero est. Aenean vulputate orci sit amet diam faucibus, eu sagittis sapien volutpat. Nam imperdiet felis turpis, at pretium odio pulvinar in. Sed vestibulum id eros nec ultricies. Sed quis aliquam tortor, vitae ullamcorper tellus. Donec egestas laoreet eros, id suscipit est rutrum nec. Sed auctor nulla eget metus aliquam, ut condimentum enim elementum. - -Aliquam suscipit non turpis sit amet bibendum. Fusce velit ligula, euismod et maximus at, luctus sed neque. Quisque pretium, nisl at ullamcorper finibus, lectus leo mattis sapien, vel euismod mauris diam ullamcorper ex. Nulla ut risus finibus, lacinia ligula at, auctor erat. Mauris consectetur sagittis ligula vel dapibus. Nullam libero libero, lobortis aliquam libero vel, venenatis ultricies leo. Duis porttitor, nibh congue fermentum posuere, erat libero pulvinar tortor, a pellentesque nunc ipsum vel sem. Nullam volutpat, eros sit amet facilisis consectetur, ipsum est vehicula massa, non vestibulum neque elit in mauris. Nunc hendrerit ipsum non enim bibendum, vitae rhoncus mi egestas. Etiam ullamcorper massa vel nisl sagittis, nec bibendum arcu malesuada. Aenean aliquet turpis justo, a consectetur arcu mollis convallis. Etiam tellus ipsum, ultricies vitae lorem et, ornare facilisis orci. Praesent fringilla justo urna, vel mollis neque pulvinar vestibulum. - -Donec non iaculis erat. Aliquam et mi sed nunc pulvinar ultricies in ut ipsum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent feugiat lacus ac dignissim semper. Phasellus vitae quam nisi. Morbi vel diam ultricies risus lobortis ornare. Fusce maximus et ligula quis iaculis. Sed congue ex eget felis convallis, sit amet hendrerit elit tempor. Donec vehicula blandit ante eget commodo. Vestibulum eleifend diam at feugiat euismod. Etiam magna tellus, dignissim eget fermentum vel, vestibulum vitae mauris. Nam accumsan et erat id sagittis. Donec lacinia, odio ut ornare ultricies, dolor velit accumsan tortor, non finibus erat tellus quis ligula. Nunc quis metus in leo volutpat ornare vulputate eu nisl. - -Donec quis viverra ex. Nullam id feugiat mauris, eu fringilla nulla. Vestibulum id maximus elit. Cras elementum elit sed felis lobortis, eget sagittis nisi hendrerit. Vivamus vitae elit neque. Donec vulputate lacus ut libero ultrices accumsan. Vivamus accumsan nulla orci, in dignissim est laoreet sagittis. Proin at commodo velit. Curabitur in velit felis. Aliquam erat volutpat. Sed consequat, nulla et cursus sodales, nisi lacus mattis risus, quis eleifend erat ex nec turpis. Sed suscipit ultrices lorem in hendrerit. - -Morbi vitae lacus nec libero ornare tempus eu et diam. Suspendisse magna ipsum, fermentum vel odio quis, molestie aliquam urna. Fusce mollis turpis a eros accumsan porttitor. Pellentesque rhoncus dolor sit amet magna rutrum, et dapibus justo tempor. Sed purus nisi, maximus vitae fringilla eu, molestie nec urna. Fusce malesuada finibus pretium. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec sed aliquet eros. Pellentesque luctus diam ante, eget euismod nisl aliquet eu. Sed accumsan elit purus, tempor varius ligula tempus nec. Curabitur ornare leo suscipit suscipit fermentum. Morbi eget nulla est. Maecenas faucibus interdum tristique. - -Etiam ut elit eros. Nulla pharetra suscipit molestie. Nulla facilisis bibendum nisl non molestie. Curabitur turpis lectus, facilisis vel diam non, vulputate ultrices mauris. Aenean placerat aliquam convallis. Suspendisse sed scelerisque tellus. Vivamus lacinia neque eget risus cursus suscipit. Proin consequat dolor vel neque tempor, eu aliquam sem scelerisque. Duis non eros a purus malesuada pharetra non et nulla. Suspendisse potenti. Mauris libero eros, finibus vel nulla id, sagittis dapibus ante. Proin iaculis sed nunc et cursus. - -Quisque accumsan lorem sit amet lorem aliquet euismod. Curabitur fermentum rutrum posuere. Etiam ultricies, sem id pellentesque suscipit, urna magna lacinia eros, quis efficitur risus nisl at lacus. Nulla quis lacus tortor. Mauris placerat ex in dolor tincidunt, vel aliquet nisi pretium. Cras iaculis risus vitae pellentesque aliquet. Quisque a enim imperdiet, ullamcorper arcu vitae, rutrum risus. Nullam consectetur libero at felis fringilla, nec congue nibh dignissim. Nam et lobortis felis, eu pellentesque ligula. Aenean facilisis, ligula non imperdiet maximus, massa orci gravida sapien, at sagittis lacus nisl in lacus. Nulla quis mauris luctus, scelerisque felis consequat, tempus risus. Fusce auctor nisl non nulla luctus molestie. Maecenas sapien nisl, auctor non dolor et, iaculis scelerisque lorem. Suspendisse egestas enim aliquet, accumsan mauris nec, posuere quam. Nulla iaculis dui dui, sit amet vestibulum erat ultricies ac. - -Cras eget dolor erat. Proin at nisl ut leo consectetur ultricies vel ut arcu. Nulla in felis malesuada, ullamcorper tortor et, convallis massa. Nunc urna justo, ornare in nibh vitae, hendrerit condimentum libero. Etiam vitae libero in purus venenatis fringilla. Nullam velit nulla, consequat ut turpis non, egestas hendrerit nibh. Duis tortor turpis, interdum non ante ac, cursus accumsan lectus. Cras pharetra bibendum augue quis dictum. Sed euismod vestibulum justo. Proin porta lobortis purus. Duis venenatis diam tortor, sit amet condimentum eros rhoncus a. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc at magna nec diam lobortis efficitur sit amet ut lacus. Nulla quis orci tortor. Pellentesque tempus velit a odio finibus porta. - -Proin feugiat mauris a tellus scelerisque convallis. Maecenas libero magna, blandit nec ultrices id, congue vel mi. Aliquam lacinia, quam vel condimentum convallis, tortor turpis aliquam odio, sed blandit libero lacus et eros. In eleifend iaculis magna ac finibus. Praesent auctor facilisis tellus in congue. Sed molestie lobortis dictum. Nam quis dignissim augue, vel euismod lorem. Curabitur posuere dapibus luctus. Donec ultricies dictum lectus, quis blandit arcu commodo ac. Aenean tincidunt ligula in nunc imperdiet dignissim. Curabitur egestas sollicitudin sapien ut semper. Aenean nec dignissim lacus. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec aliquam dictum vehicula. Donec tortor est, volutpat non nisi nec, varius gravida ex. Nunc vel tristique nunc, vitae mattis nisi. Nunc nec luctus ex, vitae tincidunt lectus. In hac habitasse platea dictumst. Curabitur lobortis ex eget tincidunt tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut a vehicula mi. - -Fusce eu libero finibus, interdum nulla a, placerat neque. Cras bibendum tempor libero nec feugiat. Cras ut sodales eros. Proin viverra, massa sit amet viverra egestas, neque nisl porta ex, sit amet hendrerit libero ligula vel urna. Mauris suscipit lacus id justo rhoncus suscipit. Etiam vel libero tellus. Maecenas non diam molestie, condimentum tellus a, bibendum enim. Mauris aliquet imperdiet tellus, eget sagittis dolor. Sed blandit in neque et luctus. Cras elementum sagittis nunc, vel mollis lorem euismod et. Donec posuere at lacus eget suscipit. - -Nulla nunc mi, pretium non massa vel, tempor semper magna. Nunc a leo pulvinar, tincidunt nunc at, dignissim mi. Aliquam erat volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut viverra nulla a nisl finibus, at hendrerit ligula ullamcorper. Donec a lorem semper, tempor magna et, lobortis libero. Mauris id sapien leo. Donec dignissim, quam vitae porttitor dignissim, quam justo mattis dui, vel consequat odio elit quis orci. Etiam nec pretium neque, sit amet pretium orci. Duis ac tortor venenatis, feugiat purus non, feugiat nunc. Proin scelerisque nisl in turpis aliquam vulputate. - -Praesent sed est semper, fringilla lorem vitae, tincidunt nibh. Cras eros metus, auctor at mauris sit amet, sodales semper orci. Nunc a ornare ex. Curabitur bibendum arcu congue urna vulputate egestas. Vestibulum finibus id risus et accumsan. Aenean ut volutpat tellus. Aenean tincidunt malesuada urna sit amet vestibulum. Mauris vel tellus dictum, varius lacus quis, dictum arcu. - -Aenean quis metus eu erat feugiat cursus vel at ligula. Proin dapibus sodales urna, id euismod lectus tempus id. Pellentesque ex ligula, convallis et erat vel, vulputate condimentum nisl. Pellentesque pharetra nulla quis massa eleifend hendrerit. Praesent sed massa ipsum. Maecenas vehicula dolor massa, id sodales urna faucibus et. Mauris ac quam non massa tincidunt feugiat et at lacus. Fusce libero massa, vulputate vel scelerisque non, mollis in leo. Ut sit amet ultricies odio. Suspendisse in sapien viverra, facilisis purus ut, pretium libero. - -Vivamus tristique pharetra molestie. Nam a volutpat purus. Praesent consequat gravida nisi, ac blandit nisi suscipit ut. Quisque posuere, ligula a ultrices laoreet, ligula nunc vulputate libero, ut rutrum erat odio tincidunt justo. Sed vitae leo at leo fringilla bibendum. Vestibulum ut augue nec dolor auctor accumsan. Praesent laoreet id eros pulvinar commodo. Suspendisse potenti. Ut pharetra, mauris vitae blandit fringilla, odio ante tincidunt lorem, sit amet tempor metus diam ut turpis. - -Praesent quis egestas arcu. Nullam at porta arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi vulputate ligula malesuada ligula luctus, vulputate tempus erat bibendum. Nunc ullamcorper non lectus at euismod. Etiam nibh felis, tincidunt a metus vel, pellentesque rhoncus neque. Etiam at diam in erat luctus interdum. Nunc vel ipsum pulvinar, sollicitudin lacus ac, tempus urna. Etiam vel lacinia sapien. Pellentesque sagittis velit vel mi efficitur iaculis. Integer euismod sit amet urna in sagittis. Cras eleifend ut nibh in facilisis. Donec et lacus vitae nunc placerat sodales. Nulla sed hendrerit ligula, at dapibus sapien. - -Praesent at iaculis ex. Curabitur est purus, cursus a faucibus quis, dictum id velit. Donec dignissim fringilla viverra. Nunc mauris felis, laoreet sit amet sagittis at, vestibulum in libero. Maecenas quis orci turpis. Quisque ut nibh vitae magna mollis consequat id at mauris. Aliquam eu odio eget nulla bibendum sodales. Quisque vel orci eleifend nisi pretium lacinia. Suspendisse eget risus eget mi volutpat molestie eget quis lacus. Duis nisi libero, tincidunt nec nulla id, faucibus cursus felis. - -Donec tempor eget risus pellentesque molestie. Phasellus porta neque vel arcu egestas, nec blandit velit fringilla. Nullam porta faucibus justo vitae laoreet. Pellentesque viverra id nunc eu varius. Nulla pulvinar lobortis iaculis. Etiam vestibulum odio nec velit tristique, a tristique nisi mattis. In sed fringilla orci, vitae efficitur odio. Quisque dui odio, ornare eget velit at, lacinia consequat libero. Quisque lectus nulla, aliquet eu leo in, porta rutrum diam. Donec nec mattis neque. Nam rutrum, odio ac eleifend bibendum, dolor arcu rutrum neque, eget porta elit tellus a lacus. Sed massa metus, sollicitudin et sapien eu, finibus tempus orci. Proin et sapien sit amet erat molestie interdum. In quis rutrum velit, faucibus ultrices tellus. - -Sed sagittis sed justo eget tincidunt. Maecenas ut leo sagittis, feugiat magna et, viverra velit. Maecenas ex arcu, feugiat at consequat vitae, auctor eu massa. Integer egestas, enim vitae maximus convallis, est lectus pretium mauris, ac posuere lectus nisl quis quam. Aliquam tempus laoreet mi, vitae dapibus dolor varius dapibus. Suspendisse potenti. Donec sit amet purus nec libero dapibus tristique. Pellentesque viverra bibendum ligula. Donec sed felis et ex lobortis laoreet. Phasellus a fringilla libero, vitae malesuada nulla. Pellentesque blandit mattis lacus, et blandit tortor laoreet consequat. Suspendisse libero nunc, viverra sed fermentum in, accumsan egestas arcu. Proin in placerat elit. Sed interdum imperdiet malesuada. Suspendisse aliquet quis mauris eget sollicitudin. - -Vivamus accumsan tellus non erat volutpat, quis dictum dolor feugiat. Praesent rutrum nunc ac est mollis cursus. Fusce semper volutpat dui ut egestas. Curabitur sit amet posuere massa. Cras tincidunt nulla et mi mollis imperdiet. Suspendisse scelerisque ex id sodales vulputate. In nunc augue, pharetra in placerat eu, mattis id tellus. Vivamus cursus efficitur vehicula. Nulla aliquet vehicula aliquet. - -Sed cursus tellus sed porta pulvinar. Sed vitae nisi neque. Nullam aliquet, lorem et efficitur scelerisque, arcu diam aliquam felis, sed pulvinar lorem odio et turpis. Praesent convallis pulvinar turpis eu iaculis. Aliquam nec gravida mi. Curabitur eu nibh tempor, blandit justo in, ultrices felis. Fusce placerat metus non mi sagittis rutrum. Morbi sed dui fringilla, sagittis mauris eget, imperdiet nunc. Phasellus hendrerit sem elit, id hendrerit libero auctor sit amet. Integer sodales elit sit amet consequat cursus. - -Nam semper est eget nunc mollis, in pellentesque lectus fringilla. In finibus vel diam id semper. Nunc mattis quis erat eu consectetur. In hac habitasse platea dictumst. Nullam et ipsum vestibulum ex pulvinar ultricies sit amet id velit. Aenean suscipit mi tortor, a lobortis magna viverra non. Nulla condimentum aliquet ante et ullamcorper. Pellentesque porttitor arcu a posuere tempus. Aenean lacus quam, imperdiet eu justo vitae, pretium efficitur ex. Duis id purus id magna rhoncus ultrices id eu risus. Nunc dignissim et libero id dictum. - -Quisque a tincidunt neque. Phasellus commodo mi sit amet tempor fringilla. Ut rhoncus, neque non porttitor elementum, libero nulla egestas augue, sed fringilla sapien felis ac velit. Phasellus viverra rhoncus mollis. Nam ullamcorper leo vel erat laoreet luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus semper a metus a cursus. Nulla sed orci egestas, efficitur purus ac, malesuada tellus. Aenean rutrum velit at tellus fermentum mollis. Aliquam eleifend euismod metus. - -In hac habitasse platea dictumst. Vestibulum volutpat neque vitae porttitor laoreet. Nam at tellus consequat, sodales quam in, pulvinar arcu. Maecenas varius convallis diam, ac lobortis tellus pellentesque quis. Maecenas eget augue massa. Nullam volutpat nibh ac justo rhoncus, ut iaculis tellus rutrum. Fusce efficitur efficitur libero quis condimentum. Curabitur congue neque non tincidunt tristique. Fusce eget tempor ex, at pellentesque odio. Praesent luctus dictum vestibulum. Etiam non orci nunc. Vivamus vitae laoreet purus, a lobortis velit. Curabitur tincidunt purus ac lectus elementum pellentesque. Quisque sed tincidunt est. - -Sed vel ultrices massa, vitae ultricies justo. Cras finibus mauris nec lacus tempus dignissim. Cras faucibus maximus velit, eget faucibus orci luctus vehicula. Nulla massa nunc, porta ac consequat eget, rhoncus non tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce sed maximus metus, vel imperdiet ipsum. Ut scelerisque lectus at blandit porttitor. Ut vulputate nunc pharetra, aliquet sapien ac, sollicitudin sapien. Aenean eget ante lorem. Nam accumsan venenatis tellus id dignissim. - -Curabitur fringilla, magna non maximus dapibus, nulla sapien vestibulum lectus, sit amet semper dolor neque vitae nisl. Nunc ultrices vehicula augue sed iaculis. Maecenas nec diam mollis, suscipit orci et, vestibulum ante. Pellentesque eu nisl tortor. Nunc eleifend, lacus quis volutpat volutpat, nisi mi molestie sem, quis mollis ipsum libero a tellus. Ut viverra dolor mattis convallis interdum. Sed tempus nisl at nunc scelerisque aliquet. Quisque tempor tempor lorem id feugiat. Nullam blandit lectus velit, vitae porta lacus tincidunt a. Vivamus sit amet arcu ultrices, tincidunt mi quis, viverra quam. Aenean fringilla libero elementum lorem semper, quis pulvinar eros gravida. Nullam sodales blandit mauris, sed fermentum velit fermentum sit amet. Donec malesuada mauris in augue sodales vulputate. Vestibulum gravida turpis id elit rhoncus dignissim. Integer non congue lorem, eu viverra orci. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec at dolor magna. Aliquam consectetur erat augue, id iaculis velit pharetra ac. Integer rutrum venenatis dignissim. Integer non sodales elit. Curabitur ut magna ut nibh feugiat aliquam ac ut risus. Morbi nibh quam, aliquam id placerat nec, vestibulum eget velit. Suspendisse at dignissim quam. Vivamus aliquet sem sed nisl volutpat, ut cursus orci ultrices. Aliquam ultrices lacinia enim, vitae aliquet neque. - -Quisque scelerisque finibus diam in mattis. Cras cursus auctor velit. Aliquam sem leo, fermentum et maximus et, molestie a libero. Aenean justo elit, rutrum a ornare id, egestas eget enim. Aenean auctor tristique erat. Curabitur condimentum libero lacus, nec consequat orci vestibulum sed. Fusce elit ligula, blandit vitae sapien vitae, dictum ultrices risus. Nam laoreet suscipit sapien, at interdum velit faucibus sit amet. Duis quis metus egestas lectus elementum posuere non nec libero. Aliquam a dolor bibendum, facilisis nunc a, maximus diam. Vestibulum suscipit tristique magna, non dignissim turpis sodales sed. Nunc ornare, velit ac facilisis fringilla, dolor mi consectetur lorem, vitae finibus erat justo suscipit urna. Maecenas sit amet eros erat. Nunc non arcu ornare, suscipit lorem eget, sodales mauris. Aliquam tincidunt, quam nec mollis lacinia, nisi orci fermentum libero, consequat eleifend lectus quam et sapien. Vestibulum a quam urna. - -Cras arcu leo, euismod ac ullamcorper at, faucibus sed massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus porttitor velit in enim interdum, non commodo metus ornare. Morbi vel lorem quis nisl luctus tristique quis vitae nisl. Suspendisse condimentum tortor enim, nec eleifend ipsum euismod et. Sed gravida quam ut tristique lacinia. Mauris eu interdum ipsum, ac ultrices odio. Nullam auctor tellus a risus porttitor vehicula. Nulla blandit euismod dictum. In pharetra, enim iaculis pulvinar interdum, dui nunc placerat nunc, sit amet pretium lectus nulla vitae quam. Phasellus quis enim sollicitudin, varius nulla id, ornare purus. Donec quam lacus, vestibulum quis nunc ac, mollis dictum nisi. Cras ut mollis elit. Maecenas ultrices ligula at risus faucibus scelerisque. Etiam vitae porttitor purus. Curabitur blandit lectus urna, ut hendrerit tortor feugiat ut. - -Phasellus fringilla, sapien pellentesque commodo pharetra, ante libero aliquam tellus, ut consectetur augue libero a sapien. Maecenas blandit luctus nisl eget aliquet. Maecenas vitae porta dolor, faucibus laoreet sapien. Suspendisse lobortis, ipsum sed vehicula aliquam, elit purus scelerisque dui, rutrum consectetur diam odio et lorem. In nec lacinia metus. Donec viverra libero est, vel bibendum erat condimentum quis. Donec feugiat purus leo. In laoreet vitae felis a porttitor. Mauris ullamcorper, lacus id condimentum suscipit, neque magna pellentesque arcu, eget cursus neque tellus id metus. Curabitur volutpat ac orci vel ultricies. - -Sed ut finibus erat. Sed diam purus, varius non tincidunt quis, ultrices sit amet ipsum. Donec et egestas nulla. Suspendisse placerat nisi at dui laoreet iaculis. Aliquam aliquet leo at augue faucibus molestie. Nullam lacus augue, hendrerit sed nisi eu, faucibus porta est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam ut leo aliquet sem fermentum rutrum quis ac justo. Integer placerat aliquam nisl ut sagittis. Proin erat orci, lobortis et sem eget, eleifend fringilla augue. Mauris varius laoreet arcu, sed tincidunt felis. Pellentesque venenatis lorem odio, id pulvinar velit molestie feugiat. Donec mattis lacus sed eleifend pulvinar. - -Sed condimentum ex in tincidunt hendrerit. Etiam eget risus lacinia, euismod nibh eu, pellentesque quam. Proin elit eros, convallis id mauris ac, bibendum ultrices lectus. Morbi venenatis, purus id fermentum consequat, nunc libero tincidunt ligula, non dictum ligula orci nec quam. Nulla nec ultrices lorem. Aenean maximus augue vel dictum pharetra. Etiam turpis urna, pellentesque quis malesuada eu, molestie faucibus felis. - -Vestibulum pharetra augue ut quam blandit congue in nec risus. Proin eu nibh eu dui eleifend porta vitae id lectus. Proin lacus nibh, lobortis sed ligula vitae, interdum lobortis erat. Suspendisse potenti. In sollicitudin quis sapien ut aliquet. Mauris ac nulla arcu. Fusce tristique justo quis lectus mollis, eu volutpat lectus finibus. Vivamus venenatis facilisis ex ut vestibulum. - -Etiam varius lobortis purus, in hendrerit elit tristique at. In tempus, augue vestibulum fermentum gravida, ligula tellus vulputate arcu, eu molestie ex sapien at purus. Vestibulum nec egestas metus. Duis pulvinar quam nec consequat interdum. Aenean non dapibus lacus. Aliquam sit amet aliquet nulla. Sed venenatis volutpat purus nec convallis. Phasellus aliquet semper sodales. Cras risus sapien, condimentum auctor urna a, pulvinar ornare nisl. Sed tincidunt felis elit, ut elementum est bibendum ac. Morbi interdum justo vel dui faucibus condimentum. - -Sed convallis eu sem at tincidunt. Nullam at auctor est, et ullamcorper ipsum. Pellentesque eget ante ante. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer euismod, sapien sed dapibus ornare, nibh enim maximus lacus, lacinia placerat urna quam quis felis. Morbi accumsan id nisl ut condimentum. Donec bibendum nisi est, sed volutpat lorem rhoncus in. Vestibulum ac lacinia nunc, eget volutpat magna. Integer aliquam pharetra ipsum, id placerat nunc volutpat quis. Etiam urna diam, rhoncus sit amet varius vel, euismod vel sem. Nullam vel molestie urna. Vivamus ornare erat at venenatis euismod. Suspendisse potenti. Fusce diam justo, tincidunt vel sem at, commodo faucibus nisl. Duis gravida efficitur diam, vel sagittis erat pulvinar ut. - -Quisque vel pharetra felis. Duis efficitur tortor dolor, vitae porttitor erat fermentum sed. Sed eu mi purus. Etiam dignissim tortor eu tempus molestie. Aenean pretium erat enim, in hendrerit ante hendrerit at. Sed ut risus vel nunc venenatis ultricies quis in lacus. Pellentesque vitae purus euismod, placerat risus non, ullamcorper augue. Quisque varius quam ligula, nec aliquet ex faucibus vitae. Quisque rhoncus sit amet leo tincidunt mattis. Cras id mauris eget purus pretium gravida sit amet eu augue. Aliquam dapibus odio augue, id lacinia velit pulvinar eu. - -Mauris fringilla, tellus nec pharetra iaculis, neque nisi ultrices massa, et tincidunt sem dui sed mi. Curabitur erat lorem, venenatis quis tempus lacinia, tempus sit amet nunc. Aliquam at neque ac metus commodo dictum quis vitae justo. Phasellus eget lacus tempus, blandit lorem vel, rutrum est. Aenean pharetra sem ut augue lobortis dignissim. Sed rhoncus at nulla id ultrices. Cras id condimentum felis. In suscipit luctus vulputate. Donec tincidunt lacus nec enim tincidunt sollicitudin ut quis enim. Nam at libero urna. Praesent sit amet massa vitae massa ullamcorper vehicula. - -Nullam bibendum augue ut turpis condimentum bibendum. Proin sit amet urna hendrerit, sodales tortor a, lobortis lectus. Integer sagittis velit turpis, et tincidunt nisi commodo eget. Duis tincidunt elit finibus accumsan cursus. Aenean dignissim scelerisque felis vel lacinia. Nunc lacinia maximus luctus. In hac habitasse platea dictumst. Vestibulum eget urna et enim tempor tempor. Nam feugiat, felis vel vestibulum tempus, orci justo viverra diam, id dapibus lorem justo in ligula. - -Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In ac pellentesque sem. Vestibulum lacinia magna dui, eu lacinia augue placerat et. Maecenas pulvinar congue est. Pellentesque commodo dui non pulvinar scelerisque. Etiam interdum est posuere sem bibendum, ac commodo magna dictum. Cras ipsum turpis, rhoncus nec posuere vitae, laoreet a arcu. Integer ac massa sit amet enim placerat lacinia sed ultrices arcu. Suspendisse sem nibh, luctus sit amet volutpat in, pellentesque eu metus. Ut gravida neque eget mi accumsan tempus. Nam sit amet aliquet nibh. - -Pellentesque a purus cursus nulla hendrerit congue quis et odio. Aenean hendrerit, leo ullamcorper sagittis hendrerit, erat dui molestie quam, sed condimentum lacus risus sed tellus. Morbi a dapibus lectus, ut feugiat ex. Phasellus pretium quam et sapien mollis, vel iaculis dui dignissim. Sed ullamcorper est turpis, a viverra lorem consectetur in. Aenean aliquet nibh non cursus rutrum. Suspendisse at tristique urna, id lobortis urna. In hac habitasse platea dictumst. Phasellus libero velit, rutrum sed tellus nec, dapibus tincidunt ligula. Quisque vel dui venenatis, consequat nisl ut, lacinia ipsum. Phasellus vitae magna pellentesque, lobortis est id, faucibus quam. Nam eleifend faucibus dui vel pellentesque. - -Etiam ut est non lacus tincidunt interdum. Maecenas sed massa urna. Quisque ut nibh tortor. Pellentesque felis ipsum, tempor finibus ipsum et, euismod pretium metus. Donec sit amet est ipsum. Quisque rhoncus justo non finibus elementum. Nulla nec lectus ac tortor placerat fringilla. Phasellus ac ultrices nunc, eu efficitur nisl. Nulla rhoncus nunc vitae ante dictum tincidunt. Nunc ultrices, massa sit amet malesuada dignissim, lectus lacus consequat sapien, non eleifend metus sem in eros. Phasellus mauris ante, dictum sit amet suscipit ac, rhoncus eget nisi. Phasellus at orci mollis, imperdiet neque eget, faucibus nulla. In at purus massa. Pellentesque quis rutrum lectus. - -Integer eu faucibus turpis, sit amet mollis massa. Vestibulum id nulla commodo, rutrum ipsum sed, semper ante. Phasellus condimentum orci nec nibh convallis, ac maximus orci ullamcorper. Maecenas vitae sollicitudin mi. Integer et finibus lectus, et condimentum ligula. Donec elementum tristique quam vitae dapibus. Morbi euismod ipsum in tristique ullamcorper. - -Duis fermentum non enim eu auctor. Quisque lacinia nibh vehicula nibh posuere, eu volutpat turpis facilisis. Ut ac faucibus nulla. Sed eleifend quis ex et pellentesque. Vestibulum sollicitudin in libero id fringilla. Phasellus dignissim purus consequat, condimentum dui sit amet, condimentum ante. Pellentesque ac consectetur massa, quis sagittis est. Nulla maximus tristique risus accumsan convallis. Curabitur imperdiet ac lacus a ultrices. Nulla facilisi. Sed quis quam quis lectus placerat lobortis vel sed turpis. In mollis dui id neque iaculis, ut aliquet tellus malesuada. Proin at luctus odio, vel blandit sapien. Praesent dignissim tortor vehicula libero fringilla, nec ultrices erat suscipit. Maecenas scelerisque purus in dapibus fermentum. - -Curabitur magna odio, mattis in tortor ut, porttitor congue est. Vestibulum mollis lacinia elementum. Fusce maximus erat vitae nunc rutrum lobortis. Integer ligula eros, auctor vel elit non, posuere luctus lacus. Maecenas quis auctor massa. Ut ipsum lacus, efficitur posuere euismod et, hendrerit efficitur est. Phasellus fringilla, quam id tincidunt pretium, nunc dui sollicitudin orci, eu dignissim nisi metus ut magna. Integer lobortis interdum dolor, non bibendum purus posuere et. Donec non lectus aliquet, pretium dolor eu, cursus massa. Sed ut dui sapien. In sed vestibulum massa. Pellentesque blandit, dui non sodales vehicula, orci metus mollis nunc, non pharetra ex tellus ac est. Mauris sagittis metus et fermentum pretium. Nulla facilisi. Quisque quis ante ut nulla placerat mattis ut quis nisi. - -Sed quis nulla ligula. Quisque dignissim ligula urna, sed aliquam purus semper at. Suspendisse potenti. Nunc massa lectus, pharetra vehicula arcu bibendum, imperdiet sodales ipsum. Nam ac sapien diam. Mauris iaculis fringilla mattis. Pellentesque tempus eros sit amet justo volutpat mollis. Phasellus ac turpis ipsum. Morbi vel ante elit. Aenean posuere quam consequat velit varius suscipit. Donec tempor quam ut nibh cursus efficitur. - -Morbi molestie dolor nec sem egestas suscipit. Etiam placerat pharetra lectus, et ullamcorper risus tristique in. Sed faucibus ullamcorper lectus eget fringilla. Maecenas malesuada hendrerit congue. Sed eget neque a erat placerat tincidunt. Aliquam vitae dignissim turpis. Fusce at placerat magna, a laoreet lectus. Maecenas a purus nec diam gravida fringilla. Nam malesuada euismod ante non vehicula. In faucibus bibendum leo, faucibus posuere nisl pretium quis. Fusce finibus bibendum finibus. Vestibulum eu justo maximus, hendrerit diam nec, dignissim sapien. Aenean dolor lacus, malesuada quis vestibulum ac, venenatis ac ipsum. Cras a est id nunc finibus facilisis. Cras lacinia neque et interdum vehicula. Suspendisse vulputate tellus elit, eget tempor dui finibus vel. - -Cras sed pretium odio. Proin hendrerit elementum felis in tincidunt. Nam sed turpis vel justo molestie accumsan condimentum eu nunc. Praesent lobortis euismod rhoncus. Nulla vitae euismod nibh, quis mattis mi. Fusce ultrices placerat porttitor. Duis sem ipsum, pellentesque sit amet odio a, molestie vulputate mauris. - -Duis blandit mollis ligula, sit amet mattis ligula finibus sit amet. Nunc a leo molestie, placerat diam et, vestibulum leo. Suspendisse facilisis neque purus, nec pellentesque ligula fermentum nec. Aenean malesuada mauris lorem, eu blandit arcu pulvinar quis. Duis laoreet urna lacus, non maximus arcu rutrum ultricies. Nulla augue dolor, suscipit eu mollis eu, aliquam condimentum diam. Ut semper orci luctus, pharetra turpis at, euismod mi. Nulla leo diam, finibus sit amet purus sed, maximus dictum lorem. Integer eu mi id turpis laoreet rhoncus. - -Integer a mauris tincidunt, finibus orci ut, pretium mauris. Nulla molestie nunc mi, id finibus lorem elementum sed. Proin quis laoreet ante. Integer nulla augue, commodo id molestie quis, rutrum ut turpis. Suspendisse et tortor turpis. Sed ut pharetra massa. Pellentesque elementum blandit sem, ut elementum tellus egestas a. Fusce eu purus nibh. - -Cras dignissim ligula scelerisque magna faucibus ullamcorper. Proin at condimentum risus, auctor malesuada quam. Nullam interdum interdum egestas. Nulla aliquam nisi vitae felis mollis dictum. Suspendisse dapibus consectetur tortor. Ut ut nisi non sem bibendum tincidunt. Vivamus suscipit leo quis gravida dignissim. - -Aliquam interdum, leo id vehicula mollis, eros eros rhoncus diam, non mollis ligula mi eu mauris. Sed ultrices vel velit sollicitudin tincidunt. Nunc auctor metus at ligula gravida elementum. Praesent interdum eu elit et mollis. Duis egestas quam sit amet velit dignissim consequat. Aliquam ac turpis nec nunc convallis sagittis. Fusce blandit, erat ac fringilla consectetur, dolor eros sodales leo, vel aliquet risus nisl et diam. Aliquam luctus felis vitae est eleifend euismod facilisis et lacus. Sed leo tellus, auctor eu arcu in, volutpat sagittis nisl. Pellentesque nisl ligula, placerat vel ullamcorper at, vulputate ac odio. Morbi ac faucibus orci, et tempus nulla. Proin rhoncus rutrum dolor, in venenatis mauris. Suspendisse a fermentum augue, non semper mi. Nunc eget pretium neque. Phasellus augue erat, feugiat ac aliquam congue, rutrum non sapien. Pellentesque ac diam gravida, consectetur felis at, ornare neque. - -Nullam interdum mattis sapien quis porttitor. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus aliquet rutrum ipsum id euismod. Maecenas consectetur massa et mi porta viverra. Nunc quam nibh, dignissim vitae maximus et, ullamcorper nec lorem. Nunc vitae justo dapibus, luctus lacus vitae, pretium elit. Maecenas et efficitur leo. Curabitur mauris lectus, placerat quis vehicula vitae, auctor ut urna. Quisque rhoncus pharetra luctus. In hac habitasse platea dictumst. Integer sit amet metus nec eros malesuada aliquam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi hendrerit mi ac leo aliquam, sit amet ultricies libero commodo. Mauris dapibus purus metus, sit amet viverra nibh imperdiet et. Nullam porta nulla tellus, quis vehicula diam imperdiet non. Vivamus enim massa, bibendum in fermentum in, ultrices at ex. - -Suspendisse fermentum id nibh eget accumsan. Duis dapibus bibendum erat ut sollicitudin. Aliquam nec felis risus. Pellentesque rhoncus ligula id sem maximus mollis sed nec massa. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ipsum ipsum, sodales sed enim id, convallis faucibus eros. Donec ultricies dictum tincidunt. Cras vitae nibh arcu. Pellentesque cursus, sapien nec consequat fermentum, ipsum ante suscipit dui, imperdiet hendrerit est nisl eu massa. Quisque vitae sem ligula. Aenean iaculis metus ut mauris interdum laoreet. Vivamus sed gravida dolor. - -Morbi nulla metus, porttitor sed eros sit amet, efficitur efficitur est. In vel nisl urna. Ut aliquet tellus at congue convallis. Phasellus imperdiet lobortis sollicitudin. Integer sodales, sem eu ultricies pharetra, erat erat porttitor odio, eget dapibus libero ipsum eget velit. Phasellus gravida nulla nisl, eu pharetra mi auctor vel. Sed blandit pharetra velit, ut egestas libero placerat non. Aliquam a interdum quam. Proin at tortor nec dui sollicitudin tempus sed vestibulum elit. Nunc non sollicitudin velit. - -Aenean consequat diam velit, sed rutrum tortor faucibus dictum. Quisque at semper augue. Duis ut est eget mi ornare bibendum id et ligula. Phasellus consequat tortor non leo pulvinar posuere. Proin vestibulum eleifend felis, in hendrerit tortor sollicitudin eu. Phasellus hendrerit, lacus vel laoreet interdum, dui tortor consequat justo, commodo ultricies arcu felis vitae enim. Vivamus eu sapien at leo suscipit rutrum eu at justo. Aenean et dolor a libero ullamcorper posuere. Integer laoreet placerat nisi in vulputate. Mauris laoreet eget risus sed cursus. Donec scelerisque neque a libero eleifend hendrerit. Nulla varius condimentum nunc sit amet fermentum. Aliquam lorem ex, varius nec mollis ut, ultrices in neque. Morbi sit amet porta leo. Integer iaculis fermentum lacus in vestibulum. - -Ut gravida, tellus ut maximus ultrices, erat est venenatis nisl, vitae pretium massa ex ac magna. Sed non purus eget ligula aliquet volutpat non quis arcu. Nam aliquam tincidunt risus, sit amet fringilla sapien vulputate ut. Mauris luctus suscipit pellentesque. Nunc porttitor dapibus ex quis tempus. Ut ullamcorper metus a eros vulputate, vitae viverra lectus convallis. Mauris semper imperdiet augue quis tincidunt. Integer porta pretium magna, sed cursus sem scelerisque sollicitudin. Nam efficitur, nibh pretium eleifend vestibulum, purus diam posuere sem, in egestas mauris augue sit amet urna. - -Vestibulum tincidunt euismod massa in congue. Duis interdum metus non laoreet fringilla. Donec at ligula congue, tincidunt nunc non, scelerisque nunc. Donec bibendum magna non est scelerisque feugiat at nec neque. Ut orci tortor, tempus eget massa non, dignissim faucibus dolor. Nam odio risus, accumsan pretium neque eget, accumsan dignissim dui. In ut neque auctor, scelerisque tellus sed, ullamcorper nisi. Suspendisse varius cursus quam at hendrerit. Vivamus elit libero, sagittis vitae sem ac, vulputate iaculis ligula. - -Sed lobortis laoreet purus sit amet rutrum. Pellentesque feugiat non leo vel lacinia. Quisque feugiat nisl a orci bibendum vestibulum. In et sollicitudin urna. Morbi a arcu ac metus faucibus tempus. Nam eu imperdiet sapien, suscipit mattis tortor. Aenean blandit ipsum nisi, a eleifend ligula euismod at. Integer tincidunt pharetra felis, mollis placerat mauris hendrerit at. Curabitur convallis, est sit amet luctus volutpat, massa lacus cursus augue, sed eleifend magna quam et risus. Aliquam lobortis tincidunt metus vitae porttitor. Suspendisse potenti. Aenean ullamcorper, neque id commodo luctus, nulla nunc lobortis quam, id dapibus neque dui nec mauris. Etiam quis lorem quis elit commodo ornare. Ut pharetra purus ultricies enim ultrices efficitur. Proin vehicula tincidunt molestie. Mauris et placerat sem. - -Aliquam erat volutpat. Suspendisse velit turpis, posuere ac lacus eu, lacinia laoreet velit. Sed interdum felis neque, id blandit sem malesuada sit amet. Ut sagittis justo erat, efficitur semper orci tempor sed. Donec enim massa, posuere varius lectus egestas, pellentesque posuere mi. Cras tincidunt ut libero sed mattis. Suspendisse quis magna et tellus posuere interdum vel at purus. Pellentesque fringilla tristique neque, id aliquet tellus ultricies non. Duis ut tellus vel odio lobortis vulputate. - -Integer at magna ac erat convallis vestibulum. Sed lobortis porttitor mauris. Fusce varius lorem et volutpat pulvinar. Aenean ac vulputate lectus, vitae consequat velit. Suspendisse ex dui, varius ut risus ut, dictum scelerisque sem. Vivamus urna orci, volutpat ut convallis ac, venenatis vitae urna. In hac habitasse platea dictumst. Etiam eu purus arcu. Aenean vulputate leo urna, vel tristique dui sagittis euismod. Suspendisse non tellus efficitur ante rhoncus volutpat at et sapien. - -Sed dapibus accumsan porttitor. Phasellus facilisis lectus finibus ligula dignissim, id pulvinar lectus feugiat. Nullam egestas commodo nisi posuere aliquet. Morbi sit amet tortor sagittis, rutrum dui nec, dapibus sapien. Sed posuere tortor tortor, interdum auctor magna varius vitae. Vestibulum id sagittis augue. Curabitur fermentum arcu sem, eu condimentum quam rutrum non. Phasellus rutrum nibh quis lectus rhoncus pretium. Curabitur dictum interdum elit. Vestibulum maximus sodales imperdiet. Mauris auctor nec purus sed venenatis. In in urna purus. - -Duis placerat molestie suscipit. Morbi a elit id purus efficitur consequat. Nunc ac commodo turpis. Etiam sit amet lacus a ipsum tempus venenatis sed vel nibh. Duis elementum aliquam mi sed tristique. Morbi ligula tortor, semper ac est vel, lobortis maximus erat. Curabitur ipsum felis, laoreet vel condimentum eget, ullamcorper sit amet mauris. Nulla facilisi. Nam at purus sed mi egestas placerat vitae vel magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse at dignissim diam. Phasellus consectetur eget neque vel viverra. Donec sollicitudin mattis dolor vel malesuada. Vivamus vehicula leo neque, vitae fermentum leo posuere et. Praesent dui est, finibus sit amet tristique quis, pharetra vel nibh. - -Duis nulla leo, accumsan eu odio eget, sagittis semper orci. Quisque ullamcorper ligula quam, commodo porttitor mauris ullamcorper eu. Cras varius sagittis felis in aliquam. Duis sodales risus ac justo vehicula, nec mattis diam lacinia. Cras eget lectus ipsum. Ut commodo, enim vitae malesuada hendrerit, ex dolor egestas lectus, sit amet hendrerit metus diam nec est. Vestibulum tortor metus, lobortis sit amet ante eget, tempor molestie lacus. In molestie et urna et semper. Mauris mollis, sem non hendrerit condimentum, sapien nisi cursus est, non suscipit quam justo non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam enim est, porta ac feugiat vitae, rutrum in lorem. Duis vehicula tortor ut posuere maximus. - -Nullam vestibulum non tellus sed commodo. Quisque mattis elit sit amet sapien sollicitudin, ut condimentum nisl congue. Aenean sagittis massa vel elit faucibus fermentum. Donec tincidunt nisi nec nisl sodales pellentesque. Mauris congue congue ligula ut suscipit. Vivamus velit tortor, tempor et gravida eget, fermentum sit amet ante. Nullam fringilla, lorem at ultrices cursus, urna neque ornare dolor, eu lacinia orci enim sed nibh. Ut a ullamcorper lectus, id mattis purus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean maximus sollicitudin posuere. Nunc at augue lacus. Aenean efficitur leo sit amet lacinia efficitur. - -Quisque venenatis quam mi, in pharetra odio vulputate eu. In vel nisl pulvinar, pulvinar ligula ut, sodales risus. Sed efficitur lectus at vestibulum tincidunt. Vestibulum eu ullamcorper elit. Fusce vestibulum magna enim, et tempor lacus posuere vitae. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer leo elit, luctus nec mattis sit amet, sollicitudin in turpis. - -Proin convallis venenatis leo, vitae tristique erat iaculis nec. Nulla facilisi. Duis porttitor, sapien et bibendum vulputate, sem libero sodales lacus, non malesuada felis erat ut libero. Nam non felis semper, finibus est a, mattis mauris. Praesent nec eros quam. Nulla hendrerit, augue consectetur eleifend ultricies, purus mi condimentum nulla, eget dapibus est nunc sed libero. Nullam elementum dui erat, vitae luctus libero sollicitudin et. Nulla odio magna, placerat in augue eu, dapibus imperdiet odio. Suspendisse imperdiet metus sit amet rhoncus dapibus. Cras at enim et urna vehicula cursus eu a mauris. Integer magna ante, eleifend ac placerat vitae, porta at nisi. Cras eget malesuada orci. Curabitur nunc est, vulputate id viverra et, dignissim sed odio. Curabitur non mattis sem. Sed bibendum, turpis vitae vehicula faucibus, nunc quam ultricies lectus, vitae viverra felis turpis at libero. - -Nullam ut egestas ligula. Proin hendrerit justo a lectus commodo venenatis. Nulla facilisi. Ut cursus lorem quis est bibendum condimentum. Aenean in tristique odio. Fusce tempor hendrerit ipsum. Curabitur mollis felis justo, quis dapibus erat auctor vel. Sed augue lectus, finibus ut urna quis, ullamcorper vestibulum dui. Etiam molestie aliquam tempor. Integer mattis sollicitudin erat, et tristique elit varius vel. Mauris a ex justo. - -Nam eros est, imperdiet non volutpat rutrum, pellentesque accumsan ligula. Duis sit amet turpis metus. Aenean in rhoncus metus, ac fringilla ex. Suspendisse condimentum egestas purus, ut pharetra odio vulputate vel. Duis tincidunt massa a placerat ultrices. Mauris ultricies nibh sit amet condimentum malesuada. Duis tincidunt id ipsum sed congue. - -Praesent eu ex augue. Nullam in porta ligula. In tincidunt accumsan arcu, in pellentesque magna tristique in. Mauris eleifend libero ac nisl viverra faucibus. Nam sollicitudin dolor in commodo hendrerit. Cras at orci metus. Ut quis laoreet orci. Vivamus ultrices leo pellentesque tempor aliquet. Maecenas ut eros vitae purus placerat vestibulum. Etiam vitae gravida dolor, quis rhoncus diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. - -Suspendisse fringilla lacinia sagittis. Integer tincidunt consectetur tristique. Morbi non orci convallis, congue sapien quis, vulputate nunc. Donec a libero vel magna elementum facilisis non quis mi. Mauris posuere tellus non ipsum ultrices elementum. Vivamus massa velit, facilisis quis placerat aliquet, aliquet nec leo. Praesent a maximus sem. Sed neque elit, feugiat vel quam non, molestie sagittis nunc. Etiam luctus nunc ac mauris scelerisque, nec rhoncus lacus convallis. Nunc pharetra, nunc ac pulvinar aliquam, ex ipsum euismod augue, nec porttitor lacus turpis vitae neque. Fusce bibendum odio id tortor faucibus pellentesque. Sed ac porta nibh, eu gravida erat. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam quis ullamcorper felis. Nulla mattis sagittis ante ac tincidunt. Integer ac felis efficitur, viverra libero et, facilisis ligula. Suspendisse a metus a massa rhoncus posuere. Phasellus suscipit ligula ut lacus facilisis, ac pellentesque ex tempor. Quisque consectetur massa mi, ac molestie libero dictum quis. Proin porttitor ligula quis erat tincidunt venenatis. Proin congue nunc sed elit gravida, nec consectetur lectus sodales. Etiam tincidunt convallis ipsum at vestibulum. Quisque maximus enim et mauris porttitor, et molestie magna tristique. Morbi vitae metus elit. Maecenas sed volutpat turpis. Aliquam vitae dolor vestibulum, elementum purus eget, dapibus nibh. Nullam egestas dui ac rutrum semper. - -Etiam hendrerit est metus, et condimentum metus aliquam ac. Pellentesque id neque id ipsum rhoncus vulputate. Aliquam erat nisl, posuere sit amet ligula ac, fermentum blandit felis. Vivamus fermentum mi risus, non lacinia purus viverra id. Aenean ac sapien consequat, finibus mauris nec, porta sem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed quis consectetur ex, dignissim bibendum nulla. Phasellus ac libero at quam vehicula euismod non eu leo. Phasellus a sapien augue. - -Maecenas ligula dui, bibendum vitae mauris et, auctor laoreet felis. Duis non libero a mi semper mattis. Quisque consequat luctus massa, quis tristique eros auctor feugiat. Maecenas sodales euismod neque vitae facilisis. Nullam laoreet imperdiet velit at pellentesque. Etiam massa odio, facilisis a consequat vitae, placerat vel magna. Nunc sagittis eros nec urna fringilla, pulvinar vestibulum nibh scelerisque. Sed magna metus, cursus eu consequat et, pharetra a est. Suspendisse elementum neque a dui malesuada lacinia. Donec sed ipsum volutpat, cursus urna id, ullamcorper arcu. Maecenas laoreet nisl eget velit egestas sollicitudin. Etiam nisl turpis, mollis id dignissim vitae, tristique vehicula ante. Maecenas eget placerat est, at rutrum augue. Vivamus faucibus lacinia ullamcorper. Sed pulvinar urna sodales ante sodales, at gravida leo dictum. - -Morbi maximus, quam a lobortis bibendum, enim felis varius elit, ac vehicula elit nisl ut lacus. Quisque ut arcu augue. Praesent id turpis quam. Sed sed arcu eros. Maecenas at cursus lorem, ac eleifend nisi. Fusce mattis felis at commodo pharetra. Praesent ac commodo ipsum. Quisque finibus et eros vitae tincidunt. In hac habitasse platea dictumst. Praesent purus ipsum, luctus lobortis ornare quis, auctor eget justo. Nam vel enim sollicitudin, faucibus tortor eu, sagittis eros. Ut nec consectetur erat. Donec ultricies malesuada ligula, a hendrerit sapien volutpat in. Maecenas sed enim vitae sapien pulvinar faucibus. - -Proin semper nunc nibh, non consequat neque ullamcorper vel. Maecenas lobortis sagittis blandit. Aenean et arcu ultricies turpis malesuada malesuada. Ut quam ex, laoreet ut blandit cursus, feugiat vitae dolor. Etiam ex lacus, scelerisque vel erat vel, efficitur tincidunt magna. Morbi tristique lacinia dolor, in egestas magna ultrices vitae. Integer ultrices leo ac tempus venenatis. Praesent ac porta tortor. Vivamus ornare blandit tristique. Nulla rutrum finibus pellentesque. In non dui elementum, fermentum ipsum vel, varius magna. Pellentesque euismod tortor risus, ac pellentesque nisl faucibus eget. - -Vivamus eu enim purus. Cras ultrices rutrum egestas. Sed mollis erat nibh, at posuere nisl luctus nec. Nunc vulputate, sapien id auctor molestie, nisi diam tristique ante, non convallis tellus nibh at orci. Morbi a posuere purus, in ullamcorper ligula. Etiam elementum sit amet dui imperdiet iaculis. Proin vitae tincidunt ipsum, sit amet placerat lectus. Curabitur commodo sapien quam, et accumsan lectus fringilla non. Nullam eget accumsan enim, ac pharetra mauris. Sed quis tristique velit, vitae commodo nisi. Duis turpis dui, maximus ut risus at, finibus consequat nunc. Maecenas sed est accumsan, aliquet diam in, facilisis risus. Curabitur vehicula rutrum auctor. Nam iaculis risus pulvinar maximus viverra. Nulla vel augue et ex sagittis blandit. - -Ut sem nulla, porta ac ante ac, posuere laoreet eros. Donec sodales posuere justo a auctor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras mollis at orci hendrerit porta. Nullam sodales tortor tortor, non lacinia diam finibus id. Duis libero orci, suscipit ac odio et, dictum consequat ipsum. Pellentesque eu ligula sagittis, volutpat eros at, lacinia lorem. Cras euismod tellus in iaculis tempor. Quisque accumsan, magna a congue venenatis, ante ipsum aliquam lectus, at egestas enim nunc at justo. Quisque sem purus, viverra ut tristique ut, maximus id enim. Etiam quis placerat sem. In sollicitudin, lacus eu rutrum mollis, nulla eros luctus elit, vel dapibus urna purus nec urna. Phasellus egestas massa quam, ac molestie erat hendrerit a. Praesent ultrices neque ut turpis molestie auctor. Etiam molestie placerat purus, et euismod erat aliquam in. Morbi id suscipit justo. - -Proin est ante, consequat at varius a, mattis quis felis. Sed accumsan nibh sit amet ipsum elementum posuere. Vestibulum bibendum id diam sit amet gravida. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi nec dolor vel ipsum dignissim hendrerit vel non ipsum. Praesent facilisis orci quis elit auctor lobortis. Phasellus cursus risus lectus, vel lobortis libero dapibus in. Quisque tristique tempus leo a pulvinar. Pellentesque a magna tincidunt, pellentesque massa nec, laoreet orci. Morbi congue ornare dolor quis commodo. Phasellus massa nisi, tincidunt at eros dictum, hendrerit lobortis urna. Maecenas porta, magna id mattis molestie, nibh tellus lobortis sem, eget tincidunt ipsum quam eu turpis. - -Ut gravida orci risus, vel rutrum mauris vehicula id. Etiam bibendum, neque a placerat condimentum, ex orci imperdiet lectus, quis dapibus arcu lacus eget lectus. Sed consequat non mi sit amet venenatis. Fusce vestibulum erat libero, eget hendrerit risus vulputate sollicitudin. Integer sed eleifend felis. Donec commodo, sem eu mattis placerat, urna odio aliquam tellus, et laoreet justo tellus eget erat. Fusce sed suscipit tortor. Nam hendrerit nibh ac nunc auctor lacinia. Pellentesque placerat condimentum ipsum, eget semper tortor hendrerit vel. Nullam non urna eu lacus pellentesque congue ut id eros. - -Nunc finibus leo in rhoncus tristique. Sed eu ipsum nec nisl egestas faucibus eget a felis. Pellentesque vitae nisi in nulla accumsan fermentum. Sed venenatis feugiat eleifend. Fusce porttitor varius placerat. Aliquam aliquet lacus sit amet mattis mollis. Sed vel nulla quis dolor suscipit vehicula ac viverra lorem. Duis viverra ipsum eget nulla ullamcorper fermentum. Mauris tincidunt arcu quis quam fringilla ornare. Donec et iaculis tortor. Nam ultricies libero vel ipsum aliquet efficitur. Morbi eget dolor aliquam, tempus sapien eget, viverra ante. Donec varius mollis ex, sed efficitur purus euismod interdum. Quisque vel sapien non neque tincidunt semper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. - -Suspendisse sit amet purus leo. Fusce lectus lorem, aliquam ac nulla eget, imperdiet ornare eros. Nullam sem augue, varius in nisi non, sollicitudin pellentesque ante. Etiam eu odio condimentum, tempor libero et, egestas arcu. Cras pellentesque eleifend aliquet. Pellentesque non blandit ligula. Ut congue viverra rhoncus. Phasellus mattis mi ac eros placerat, eu feugiat tellus ultrices. Aenean mollis laoreet libero eu imperdiet. Cras sed pulvinar mi, ac vehicula ligula. Vestibulum sit amet ex massa. In a egestas eros. - -Mauris pretium ipsum risus, venenatis cursus ante imperdiet id. Praesent eu turpis nec risus feugiat maximus ullamcorper ac lectus. Integer placerat at mi vel dapibus. Vestibulum fermentum turpis sit amet turpis viverra, id aliquet diam suscipit. Nam nec ex sed ante ullamcorper pharetra quis sit amet risus. Sed ac faucibus velit, id feugiat nibh. Nullam eget ipsum ex. Vivamus tincidunt non nunc non faucibus. Quisque bibendum viverra facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at nisi hendrerit quam suscipit egestas. Curabitur laoreet maximus ultricies. Duis ut tellus ac augue molestie dictum. - -Suspendisse rhoncus iaculis erat, ut ullamcorper est tristique eget. Donec auctor nec risus at gravida. Vivamus volutpat vulputate tellus, vel ultricies eros suscipit eget. Ut pulvinar id mi eu tempus. Morbi malesuada augue in dui varius, nec blandit neque vehicula. Donec ornare nec nisl in mollis. Morbi enim nisi, rhoncus nec est id, dapibus tempus urna. Ut id elit a felis vestibulum consectetur. Duis lectus quam, pharetra sit amet diam sed, posuere vestibulum erat. Fusce vitae maximus massa. Nullam id metus tempus, iaculis risus eu, lobortis urna. Quisque in congue urna. Pellentesque placerat neque in augue dapibus, non varius ex malesuada. Curabitur ut eleifend libero. Fusce vitae ligula luctus, fermentum enim vitae, ultrices erat. - -Sed viverra augue turpis, scelerisque egestas sapien mattis eu. Duis laoreet magna at ex pharetra dapibus. Praesent eget odio vel quam venenatis dictum. Nulla in sollicitudin dolor. Mauris lobortis nec eros vel rhoncus. Vestibulum porta viverra venenatis. Curabitur vel scelerisque quam, a egestas velit. Praesent volutpat tincidunt magna at laoreet. - -Cras nec lorem odio. Pellentesque quis dui urna. Praesent at tellus ac lectus scelerisque placerat nec eu risus. Vestibulum sit amet mattis ligula. Vivamus sed nisi at leo elementum accumsan at sit amet arcu. Aenean mattis tellus nec leo gravida, eget hendrerit nisl faucibus. Mauris pellentesque luctus condimentum. Maecenas pretium sapien nunc, eget commodo dolor maximus id. Mauris vestibulum accumsan massa a dictum. Phasellus interdum quam ligula, ut maximus diam blandit aliquam. Nunc vitae ex eu erat condimentum consectetur. Maecenas interdum condimentum volutpat. - -Donec et enim a libero rutrum laoreet. Praesent a condimentum sem, at tincidunt quam. In vel molestie risus. Sed urna dui, molestie vitae mollis laoreet, tempor quis lectus. Praesent vitae auctor est, et aliquet nunc. Curabitur vulputate blandit nulla, at gravida metus. Maecenas gravida dui eu iaculis tristique. Pellentesque posuere turpis nec auctor eleifend. Suspendisse bibendum diam eu tellus lobortis, et laoreet quam congue. In hac habitasse platea dictumst. Morbi dictum neque velit, eget rutrum eros ultrices sit amet. - -Phasellus fermentum risus pharetra consectetur bibendum. Donec magna tortor, lacinia vitae nibh quis, aliquet pretium lorem. Donec turpis nisi, pretium eu enim volutpat, mattis malesuada augue. Nullam vel tellus iaculis, sollicitudin elit eget, tincidunt lacus. Fusce elementum elementum felis et iaculis. Suspendisse porta eros nec neque malesuada, in malesuada ante sollicitudin. Vivamus bibendum viverra molestie. - -Integer feugiat, erat nec convallis aliquam, velit felis congue erat, molestie eleifend tellus erat in tellus. Nunc et justo purus. Donec egestas fermentum dui non feugiat. Quisque in sapien sagittis, gravida quam id, iaculis lectus. Cras sagittis rhoncus bibendum. Fusce quis metus in velit scelerisque tincidunt at non ipsum. Vivamus efficitur ante eu odio vulputate, vitae ultricies risus vehicula. Proin eget odio eu sem tincidunt feugiat vel id lorem. - -Vestibulum sit amet nulla dignissim, euismod mi in, fermentum tortor. Donec ut aliquet libero, lacinia accumsan velit. Donec et nulla quam. Nullam laoreet odio nec nunc imperdiet, a congue eros venenatis. Quisque nec tellus sit amet neque interdum posuere. Duis quis mi gravida, tincidunt diam convallis, ultricies augue. Mauris consequat risus non porttitor congue. Ut in ligula consequat, viverra nunc a, eleifend enim. Duis ligula urna, imperdiet nec facilisis et, ornare eu ex. Proin lobortis lectus a lobortis porttitor. Nulla leo metus, egestas eu libero sed, pretium faucibus felis. Vestibulum non sem tortor. Nam cursus est leo. Vivamus luctus enim odio, non interdum sem dapibus a. Aenean accumsan consequat lectus in imperdiet. - -Donec vehicula laoreet ipsum in posuere. Quisque vel quam imperdiet, sollicitudin nisi quis, suscipit velit. Morbi id sodales mauris. Curabitur tellus arcu, feugiat sed dui sit amet, sodales sagittis libero. Aenean vel suscipit metus, non placerat leo. Vestibulum quis nulla elit. Proin scelerisque non ante ut commodo. Interdum et malesuada fames ac ante ipsum primis in faucibus. - -Sed non urna dolor. Suspendisse convallis mi porta pulvinar ultrices. Suspendisse quam ipsum, hendrerit non scelerisque molestie, interdum dictum nunc. Morbi condimentum condimentum turpis eu luctus. Pellentesque sagittis sollicitudin odio, sed ultricies felis ornare sit amet. Sed ultrices ex leo, a tincidunt nisl gravida sed. Nullam ornare accumsan porta. Praesent consectetur id est nec sollicitudin. - -In hac habitasse platea dictumst. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sed ultrices nibh. Duis accumsan suscipit eros, a dictum odio tempus sit amet. Aenean imperdiet erat ac lacus finibus, scelerisque cursus massa imperdiet. Mauris molestie risus ut lacinia posuere. Nulla et sodales purus. Maecenas orci erat, placerat in tristique quis, placerat in mi. - -Donec sollicitudin pellentesque odio in feugiat. Morbi eu dolor ut mauris congue sollicitudin. Aliquam erat volutpat. Nulla id varius dui. Curabitur finibus urna ante, consectetur interdum nisi volutpat a. Quisque quis mi tristique, consequat tellus eget, rutrum sapien. Vivamus vitae tellus vulputate, rutrum ex eu, vulputate sem. Suspendisse viverra lorem tellus, vel interdum orci gravida quis. Ut laoreet arcu at mi ullamcorper finibus. Duis porta sagittis vestibulum. Sed commodo nisl vitae urna sollicitudin, nec lacinia est sodales. Curabitur imperdiet sodales dui sed iaculis. Sed ac tellus maximus, eleifend quam sit amet, feugiat elit. Aenean viverra, dui at mattis varius, est odio vestibulum sapien, sit amet mollis libero massa nec velit. Etiam quis sodales justo. - -Ut ultricies, sem eget sodales feugiat, nunc arcu congue elit, ac tempor justo massa nec purus. Maecenas enim nunc, pharetra eget dictum sit amet, tempus pellentesque velit. Suspendisse venenatis ligula in nulla mattis, et imperdiet ex tincidunt. Etiam vulputate, tellus et ultrices suscipit, enim velit laoreet massa, vitae congue odio enim ac urna. Morbi quam lorem, iaculis ac varius sagittis, euismod quis dolor. In ut dui eu purus feugiat consectetur. Vestibulum cursus velit quis lacus pellentesque iaculis. Cras in risus sed mauris porta rutrum. Nulla facilisi. Nullam eu bibendum est, non pellentesque lectus. Sed imperdiet feugiat lorem, quis convallis ante auctor in. Maecenas justo magna, scelerisque sit amet tellus eget, varius elementum risus. Duis placerat et quam sed varius. - -Duis nec nibh vitae nibh dignissim mollis quis sed felis. Curabitur vitae quam placerat, venenatis purus ut, euismod nisl. Curabitur porttitor nibh eu pulvinar ullamcorper. Suspendisse posuere nec ipsum ac dapibus. Cras convallis consectetur urna. Phasellus a nibh in dolor lacinia posuere id eget augue. In eu pharetra lorem, vitae cursus lacus. Aliquam tincidunt nibh lectus. Aenean facilisis ultricies posuere. Sed ut placerat orci. Curabitur scelerisque gravida blandit. Maecenas placerat ligula eget suscipit fringilla. Mauris a tortor justo. Aliquam hendrerit semper mollis. Phasellus et tincidunt libero. Etiam vel quam libero. - -Quisque aliquet tempor ex. Ut ante sem, vehicula at enim vel, gravida porta elit. Etiam vitae lacus a neque lobortis consectetur. Mauris sed interdum odio. Mauris elementum ex blandit tempor cursus. Integer in enim in leo viverra elementum. Fusce consectetur metus et sem rutrum, mattis euismod diam semper. Nunc sed ipsum vel urna consequat vehicula. Donec cursus pretium lorem, vestibulum pretium felis commodo sit amet. Nam blandit felis enim, eget gravida ex faucibus a. In nec neque massa. Etiam laoreet posuere ipsum. Praesent volutpat nunc dolor, ac vulputate magna facilisis non. Aenean congue turpis vel lectus sollicitudin tristique. Sed nec consequat purus, non vehicula quam. Etiam ultricies, est ac dictum tincidunt, turpis turpis pretium massa, a vulputate libero justo at nibh. - -Aliquam erat volutpat. Cras ultrices augue ac sollicitudin lobortis. Curabitur et aliquet purus. Duis feugiat semper facilisis. Phasellus lobortis cursus velit, a sollicitudin tortor. Nam feugiat sapien non dapibus condimentum. Morbi at mi bibendum, commodo quam at, laoreet enim. Integer eu ultrices enim. Sed vestibulum eu urna ut dictum. Curabitur at mattis leo, sed cursus massa. Aliquam porttitor, felis quis fermentum porttitor, justo velit feugiat nulla, eget condimentum sem dui ut sapien. - -In fringilla elit eu orci aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut eget fringilla tellus. Curabitur fermentum, mi et condimentum suscipit, elit neque bibendum dui, et hendrerit nunc metus id ipsum. Morbi placerat mi in hendrerit congue. Ut feugiat mauris eget scelerisque viverra. Vivamus sit amet erat dictum, sagittis lectus nec, pulvinar lorem. Sed non enim ac dui sollicitudin aliquet. Quisque ut lacus dolor. Fusce hendrerit malesuada euismod. Nulla faucibus vel mauris eu mollis. Mauris est diam, fringilla ac arcu feugiat, efficitur volutpat turpis. Aliquam venenatis cursus massa sed porttitor. Ut ac finibus enim, in tincidunt sapien. - -Nunc faucibus semper turpis a lacinia. Phasellus gravida, libero vel pulvinar ornare, ex sem tincidunt lectus, sit amet convallis augue risus at tortor. Quisque sit amet ipsum id nulla posuere vestibulum. Pellentesque scelerisque mauris vel leo viverra sodales. Nulla viverra aliquam ex, ut rutrum enim fermentum venenatis. Aenean eget dapibus ex, eget faucibus metus. Vestibulum volutpat leo in diam semper, eget porta magna suscipit. Sed sit amet nulla blandit, aliquam dolor ac, gravida velit. Sed vel velit viverra, maximus est id, convallis justo. - -Curabitur nulla ante, vulputate at libero vel, ullamcorper rutrum nibh. Pellentesque porttitor eu mauris id mattis. Duis vulputate augue elit, eget interdum justo pretium vel. Maecenas eu vulputate arcu, eget posuere purus. Suspendisse viverra a velit dictum eleifend. Suspendisse vitae dapibus diam. Donec vehicula justo in ante interdum, eu luctus diam placerat. Vivamus convallis ipsum eu orci suscipit, sed fermentum enim euismod. Maecenas faucibus elit vitae ex ornare tristique. Donec vestibulum nec elit sit amet porttitor. Aenean tempor lectus eget tortor hendrerit luctus. Nullam interdum vitae lectus vel feugiat. Cras in risus non magna consectetur lobortis. Sed faucibus enim quis gravida convallis. - -Phasellus eget massa sit amet libero ultrices suscipit. Vivamus at risus sapien. Nam mollis nunc eget velit dictum maximus. Sed pellentesque, nunc ac fringilla lacinia, quam enim mattis ex, sed euismod tortor metus eu neque. Ut mattis nisl ut lectus rhoncus, sodales bibendum eros porta. Nulla porttitor enim nec diam sagittis, eget porta velit efficitur. Vestibulum ultricies eros neque. Phasellus rutrum suscipit enim, in interdum ante gravida vitae. Sed in sagittis diam, non commodo velit. - -Morbi hendrerit odio orci, nec tincidunt odio rhoncus nec. Mauris neque velit, vehicula a lorem at, suscipit tristique dui. Sed finibus, nisl in mattis convallis, turpis neque sodales lacus, eu porta enim magna non diam. Nam commodo sodales risus consectetur malesuada. In eget elementum justo. Phasellus sit amet massa imperdiet, dapibus nunc sit amet, suscipit orci. Fusce condimentum laoreet feugiat. Ut ut viverra ante. Praesent bibendum interdum commodo. Nulla mollis nisi a est ornare volutpat. Sed at ligula eu nisi dapibus tempus. Proin cursus vestibulum justo, nec efficitur justo dignissim vel. Nunc quis maximus eros. - -Cras viverra, diam a tristique mattis, libero felis vulputate tellus, a ornare felis leo a dui. Nulla ante nulla, finibus ut tellus ut, blandit pharetra nibh. Proin eleifend fermentum ex, eget auctor libero vulputate in. Nullam ultricies, mauris placerat pretium placerat, leo urna lobortis leo, vel placerat arcu libero sed mauris. Aliquam mauris ligula, ornare at urna at, eleifend gravida ligula. Vestibulum consectetur ut nulla non scelerisque. Donec ornare, sem nec elementum aliquam, urna nulla bibendum metus, eu euismod dui ligula ac est. Fusce laoreet erat eu ex lobortis, quis bibendum ligula interdum. Sed vel mi erat. Vivamus id lacus ac enim mattis tempor. Nunc ultricies pellentesque enim sed euismod. Fusce tincidunt convallis elit quis aliquam. Mauris nulla ipsum, sollicitudin quis diam ac, feugiat volutpat tellus. In nibh nibh, vulputate quis tincidunt quis, pulvinar eget magna. Pellentesque quis finibus dolor. Suspendisse viverra vitae lectus non eleifend. - -Nunc ut orci et sapien maximus semper. Nulla dignissim sem urna, ac varius lectus ultricies id. Quisque aliquet pulvinar pretium. In ultricies molestie tellus vehicula porta. Nam enim lorem, aliquam eget ex et, hendrerit volutpat quam. Maecenas diam lacus, pellentesque eget tempus ac, pharetra eu elit. Donec vel eros a sem facilisis vulputate. Nullam ac nisi vulputate, laoreet nisl ac, eleifend sem. Nullam mi massa, rhoncus sed pharetra interdum, tincidunt eget nunc. Aliquam viverra mattis posuere. Mauris et dui sed nisl sollicitudin fermentum quis ut arcu. Nam placerat eget orci at tincidunt. Curabitur vel turpis metus. Phasellus nibh nulla, fermentum scelerisque sem vel, gravida tincidunt velit. Pellentesque vel quam tempor, finibus massa pellentesque, condimentum dui. - -Donec at mattis neque. Etiam velit diam, consequat auctor mauris id, hendrerit faucibus metus. Maecenas ullamcorper eros a est sodales, ac consectetur odio scelerisque. Donec leo metus, imperdiet at pellentesque vel, feugiat id erat. Suspendisse at magna enim. Vestibulum placerat sodales lorem id sollicitudin. Aenean at euismod ligula, eget mollis diam. Phasellus pulvinar, orci nec pretium condimentum, est erat facilisis purus, quis feugiat augue elit aliquam nulla. Aenean vitae tortor id risus congue tincidunt. Sed dolor enim, mattis a ullamcorper id, volutpat ac leo. - -Proin vehicula feugiat augue, id feugiat quam sodales quis. Donec et ultricies massa, a lacinia nulla. Duis aliquam augue ornare euismod viverra. Ut lectus risus, rutrum sit amet efficitur a, luctus nec nisl. Cras volutpat ullamcorper congue. Sed vitae odio metus. Phasellus aliquet euismod varius. - -Nullam sem ex, malesuada ut magna ut, pretium mollis arcu. Nam porttitor eros cursus mi lacinia faucibus. Suspendisse aliquet eleifend iaculis. Maecenas sit amet viverra tortor. Nunc a mollis risus. Etiam tempus dolor in tortor malesuada mattis. Ut tincidunt venenatis est sit amet dignissim. Vestibulum massa enim, tristique sed scelerisque eu, fringilla ac velit. Donec efficitur quis urna sit amet malesuada. Vestibulum consequat ac ligula in dapibus. Maecenas massa massa, molestie non posuere nec, elementum ut magna. In nisi erat, mollis non venenatis eu, faucibus in justo. Morbi gravida non ex non egestas. Pellentesque finibus laoreet diam, eu commodo augue congue vitae. - -Aenean sem mi, ullamcorper dapibus lobortis vitae, interdum tincidunt tortor. Vivamus eget vulputate libero. Ut bibendum posuere lectus, vel tincidunt tortor aliquet at. Phasellus malesuada orci et bibendum accumsan. Aliquam quis libero vel leo mollis porta. Sed sagittis leo ac lacus dictum, ac malesuada elit finibus. Suspendisse pharetra luctus commodo. Vivamus ultricies a odio non interdum. Vivamus scelerisque tincidunt turpis quis tempor. Pellentesque tortor ligula, varius non nunc eu, blandit sollicitudin neque. Nunc imperdiet, diam et tristique luctus, ipsum ex condimentum nunc, sit amet aliquam justo velit sed libero. Duis vel suscipit ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed tincidunt neque vel massa ultricies, id dictum leo consequat. Curabitur lobortis ultricies tellus, eget mattis nisl aliquam sit amet. - -Proin at suscipit justo. Vivamus ut vestibulum nisl. Pellentesque enim odio, pharetra non magna sed, efficitur auctor magna. Praesent tincidunt ante quis ante hendrerit viverra. Pellentesque vel ipsum id magna vulputate efficitur. Sed nec neque accumsan, pulvinar sapien quis, euismod mauris. Donec condimentum laoreet sapien quis gravida. Quisque sed mattis purus. Vestibulum placerat vel neque maximus scelerisque. - -Vestibulum mattis quam quis efficitur elementum. Duis dictum dolor ac scelerisque commodo. Fusce sollicitudin nisi sit amet dictum placerat. Suspendisse euismod pharetra eleifend. In eros nisl, porttitor sed mauris at, consectetur aliquet mauris. Donec euismod viverra neque sed fermentum. Phasellus libero magna, accumsan ut ultricies vitae, dignissim eget metus. Donec tellus turpis, interdum eget maximus nec, hendrerit eget massa. Curabitur auctor ligula in iaculis auctor. In ultrices quam suscipit cursus finibus. Aenean id mi at dolor interdum iaculis vitae ut lorem. Nullam sed nibh fringilla, lacinia odio nec, placerat erat. In dui libero, viverra ac viverra ac, pellentesque sit amet turpis. - -Nulla in enim ex. Sed feugiat est et consectetur venenatis. Cras varius facilisis dui vel convallis. Vestibulum et elit eget tellus feugiat pellentesque. In ut ante eu purus aliquet posuere. Nulla nec ornare sem, sed luctus lorem. Nam varius iaculis odio, eget faucibus nisl ullamcorper in. Sed eget cursus felis, nec efficitur nisi. - -Vivamus commodo et sem quis pulvinar. Pellentesque libero ante, venenatis vitae ligula sit amet, ornare sollicitudin nulla. Mauris eget tellus hendrerit, pulvinar metus quis, tempor nisi. Proin magna ex, laoreet sed tortor quis, varius fermentum enim. Integer eu dolor dictum, vulputate tortor et, aliquet ligula. Vestibulum vitae justo id mauris luctus sollicitudin. Suspendisse eget auctor neque, sodales egestas lorem. Vestibulum lacinia egestas metus vitae euismod. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus ex tellus, volutpat nec pulvinar sit amet, condimentum vitae dui. Curabitur vel felis sodales, lacinia nunc iaculis, ullamcorper augue. Pellentesque consequat dolor quis eros efficitur malesuada. Nulla ut malesuada lectus. - -Morbi et tristique ante. Aliquam erat volutpat. Vivamus vitae dui nec turpis pellentesque fermentum. Quisque eget velit massa. Pellentesque tristique aliquam nisl, eu sollicitudin justo venenatis sed. Duis eleifend sem eros, ut aliquam libero porttitor id. Sed non nunc consequat, rhoncus diam eu, commodo erat. Praesent fermentum in lectus id blandit. Donec quis ipsum at justo volutpat finibus. Nulla blandit justo nulla, at mollis lacus consequat eget. Aenean sollicitudin quis eros ut ullamcorper. - -Pellentesque venenatis nulla ut mi aliquet feugiat. Cras semper vel magna nec pharetra. Integer mattis felis et sapien commodo imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis quis luctus felis. Vestibulum justo nibh, aliquam non lectus vitae, molestie placerat justo. Donec lorem nibh, gravida sit amet hendrerit ac, maximus id ipsum. Nunc ac libero sodales risus eleifend sagittis. Phasellus est massa, lobortis elementum ex sed, scelerisque consectetur neque. Nunc faucibus neque id lorem malesuada, eget convallis ex mattis. - -Sed turpis tortor, fermentum non turpis id, posuere varius nibh. Donec iaculis lorem dui. Etiam eros ante, sodales eget venenatis at, consectetur eget risus. Curabitur non aliquam ante, a pretium justo. Maecenas tempor nisl tortor, vitae dictum nisi ultrices eu. Duis eget dui ultrices, porttitor lacus sed, lobortis purus. Quisque mattis elit nec neque sagittis, sed commodo leo blandit. Mauris sodales interdum eleifend. Vestibulum condimentum consectetur augue, id luctus diam convallis et. - -Nunc suscipit risus in justo accumsan, a placerat magna tincidunt. Proin a nisl ipsum. Sed libero dui, tristique in augue quis, auctor tristique risus. Sed porttitor ex augue, eu porta augue molestie a. Duis rhoncus purus libero, eu tempus turpis condimentum at. Sed mollis nisi id lectus placerat tincidunt. Maecenas non scelerisque elit, quis rutrum orci. Donec in tellus pharetra urna ornare lobortis. Phasellus id risus at nisi varius rutrum eu ut turpis. - -Duis dictum justo quis nisl porta, eget tincidunt magna suscipit. Sed velit massa, ullamcorper eu sodales ac, pretium a massa. Duis et rutrum tortor. Nulla accumsan hendrerit sapien, cursus volutpat eros egestas eget. Donec sollicitudin at ante quis sollicitudin. Aenean blandit feugiat diam, id feugiat eros faucibus eget. Donec viverra dolor vel justo scelerisque dignissim. Nulla semper sem nunc, rhoncus semper tellus ultricies sed. Duis in ornare diam. Donec vehicula feugiat varius. Maecenas ut suscipit est. Vivamus sem sem, finibus at dolor sit amet, euismod dapibus ligula. Vestibulum fringilla odio dapibus, congue massa eget, congue sem. Donec feugiat magna eget tortor lacinia scelerisque non et ipsum. - -Suspendisse potenti. Nunc convallis sollicitudin ex eget venenatis. Sed iaculis nibh ex, vel ornare ligula congue dignissim. Quisque sollicitudin dolor ac dui vestibulum, sit amet molestie nisi aliquet. Donec at risus felis. Aenean sollicitudin metus a feugiat porta. Aenean a tortor ut dolor cursus sagittis. Vivamus consectetur porttitor nunc in facilisis. Proin sit amet mi vel lectus consectetur ultrices. - -Sed cursus lectus vitae nunc tristique, nec commodo turpis dapibus. Pellentesque luctus ex id facilisis ornare. Morbi quis placerat dolor. Donec in lectus in arcu mattis porttitor ac sit amet metus. Cras congue mauris non risus sodales, vitae feugiat ipsum bibendum. Nulla venenatis urna sed libero elementum, a cursus lorem commodo. Mauris faucibus lobortis eros nec commodo. - -Nullam suscipit ligula ullamcorper lorem commodo blandit. Nulla porta nibh quis pulvinar placerat. Vivamus eu arcu justo. Vestibulum imperdiet est ut fermentum porttitor. Pellentesque consectetur libero in sapien efficitur scelerisque. Curabitur ac erat sit amet odio aliquet dignissim. Pellentesque mi sem, rhoncus et luctus at, porttitor rutrum lectus. Vestibulum sollicitudin sollicitudin suscipit. Aenean efficitur dolor non ultrices imperdiet. Donec vel sem ex. - -Sed convallis mauris aliquam rutrum cursus. Ut tempor porttitor sodales. Etiam eu risus ac augue gravida egestas et eu dolor. Proin id magna ex. Suspendisse quis lectus quis lorem ultricies tempus. Donec porttitor velit vitae tincidunt faucibus. Aliquam vitae semper nisi. Morbi ultrices, leo non pretium dapibus, dui libero pellentesque ex, vel placerat enim ante vitae dui. Nunc varius, sem sit amet sagittis lobortis, lectus odio scelerisque mauris, ut vestibulum orci magna quis neque. Sed id congue justo. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris congue nisi est, malesuada mollis elit tincidunt sed. Curabitur sed ex sit amet felis tristique elementum vitae vel nibh. - -Etiam mollis pretium lobortis. Mauris augue lacus, efficitur at lacus sed, mollis tincidunt lectus. Aliquam erat volutpat. Donec at euismod elit, et mattis felis. Sed id lobortis urna. Morbi imperdiet vestibulum leo, sed maximus leo blandit eu. Aliquam semper lorem neque, nec euismod turpis mattis mollis. Quisque lobortis urna ultrices odio pretium, ac venenatis orci faucibus. Suspendisse bibendum odio ligula, sed lobortis massa pharetra nec. Donec turpis justo, iaculis at dictum ac, finibus eu libero. Maecenas quis porttitor mi, sit amet aliquet neque. - -Vivamus auctor vulputate ante, at egestas lorem. Donec eu risus in nulla mollis ultricies at et urna. Duis accumsan porta egestas. Ut vel euismod augue. Fusce convallis nulla ante, nec fringilla velit aliquet at. Nam malesuada dapibus ligula, a aliquam nibh scelerisque ac. Praesent malesuada neque et pellentesque interdum. Curabitur volutpat at turpis vitae tristique. Vivamus porttitor semper congue. Quisque suscipit lacus mi, rhoncus ultrices tortor auctor quis. Maecenas neque neque, molestie ac facilisis eget, luctus ac lorem. In ut odio ut lacus suscipit pulvinar vitae sed elit. Nulla imperdiet, sem quis euismod sagittis, dui erat luctus dolor, faucibus faucibus erat sem eget nunc. Nam accumsan placerat malesuada. Maecenas convallis finibus pulvinar. - -Cras at placerat tortor. Morbi facilisis auctor felis sit amet molestie. Donec sodales sed lorem vitae suscipit. Etiam fermentum pharetra ipsum, nec luctus orci gravida eu. Pellentesque gravida, est non condimentum tempus, mauris ligula molestie est, in congue dolor nisl vel sapien. Duis congue tempor augue, id rutrum eros porta dapibus. Etiam rutrum eget est eget vestibulum. Aenean mollis arcu vel consequat varius. Praesent at condimentum felis. Duis nec interdum nisl. Donec commodo lorem sed sapien scelerisque malesuada non eu urna. In blandit non ipsum at porta. Nam lobortis leo vitae dui auctor, non feugiat quam bibendum. Donec auctor lectus sagittis laoreet maximus. Maecenas rhoncus laoreet porttitor. Vestibulum porttitor augue ut lectus hendrerit, eget posuere mi gravida. - -Sed mattis ex in erat pulvinar, eu imperdiet magna dapibus. Etiam nisi nibh, tempus non tellus sit amet, mattis tempor odio. Quisque nec lorem feugiat, lobortis odio et, commodo nunc. Maecenas semper purus nisi, nec vehicula nibh eleifend vitae. Nulla fermentum a lectus at maximus. Phasellus finibus metus non euismod ultrices. Etiam a pulvinar ante. Quisque convallis nec metus sit amet facilisis. Praesent laoreet massa et sollicitudin laoreet. Vestibulum in mauris aliquet, convallis mi ut, elementum purus. Nulla purus nulla, sodales at hendrerit quis, tempus sed lectus. - -Nam ut laoreet neque, ut maximus nibh. Maecenas quis justo pellentesque, sollicitudin elit at, venenatis velit. Aenean nunc velit, vehicula scelerisque odio at, consectetur laoreet purus. Duis dui purus, malesuada quis ipsum sit amet, tempor interdum libero. Curabitur porta scelerisque sapien, vitae cursus diam condimentum eu. Phasellus sed orci quam. Nullam vitae dui quis purus tincidunt vestibulum. Curabitur quis nulla porta, cursus arcu non, auctor enim. Etiam sollicitudin ex id sem vehicula mollis. Morbi viverra laoreet tincidunt. Praesent ut semper dui. Nam sit amet pretium neque. Mauris vitae luctus diam, in lacinia purus. Maecenas ut placerat justo, ut porta felis. Integer eu mauris ante. - -Aenean porttitor tellus diam, tempor consequat metus efficitur id. Suspendisse ut felis at erat tempor dictum at nec sapien. Sed vestibulum interdum felis, ac mattis mauris porta in. Nunc et condimentum massa. Sed cursus dictum justo et luctus. Integer convallis enim nisl, a rutrum lectus ultricies in. Donec dapibus lacus at nulla dapibus, id sollicitudin velit hendrerit. Fusce a magna at orci mollis rutrum ac a dolor. Aliquam erat volutpat. Morbi varius porta nunc, sit amet sodales ex hendrerit commodo. Donec tincidunt tortor sapien, vitae egestas sapien vehicula eget. - -Suspendisse potenti. Donec pulvinar felis nec leo malesuada interdum. Integer posuere placerat maximus. Donec nibh ipsum, tincidunt vitae luctus vitae, bibendum at leo. Sed cursus nisl ut ex faucibus aliquet sed nec eros. Curabitur molestie posuere felis. Integer faucibus velit eget consequat iaculis. Mauris sed vulputate odio. Phasellus maximus, elit a pharetra egestas, lorem magna semper tellus, vestibulum semper diam felis at sapien. Suspendisse facilisis, nisl sit amet euismod vehicula, libero nulla vehicula dolor, quis fermentum nibh elit sit amet diam. - -Morbi lorem enim, euismod eu varius ut, scelerisque quis odio. Nam tempus vitae eros id molestie. Nunc pretium in nulla eget accumsan. Quisque mattis est ut semper aliquet. Maecenas eget diam elementum, fermentum ipsum a, euismod sapien. Duis quam ligula, cursus et velit nec, ullamcorper tincidunt magna. Donec vulputate nisl est, et ullamcorper urna tempor sit amet. - -Proin lacinia dui non turpis congue pretium. Morbi posuere metus vel purus imperdiet interdum. Morbi venenatis vel eros non ultricies. Nulla vel semper elit. Ut quis purus tincidunt, auctor justo ut, faucibus turpis. Proin quis mattis erat, at faucibus ligula. Mauris in mauris enim. Donec facilisis enim at est feugiat hendrerit. Nam vel nisi lorem. Fusce ultricies convallis diam, in feugiat tortor luctus quis. Donec tempor, leo vitae volutpat aliquam, magna elit feugiat leo, quis placerat sapien felis eget arcu. Donec ornare fermentum eleifend. Integer a est orci. - -Proin rhoncus egestas leo. Nulla ultricies porta elit quis ornare. Nunc fermentum interdum vehicula. In in ligula lorem. Donec nec arcu sit amet orci lobortis iaculis. Mauris at mollis erat, sit amet mollis tortor. Mauris laoreet justo ullamcorper porttitor auctor. Aenean sit amet aliquam lectus, id fermentum eros. Praesent urna sem, vehicula ac fermentum id, dapibus ut purus. Vestibulum vitae tempus nunc. Donec at nunc ornare metus volutpat porta at eget magna. Donec varius aliquet metus, eu lobortis risus aliquam sed. Ut dapibus fermentum velit, ac tincidunt libero faucibus at. - -In in purus auctor, feugiat massa quis, facilisis nisi. Donec dolor purus, gravida eget dolor ac, porttitor imperdiet urna. Donec faucibus placerat erat, a sagittis ante finibus ac. Sed venenatis dignissim elit, in iaculis felis posuere faucibus. Praesent sed viverra dolor. Mauris sed nulla consectetur nunc laoreet molestie in ut metus. Proin ac ex sit amet magna vulputate hendrerit ac condimentum urna. Proin ligula metus, gravida et sollicitudin facilisis, iaculis ut odio. Cras tincidunt urna et augue varius, ut facilisis urna consequat. Aenean vehicula finibus quam. Ut iaculis eu diam ac mollis. Nam mi lorem, tristique eget varius at, sodales at urna. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin vitae dictum erat, et auctor ipsum. Nullam nunc nunc, sollicitudin quis magna a, vestibulum fermentum mauris. Praesent at erat dolor. Proin laoreet tristique nulla vel efficitur. Nam sed ultrices nibh, id rutrum nunc. Curabitur eleifend a erat sit amet sollicitudin. Nullam metus quam, laoreet vitae dapibus id, placerat sed leo. Aliquam erat volutpat. Donec turpis nisl, cursus eu ex sit amet, lacinia pellentesque nisl. Sed id ipsum massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec interdum scelerisque lorem eu mattis. - -Vivamus ac tristique massa, nec facilisis nisl. Nam ipsum neque, tincidunt vel urna in, cursus imperdiet enim. Nam pellentesque egestas tempus. Morbi facilisis imperdiet libero vitae fringilla. Nam lacinia ligula at sapien facilisis malesuada. Nullam accumsan pulvinar sem, et cursus libero porta sit amet. Curabitur vulputate erat elit, ut pulvinar erat maximus vel. - -Cras aliquet metus ut purus sagittis, vel venenatis ante consectetur. Pellentesque nulla lacus, viverra viverra mattis non, placerat vitae nibh. Donec enim turpis, accumsan sit amet tincidunt eu, imperdiet non metus. Morbi ipsum eros, tincidunt vel est ac, tristique porttitor nibh. Praesent ut ullamcorper mauris. Sed laoreet sit amet diam congue venenatis. Integer porta purus nec orci sagittis posuere. - -Donec vehicula mauris eget lacus mollis venenatis et sed nibh. Nam sodales ligula ipsum, scelerisque lacinia ligula sagittis in. Nam sit amet ipsum at erat malesuada congue. Aenean ut sollicitudin sapien. Etiam at tempor odio. Mauris vitae purus ut magna suscipit consequat. Vivamus quis sapien neque. Nulla vulputate sem sit amet massa pellentesque, eleifend tristique ligula egestas. Suspendisse tincidunt gravida mi, in pulvinar lectus egestas non. Aenean imperdiet ex sit amet nunc sollicitudin porta. Integer justo odio, ultricies at interdum in, rhoncus vitae sem. Sed porttitor arcu quis purus aliquet hendrerit. Praesent tempor tortor at dolor dictum pulvinar. Nulla aliquet nunc non ligula scelerisque accumsan. Donec nulla justo, congue vitae massa in, faucibus hendrerit magna. Donec non egestas purus. - -Vivamus iaculis, lacus efficitur faucibus porta, dui nulla facilisis ligula, ut sodales odio nunc id sapien. Cras viverra auctor ipsum, dapibus mattis neque dictum sed. Sed convallis fermentum molestie. Nulla facilisi turpis duis. \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_big5.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_big5.txt deleted file mode 100644 index 91b79941f16..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_big5.txt +++ /dev/null @@ -1,283 +0,0 @@ -¤¤¤åabc Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vulputate, ipsum quis interdum fermentum, lorem sem fermentum eros, vitae auctor neque lacus in nisi. Suspendisse potenti. Maecenas et scelerisque elit, in tincidunt quam. Sed eu tincidunt quam. Nullam justo ex, imperdiet a imperdiet et, fermentum sit amet eros. Aenean quis tempus sem. Pellentesque accumsan magna mi, ut mollis velit sagittis id. Etiam quis ipsum orci. Fusce purus ante, accumsan a lobortis at, venenatis eu nisl. Praesent ornare sed ante placerat accumsan. Suspendisse tempus dignissim fermentum. Nunc a leo ac lacus sodales iaculis eu vitae mi. In feugiat ante at massa finibus cursus. Suspendisse posuere fringilla ornare. Mauris elementum ac quam id convallis. Vestibulum non elit quis urna volutpat aliquam a eu lacus. - -Aliquam vestibulum imperdiet neque, suscipit aliquam elit ultrices bibendum. Suspendisse ultrices pulvinar cursus. Morbi risus nisi, cursus consequat rutrum vitae, molestie sed dui. Fusce posuere, augue quis dignissim aliquam, nisi ipsum porttitor ante, quis fringilla nisl turpis ac nisi. Nulla varius enim eget lorem vehicula gravida. Donec finibus malesuada leo nec semper. Proin ac enim eros. Vivamus non tincidunt nisi, vel tristique lorem. - -Nunc consequat ex id eros dignissim, id rutrum risus laoreet. Sed euismod non erat eu ultricies. Etiam vehicula gravida lacus ut porta. Vestibulum eu eros quis nunc aliquet luctus. Cras quis semper ligula. Nullam gravida vehicula quam sed porta. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In porta cursus vulputate. Quisque porta a nisi eget cursus. Aliquam risus leo, luctus ac magna in, efficitur cursus magna. In condimentum non mi id semper. Donec interdum ante eget commodo maximus. - -Vivamus sit amet vestibulum lectus. Fusce tincidunt mi sapien, dictum sollicitudin diam vulputate in. Integer fringilla consequat mollis. Cras aliquet consequat felis eget feugiat. Nunc tempor cursus arcu, vitae ornare nunc varius et. Vestibulum et tortor vel ante viverra porttitor. Nam at tortor ullamcorper, facilisis augue quis, tristique erat. Aenean ut euismod nibh. Quisque eu tincidunt est, nec euismod eros. - -Proin vehicula nibh non viverra egestas. Phasellus sem dolor, ultricies ac sagittis tristique, lacinia a purus. Vestibulum in ante eros. Pellentesque lacus nulla, tristique vitae interdum vel, malesuada ac diam. Aenean bibendum posuere turpis in accumsan. Ut est nulla, ullamcorper quis turpis at, viverra sagittis mauris. Sed in interdum purus. Praesent scelerisque nibh eget sem euismod, ut imperdiet mi venenatis. Vivamus pulvinar orci sed dapibus auctor. Nulla facilisi. Vestibulum tincidunt erat nec porttitor egestas. Mauris quis risus ante. Nulla facilisi. - -Aliquam ullamcorper ornare lobortis. Phasellus quis sem et ipsum mollis malesuada sed in ex. Ut aliquam ex eget metus finibus maximus. Proin suscipit mauris eu nibh lacinia, quis feugiat dui dapibus. Nam sed libero est. Aenean vulputate orci sit amet diam faucibus, eu sagittis sapien volutpat. Nam imperdiet felis turpis, at pretium odio pulvinar in. Sed vestibulum id eros nec ultricies. Sed quis aliquam tortor, vitae ullamcorper tellus. Donec egestas laoreet eros, id suscipit est rutrum nec. Sed auctor nulla eget metus aliquam, ut condimentum enim elementum. - -Aliquam suscipit non turpis sit amet bibendum. Fusce velit ligula, euismod et maximus at, luctus sed neque. Quisque pretium, nisl at ullamcorper finibus, lectus leo mattis sapien, vel euismod mauris diam ullamcorper ex. Nulla ut risus finibus, lacinia ligula at, auctor erat. Mauris consectetur sagittis ligula vel dapibus. Nullam libero libero, lobortis aliquam libero vel, venenatis ultricies leo. Duis porttitor, nibh congue fermentum posuere, erat libero pulvinar tortor, a pellentesque nunc ipsum vel sem. Nullam volutpat, eros sit amet facilisis consectetur, ipsum est vehicula massa, non vestibulum neque elit in mauris. Nunc hendrerit ipsum non enim bibendum, vitae rhoncus mi egestas. Etiam ullamcorper massa vel nisl sagittis, nec bibendum arcu malesuada. Aenean aliquet turpis justo, a consectetur arcu mollis convallis. Etiam tellus ipsum, ultricies vitae lorem et, ornare facilisis orci. Praesent fringilla justo urna, vel mollis neque pulvinar vestibulum. - -Donec non iaculis erat. Aliquam et mi sed nunc pulvinar ultricies in ut ipsum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent feugiat lacus ac dignissim semper. Phasellus vitae quam nisi. Morbi vel diam ultricies risus lobortis ornare. Fusce maximus et ligula quis iaculis. Sed congue ex eget felis convallis, sit amet hendrerit elit tempor. Donec vehicula blandit ante eget commodo. Vestibulum eleifend diam at feugiat euismod. Etiam magna tellus, dignissim eget fermentum vel, vestibulum vitae mauris. Nam accumsan et erat id sagittis. Donec lacinia, odio ut ornare ultricies, dolor velit accumsan tortor, non finibus erat tellus quis ligula. Nunc quis metus in leo volutpat ornare vulputate eu nisl. - -Donec quis viverra ex. Nullam id feugiat mauris, eu fringilla nulla. Vestibulum id maximus elit. Cras elementum elit sed felis lobortis, eget sagittis nisi hendrerit. Vivamus vitae elit neque. Donec vulputate lacus ut libero ultrices accumsan. Vivamus accumsan nulla orci, in dignissim est laoreet sagittis. Proin at commodo velit. Curabitur in velit felis. Aliquam erat volutpat. Sed consequat, nulla et cursus sodales, nisi lacus mattis risus, quis eleifend erat ex nec turpis. Sed suscipit ultrices lorem in hendrerit. - -Morbi vitae lacus nec libero ornare tempus eu et diam. Suspendisse magna ipsum, fermentum vel odio quis, molestie aliquam urna. Fusce mollis turpis a eros accumsan porttitor. Pellentesque rhoncus dolor sit amet magna rutrum, et dapibus justo tempor. Sed purus nisi, maximus vitae fringilla eu, molestie nec urna. Fusce malesuada finibus pretium. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec sed aliquet eros. Pellentesque luctus diam ante, eget euismod nisl aliquet eu. Sed accumsan elit purus, tempor varius ligula tempus nec. Curabitur ornare leo suscipit suscipit fermentum. Morbi eget nulla est. Maecenas faucibus interdum tristique. - -Etiam ut elit eros. Nulla pharetra suscipit molestie. Nulla facilisis bibendum nisl non molestie. Curabitur turpis lectus, facilisis vel diam non, vulputate ultrices mauris. Aenean placerat aliquam convallis. Suspendisse sed scelerisque tellus. Vivamus lacinia neque eget risus cursus suscipit. Proin consequat dolor vel neque tempor, eu aliquam sem scelerisque. Duis non eros a purus malesuada pharetra non et nulla. Suspendisse potenti. Mauris libero eros, finibus vel nulla id, sagittis dapibus ante. Proin iaculis sed nunc et cursus. - -Quisque accumsan lorem sit amet lorem aliquet euismod. Curabitur fermentum rutrum posuere. Etiam ultricies, sem id pellentesque suscipit, urna magna lacinia eros, quis efficitur risus nisl at lacus. Nulla quis lacus tortor. Mauris placerat ex in dolor tincidunt, vel aliquet nisi pretium. Cras iaculis risus vitae pellentesque aliquet. Quisque a enim imperdiet, ullamcorper arcu vitae, rutrum risus. Nullam consectetur libero at felis fringilla, nec congue nibh dignissim. Nam et lobortis felis, eu pellentesque ligula. Aenean facilisis, ligula non imperdiet maximus, massa orci gravida sapien, at sagittis lacus nisl in lacus. Nulla quis mauris luctus, scelerisque felis consequat, tempus risus. Fusce auctor nisl non nulla luctus molestie. Maecenas sapien nisl, auctor non dolor et, iaculis scelerisque lorem. Suspendisse egestas enim aliquet, accumsan mauris nec, posuere quam. Nulla iaculis dui dui, sit amet vestibulum erat ultricies ac. - -Cras eget dolor erat. Proin at nisl ut leo consectetur ultricies vel ut arcu. Nulla in felis malesuada, ullamcorper tortor et, convallis massa. Nunc urna justo, ornare in nibh vitae, hendrerit condimentum libero. Etiam vitae libero in purus venenatis fringilla. Nullam velit nulla, consequat ut turpis non, egestas hendrerit nibh. Duis tortor turpis, interdum non ante ac, cursus accumsan lectus. Cras pharetra bibendum augue quis dictum. Sed euismod vestibulum justo. Proin porta lobortis purus. Duis venenatis diam tortor, sit amet condimentum eros rhoncus a. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc at magna nec diam lobortis efficitur sit amet ut lacus. Nulla quis orci tortor. Pellentesque tempus velit a odio finibus porta. - -Proin feugiat mauris a tellus scelerisque convallis. Maecenas libero magna, blandit nec ultrices id, congue vel mi. Aliquam lacinia, quam vel condimentum convallis, tortor turpis aliquam odio, sed blandit libero lacus et eros. In eleifend iaculis magna ac finibus. Praesent auctor facilisis tellus in congue. Sed molestie lobortis dictum. Nam quis dignissim augue, vel euismod lorem. Curabitur posuere dapibus luctus. Donec ultricies dictum lectus, quis blandit arcu commodo ac. Aenean tincidunt ligula in nunc imperdiet dignissim. Curabitur egestas sollicitudin sapien ut semper. Aenean nec dignissim lacus. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec aliquam dictum vehicula. Donec tortor est, volutpat non nisi nec, varius gravida ex. Nunc vel tristique nunc, vitae mattis nisi. Nunc nec luctus ex, vitae tincidunt lectus. In hac habitasse platea dictumst. Curabitur lobortis ex eget tincidunt tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut a vehicula mi. - -Fusce eu libero finibus, interdum nulla a, placerat neque. Cras bibendum tempor libero nec feugiat. Cras ut sodales eros. Proin viverra, massa sit amet viverra egestas, neque nisl porta ex, sit amet hendrerit libero ligula vel urna. Mauris suscipit lacus id justo rhoncus suscipit. Etiam vel libero tellus. Maecenas non diam molestie, condimentum tellus a, bibendum enim. Mauris aliquet imperdiet tellus, eget sagittis dolor. Sed blandit in neque et luctus. Cras elementum sagittis nunc, vel mollis lorem euismod et. Donec posuere at lacus eget suscipit. - -Nulla nunc mi, pretium non massa vel, tempor semper magna. Nunc a leo pulvinar, tincidunt nunc at, dignissim mi. Aliquam erat volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut viverra nulla a nisl finibus, at hendrerit ligula ullamcorper. Donec a lorem semper, tempor magna et, lobortis libero. Mauris id sapien leo. Donec dignissim, quam vitae porttitor dignissim, quam justo mattis dui, vel consequat odio elit quis orci. Etiam nec pretium neque, sit amet pretium orci. Duis ac tortor venenatis, feugiat purus non, feugiat nunc. Proin scelerisque nisl in turpis aliquam vulputate. - -Praesent sed est semper, fringilla lorem vitae, tincidunt nibh. Cras eros metus, auctor at mauris sit amet, sodales semper orci. Nunc a ornare ex. Curabitur bibendum arcu congue urna vulputate egestas. Vestibulum finibus id risus et accumsan. Aenean ut volutpat tellus. Aenean tincidunt malesuada urna sit amet vestibulum. Mauris vel tellus dictum, varius lacus quis, dictum arcu. - -Aenean quis metus eu erat feugiat cursus vel at ligula. Proin dapibus sodales urna, id euismod lectus tempus id. Pellentesque ex ligula, convallis et erat vel, vulputate condimentum nisl. Pellentesque pharetra nulla quis massa eleifend hendrerit. Praesent sed massa ipsum. Maecenas vehicula dolor massa, id sodales urna faucibus et. Mauris ac quam non massa tincidunt feugiat et at lacus. Fusce libero massa, vulputate vel scelerisque non, mollis in leo. Ut sit amet ultricies odio. Suspendisse in sapien viverra, facilisis purus ut, pretium libero. - -Vivamus tristique pharetra molestie. Nam a volutpat purus. Praesent consequat gravida nisi, ac blandit nisi suscipit ut. Quisque posuere, ligula a ultrices laoreet, ligula nunc vulputate libero, ut rutrum erat odio tincidunt justo. Sed vitae leo at leo fringilla bibendum. Vestibulum ut augue nec dolor auctor accumsan. Praesent laoreet id eros pulvinar commodo. Suspendisse potenti. Ut pharetra, mauris vitae blandit fringilla, odio ante tincidunt lorem, sit amet tempor metus diam ut turpis. - -Praesent quis egestas arcu. Nullam at porta arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi vulputate ligula malesuada ligula luctus, vulputate tempus erat bibendum. Nunc ullamcorper non lectus at euismod. Etiam nibh felis, tincidunt a metus vel, pellentesque rhoncus neque. Etiam at diam in erat luctus interdum. Nunc vel ipsum pulvinar, sollicitudin lacus ac, tempus urna. Etiam vel lacinia sapien. Pellentesque sagittis velit vel mi efficitur iaculis. Integer euismod sit amet urna in sagittis. Cras eleifend ut nibh in facilisis. Donec et lacus vitae nunc placerat sodales. Nulla sed hendrerit ligula, at dapibus sapien. - -Praesent at iaculis ex. Curabitur est purus, cursus a faucibus quis, dictum id velit. Donec dignissim fringilla viverra. Nunc mauris felis, laoreet sit amet sagittis at, vestibulum in libero. Maecenas quis orci turpis. Quisque ut nibh vitae magna mollis consequat id at mauris. Aliquam eu odio eget nulla bibendum sodales. Quisque vel orci eleifend nisi pretium lacinia. Suspendisse eget risus eget mi volutpat molestie eget quis lacus. Duis nisi libero, tincidunt nec nulla id, faucibus cursus felis. - -Donec tempor eget risus pellentesque molestie. Phasellus porta neque vel arcu egestas, nec blandit velit fringilla. Nullam porta faucibus justo vitae laoreet. Pellentesque viverra id nunc eu varius. Nulla pulvinar lobortis iaculis. Etiam vestibulum odio nec velit tristique, a tristique nisi mattis. In sed fringilla orci, vitae efficitur odio. Quisque dui odio, ornare eget velit at, lacinia consequat libero. Quisque lectus nulla, aliquet eu leo in, porta rutrum diam. Donec nec mattis neque. Nam rutrum, odio ac eleifend bibendum, dolor arcu rutrum neque, eget porta elit tellus a lacus. Sed massa metus, sollicitudin et sapien eu, finibus tempus orci. Proin et sapien sit amet erat molestie interdum. In quis rutrum velit, faucibus ultrices tellus. - -Sed sagittis sed justo eget tincidunt. Maecenas ut leo sagittis, feugiat magna et, viverra velit. Maecenas ex arcu, feugiat at consequat vitae, auctor eu massa. Integer egestas, enim vitae maximus convallis, est lectus pretium mauris, ac posuere lectus nisl quis quam. Aliquam tempus laoreet mi, vitae dapibus dolor varius dapibus. Suspendisse potenti. Donec sit amet purus nec libero dapibus tristique. Pellentesque viverra bibendum ligula. Donec sed felis et ex lobortis laoreet. Phasellus a fringilla libero, vitae malesuada nulla. Pellentesque blandit mattis lacus, et blandit tortor laoreet consequat. Suspendisse libero nunc, viverra sed fermentum in, accumsan egestas arcu. Proin in placerat elit. Sed interdum imperdiet malesuada. Suspendisse aliquet quis mauris eget sollicitudin. - -Vivamus accumsan tellus non erat volutpat, quis dictum dolor feugiat. Praesent rutrum nunc ac est mollis cursus. Fusce semper volutpat dui ut egestas. Curabitur sit amet posuere massa. Cras tincidunt nulla et mi mollis imperdiet. Suspendisse scelerisque ex id sodales vulputate. In nunc augue, pharetra in placerat eu, mattis id tellus. Vivamus cursus efficitur vehicula. Nulla aliquet vehicula aliquet. - -Sed cursus tellus sed porta pulvinar. Sed vitae nisi neque. Nullam aliquet, lorem et efficitur scelerisque, arcu diam aliquam felis, sed pulvinar lorem odio et turpis. Praesent convallis pulvinar turpis eu iaculis. Aliquam nec gravida mi. Curabitur eu nibh tempor, blandit justo in, ultrices felis. Fusce placerat metus non mi sagittis rutrum. Morbi sed dui fringilla, sagittis mauris eget, imperdiet nunc. Phasellus hendrerit sem elit, id hendrerit libero auctor sit amet. Integer sodales elit sit amet consequat cursus. - -Nam semper est eget nunc mollis, in pellentesque lectus fringilla. In finibus vel diam id semper. Nunc mattis quis erat eu consectetur. In hac habitasse platea dictumst. Nullam et ipsum vestibulum ex pulvinar ultricies sit amet id velit. Aenean suscipit mi tortor, a lobortis magna viverra non. Nulla condimentum aliquet ante et ullamcorper. Pellentesque porttitor arcu a posuere tempus. Aenean lacus quam, imperdiet eu justo vitae, pretium efficitur ex. Duis id purus id magna rhoncus ultrices id eu risus. Nunc dignissim et libero id dictum. - -Quisque a tincidunt neque. Phasellus commodo mi sit amet tempor fringilla. Ut rhoncus, neque non porttitor elementum, libero nulla egestas augue, sed fringilla sapien felis ac velit. Phasellus viverra rhoncus mollis. Nam ullamcorper leo vel erat laoreet luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus semper a metus a cursus. Nulla sed orci egestas, efficitur purus ac, malesuada tellus. Aenean rutrum velit at tellus fermentum mollis. Aliquam eleifend euismod metus. - -In hac habitasse platea dictumst. Vestibulum volutpat neque vitae porttitor laoreet. Nam at tellus consequat, sodales quam in, pulvinar arcu. Maecenas varius convallis diam, ac lobortis tellus pellentesque quis. Maecenas eget augue massa. Nullam volutpat nibh ac justo rhoncus, ut iaculis tellus rutrum. Fusce efficitur efficitur libero quis condimentum. Curabitur congue neque non tincidunt tristique. Fusce eget tempor ex, at pellentesque odio. Praesent luctus dictum vestibulum. Etiam non orci nunc. Vivamus vitae laoreet purus, a lobortis velit. Curabitur tincidunt purus ac lectus elementum pellentesque. Quisque sed tincidunt est. - -Sed vel ultrices massa, vitae ultricies justo. Cras finibus mauris nec lacus tempus dignissim. Cras faucibus maximus velit, eget faucibus orci luctus vehicula. Nulla massa nunc, porta ac consequat eget, rhoncus non tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce sed maximus metus, vel imperdiet ipsum. Ut scelerisque lectus at blandit porttitor. Ut vulputate nunc pharetra, aliquet sapien ac, sollicitudin sapien. Aenean eget ante lorem. Nam accumsan venenatis tellus id dignissim. - -Curabitur fringilla, magna non maximus dapibus, nulla sapien vestibulum lectus, sit amet semper dolor neque vitae nisl. Nunc ultrices vehicula augue sed iaculis. Maecenas nec diam mollis, suscipit orci et, vestibulum ante. Pellentesque eu nisl tortor. Nunc eleifend, lacus quis volutpat volutpat, nisi mi molestie sem, quis mollis ipsum libero a tellus. Ut viverra dolor mattis convallis interdum. Sed tempus nisl at nunc scelerisque aliquet. Quisque tempor tempor lorem id feugiat. Nullam blandit lectus velit, vitae porta lacus tincidunt a. Vivamus sit amet arcu ultrices, tincidunt mi quis, viverra quam. Aenean fringilla libero elementum lorem semper, quis pulvinar eros gravida. Nullam sodales blandit mauris, sed fermentum velit fermentum sit amet. Donec malesuada mauris in augue sodales vulputate. Vestibulum gravida turpis id elit rhoncus dignissim. Integer non congue lorem, eu viverra orci. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec at dolor magna. Aliquam consectetur erat augue, id iaculis velit pharetra ac. Integer rutrum venenatis dignissim. Integer non sodales elit. Curabitur ut magna ut nibh feugiat aliquam ac ut risus. Morbi nibh quam, aliquam id placerat nec, vestibulum eget velit. Suspendisse at dignissim quam. Vivamus aliquet sem sed nisl volutpat, ut cursus orci ultrices. Aliquam ultrices lacinia enim, vitae aliquet neque. - -Quisque scelerisque finibus diam in mattis. Cras cursus auctor velit. Aliquam sem leo, fermentum et maximus et, molestie a libero. Aenean justo elit, rutrum a ornare id, egestas eget enim. Aenean auctor tristique erat. Curabitur condimentum libero lacus, nec consequat orci vestibulum sed. Fusce elit ligula, blandit vitae sapien vitae, dictum ultrices risus. Nam laoreet suscipit sapien, at interdum velit faucibus sit amet. Duis quis metus egestas lectus elementum posuere non nec libero. Aliquam a dolor bibendum, facilisis nunc a, maximus diam. Vestibulum suscipit tristique magna, non dignissim turpis sodales sed. Nunc ornare, velit ac facilisis fringilla, dolor mi consectetur lorem, vitae finibus erat justo suscipit urna. Maecenas sit amet eros erat. Nunc non arcu ornare, suscipit lorem eget, sodales mauris. Aliquam tincidunt, quam nec mollis lacinia, nisi orci fermentum libero, consequat eleifend lectus quam et sapien. Vestibulum a quam urna. - -Cras arcu leo, euismod ac ullamcorper at, faucibus sed massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus porttitor velit in enim interdum, non commodo metus ornare. Morbi vel lorem quis nisl luctus tristique quis vitae nisl. Suspendisse condimentum tortor enim, nec eleifend ipsum euismod et. Sed gravida quam ut tristique lacinia. Mauris eu interdum ipsum, ac ultrices odio. Nullam auctor tellus a risus porttitor vehicula. Nulla blandit euismod dictum. In pharetra, enim iaculis pulvinar interdum, dui nunc placerat nunc, sit amet pretium lectus nulla vitae quam. Phasellus quis enim sollicitudin, varius nulla id, ornare purus. Donec quam lacus, vestibulum quis nunc ac, mollis dictum nisi. Cras ut mollis elit. Maecenas ultrices ligula at risus faucibus scelerisque. Etiam vitae porttitor purus. Curabitur blandit lectus urna, ut hendrerit tortor feugiat ut. - -Phasellus fringilla, sapien pellentesque commodo pharetra, ante libero aliquam tellus, ut consectetur augue libero a sapien. Maecenas blandit luctus nisl eget aliquet. Maecenas vitae porta dolor, faucibus laoreet sapien. Suspendisse lobortis, ipsum sed vehicula aliquam, elit purus scelerisque dui, rutrum consectetur diam odio et lorem. In nec lacinia metus. Donec viverra libero est, vel bibendum erat condimentum quis. Donec feugiat purus leo. In laoreet vitae felis a porttitor. Mauris ullamcorper, lacus id condimentum suscipit, neque magna pellentesque arcu, eget cursus neque tellus id metus. Curabitur volutpat ac orci vel ultricies. - -Sed ut finibus erat. Sed diam purus, varius non tincidunt quis, ultrices sit amet ipsum. Donec et egestas nulla. Suspendisse placerat nisi at dui laoreet iaculis. Aliquam aliquet leo at augue faucibus molestie. Nullam lacus augue, hendrerit sed nisi eu, faucibus porta est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam ut leo aliquet sem fermentum rutrum quis ac justo. Integer placerat aliquam nisl ut sagittis. Proin erat orci, lobortis et sem eget, eleifend fringilla augue. Mauris varius laoreet arcu, sed tincidunt felis. Pellentesque venenatis lorem odio, id pulvinar velit molestie feugiat. Donec mattis lacus sed eleifend pulvinar. - -Sed condimentum ex in tincidunt hendrerit. Etiam eget risus lacinia, euismod nibh eu, pellentesque quam. Proin elit eros, convallis id mauris ac, bibendum ultrices lectus. Morbi venenatis, purus id fermentum consequat, nunc libero tincidunt ligula, non dictum ligula orci nec quam. Nulla nec ultrices lorem. Aenean maximus augue vel dictum pharetra. Etiam turpis urna, pellentesque quis malesuada eu, molestie faucibus felis. - -Vestibulum pharetra augue ut quam blandit congue in nec risus. Proin eu nibh eu dui eleifend porta vitae id lectus. Proin lacus nibh, lobortis sed ligula vitae, interdum lobortis erat. Suspendisse potenti. In sollicitudin quis sapien ut aliquet. Mauris ac nulla arcu. Fusce tristique justo quis lectus mollis, eu volutpat lectus finibus. Vivamus venenatis facilisis ex ut vestibulum. - -Etiam varius lobortis purus, in hendrerit elit tristique at. In tempus, augue vestibulum fermentum gravida, ligula tellus vulputate arcu, eu molestie ex sapien at purus. Vestibulum nec egestas metus. Duis pulvinar quam nec consequat interdum. Aenean non dapibus lacus. Aliquam sit amet aliquet nulla. Sed venenatis volutpat purus nec convallis. Phasellus aliquet semper sodales. Cras risus sapien, condimentum auctor urna a, pulvinar ornare nisl. Sed tincidunt felis elit, ut elementum est bibendum ac. Morbi interdum justo vel dui faucibus condimentum. - -Sed convallis eu sem at tincidunt. Nullam at auctor est, et ullamcorper ipsum. Pellentesque eget ante ante. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer euismod, sapien sed dapibus ornare, nibh enim maximus lacus, lacinia placerat urna quam quis felis. Morbi accumsan id nisl ut condimentum. Donec bibendum nisi est, sed volutpat lorem rhoncus in. Vestibulum ac lacinia nunc, eget volutpat magna. Integer aliquam pharetra ipsum, id placerat nunc volutpat quis. Etiam urna diam, rhoncus sit amet varius vel, euismod vel sem. Nullam vel molestie urna. Vivamus ornare erat at venenatis euismod. Suspendisse potenti. Fusce diam justo, tincidunt vel sem at, commodo faucibus nisl. Duis gravida efficitur diam, vel sagittis erat pulvinar ut. - -Quisque vel pharetra felis. Duis efficitur tortor dolor, vitae porttitor erat fermentum sed. Sed eu mi purus. Etiam dignissim tortor eu tempus molestie. Aenean pretium erat enim, in hendrerit ante hendrerit at. Sed ut risus vel nunc venenatis ultricies quis in lacus. Pellentesque vitae purus euismod, placerat risus non, ullamcorper augue. Quisque varius quam ligula, nec aliquet ex faucibus vitae. Quisque rhoncus sit amet leo tincidunt mattis. Cras id mauris eget purus pretium gravida sit amet eu augue. Aliquam dapibus odio augue, id lacinia velit pulvinar eu. - -Mauris fringilla, tellus nec pharetra iaculis, neque nisi ultrices massa, et tincidunt sem dui sed mi. Curabitur erat lorem, venenatis quis tempus lacinia, tempus sit amet nunc. Aliquam at neque ac metus commodo dictum quis vitae justo. Phasellus eget lacus tempus, blandit lorem vel, rutrum est. Aenean pharetra sem ut augue lobortis dignissim. Sed rhoncus at nulla id ultrices. Cras id condimentum felis. In suscipit luctus vulputate. Donec tincidunt lacus nec enim tincidunt sollicitudin ut quis enim. Nam at libero urna. Praesent sit amet massa vitae massa ullamcorper vehicula. - -Nullam bibendum augue ut turpis condimentum bibendum. Proin sit amet urna hendrerit, sodales tortor a, lobortis lectus. Integer sagittis velit turpis, et tincidunt nisi commodo eget. Duis tincidunt elit finibus accumsan cursus. Aenean dignissim scelerisque felis vel lacinia. Nunc lacinia maximus luctus. In hac habitasse platea dictumst. Vestibulum eget urna et enim tempor tempor. Nam feugiat, felis vel vestibulum tempus, orci justo viverra diam, id dapibus lorem justo in ligula. - -Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In ac pellentesque sem. Vestibulum lacinia magna dui, eu lacinia augue placerat et. Maecenas pulvinar congue est. Pellentesque commodo dui non pulvinar scelerisque. Etiam interdum est posuere sem bibendum, ac commodo magna dictum. Cras ipsum turpis, rhoncus nec posuere vitae, laoreet a arcu. Integer ac massa sit amet enim placerat lacinia sed ultrices arcu. Suspendisse sem nibh, luctus sit amet volutpat in, pellentesque eu metus. Ut gravida neque eget mi accumsan tempus. Nam sit amet aliquet nibh. - -Pellentesque a purus cursus nulla hendrerit congue quis et odio. Aenean hendrerit, leo ullamcorper sagittis hendrerit, erat dui molestie quam, sed condimentum lacus risus sed tellus. Morbi a dapibus lectus, ut feugiat ex. Phasellus pretium quam et sapien mollis, vel iaculis dui dignissim. Sed ullamcorper est turpis, a viverra lorem consectetur in. Aenean aliquet nibh non cursus rutrum. Suspendisse at tristique urna, id lobortis urna. In hac habitasse platea dictumst. Phasellus libero velit, rutrum sed tellus nec, dapibus tincidunt ligula. Quisque vel dui venenatis, consequat nisl ut, lacinia ipsum. Phasellus vitae magna pellentesque, lobortis est id, faucibus quam. Nam eleifend faucibus dui vel pellentesque. - -Etiam ut est non lacus tincidunt interdum. Maecenas sed massa urna. Quisque ut nibh tortor. Pellentesque felis ipsum, tempor finibus ipsum et, euismod pretium metus. Donec sit amet est ipsum. Quisque rhoncus justo non finibus elementum. Nulla nec lectus ac tortor placerat fringilla. Phasellus ac ultrices nunc, eu efficitur nisl. Nulla rhoncus nunc vitae ante dictum tincidunt. Nunc ultrices, massa sit amet malesuada dignissim, lectus lacus consequat sapien, non eleifend metus sem in eros. Phasellus mauris ante, dictum sit amet suscipit ac, rhoncus eget nisi. Phasellus at orci mollis, imperdiet neque eget, faucibus nulla. In at purus massa. Pellentesque quis rutrum lectus. - -Integer eu faucibus turpis, sit amet mollis massa. Vestibulum id nulla commodo, rutrum ipsum sed, semper ante. Phasellus condimentum orci nec nibh convallis, ac maximus orci ullamcorper. Maecenas vitae sollicitudin mi. Integer et finibus lectus, et condimentum ligula. Donec elementum tristique quam vitae dapibus. Morbi euismod ipsum in tristique ullamcorper. - -Duis fermentum non enim eu auctor. Quisque lacinia nibh vehicula nibh posuere, eu volutpat turpis facilisis. Ut ac faucibus nulla. Sed eleifend quis ex et pellentesque. Vestibulum sollicitudin in libero id fringilla. Phasellus dignissim purus consequat, condimentum dui sit amet, condimentum ante. Pellentesque ac consectetur massa, quis sagittis est. Nulla maximus tristique risus accumsan convallis. Curabitur imperdiet ac lacus a ultrices. Nulla facilisi. Sed quis quam quis lectus placerat lobortis vel sed turpis. In mollis dui id neque iaculis, ut aliquet tellus malesuada. Proin at luctus odio, vel blandit sapien. Praesent dignissim tortor vehicula libero fringilla, nec ultrices erat suscipit. Maecenas scelerisque purus in dapibus fermentum. - -Curabitur magna odio, mattis in tortor ut, porttitor congue est. Vestibulum mollis lacinia elementum. Fusce maximus erat vitae nunc rutrum lobortis. Integer ligula eros, auctor vel elit non, posuere luctus lacus. Maecenas quis auctor massa. Ut ipsum lacus, efficitur posuere euismod et, hendrerit efficitur est. Phasellus fringilla, quam id tincidunt pretium, nunc dui sollicitudin orci, eu dignissim nisi metus ut magna. Integer lobortis interdum dolor, non bibendum purus posuere et. Donec non lectus aliquet, pretium dolor eu, cursus massa. Sed ut dui sapien. In sed vestibulum massa. Pellentesque blandit, dui non sodales vehicula, orci metus mollis nunc, non pharetra ex tellus ac est. Mauris sagittis metus et fermentum pretium. Nulla facilisi. Quisque quis ante ut nulla placerat mattis ut quis nisi. - -Sed quis nulla ligula. Quisque dignissim ligula urna, sed aliquam purus semper at. Suspendisse potenti. Nunc massa lectus, pharetra vehicula arcu bibendum, imperdiet sodales ipsum. Nam ac sapien diam. Mauris iaculis fringilla mattis. Pellentesque tempus eros sit amet justo volutpat mollis. Phasellus ac turpis ipsum. Morbi vel ante elit. Aenean posuere quam consequat velit varius suscipit. Donec tempor quam ut nibh cursus efficitur. - -Morbi molestie dolor nec sem egestas suscipit. Etiam placerat pharetra lectus, et ullamcorper risus tristique in. Sed faucibus ullamcorper lectus eget fringilla. Maecenas malesuada hendrerit congue. Sed eget neque a erat placerat tincidunt. Aliquam vitae dignissim turpis. Fusce at placerat magna, a laoreet lectus. Maecenas a purus nec diam gravida fringilla. Nam malesuada euismod ante non vehicula. In faucibus bibendum leo, faucibus posuere nisl pretium quis. Fusce finibus bibendum finibus. Vestibulum eu justo maximus, hendrerit diam nec, dignissim sapien. Aenean dolor lacus, malesuada quis vestibulum ac, venenatis ac ipsum. Cras a est id nunc finibus facilisis. Cras lacinia neque et interdum vehicula. Suspendisse vulputate tellus elit, eget tempor dui finibus vel. - -Cras sed pretium odio. Proin hendrerit elementum felis in tincidunt. Nam sed turpis vel justo molestie accumsan condimentum eu nunc. Praesent lobortis euismod rhoncus. Nulla vitae euismod nibh, quis mattis mi. Fusce ultrices placerat porttitor. Duis sem ipsum, pellentesque sit amet odio a, molestie vulputate mauris. - -Duis blandit mollis ligula, sit amet mattis ligula finibus sit amet. Nunc a leo molestie, placerat diam et, vestibulum leo. Suspendisse facilisis neque purus, nec pellentesque ligula fermentum nec. Aenean malesuada mauris lorem, eu blandit arcu pulvinar quis. Duis laoreet urna lacus, non maximus arcu rutrum ultricies. Nulla augue dolor, suscipit eu mollis eu, aliquam condimentum diam. Ut semper orci luctus, pharetra turpis at, euismod mi. Nulla leo diam, finibus sit amet purus sed, maximus dictum lorem. Integer eu mi id turpis laoreet rhoncus. - -Integer a mauris tincidunt, finibus orci ut, pretium mauris. Nulla molestie nunc mi, id finibus lorem elementum sed. Proin quis laoreet ante. Integer nulla augue, commodo id molestie quis, rutrum ut turpis. Suspendisse et tortor turpis. Sed ut pharetra massa. Pellentesque elementum blandit sem, ut elementum tellus egestas a. Fusce eu purus nibh. - -Cras dignissim ligula scelerisque magna faucibus ullamcorper. Proin at condimentum risus, auctor malesuada quam. Nullam interdum interdum egestas. Nulla aliquam nisi vitae felis mollis dictum. Suspendisse dapibus consectetur tortor. Ut ut nisi non sem bibendum tincidunt. Vivamus suscipit leo quis gravida dignissim. - -Aliquam interdum, leo id vehicula mollis, eros eros rhoncus diam, non mollis ligula mi eu mauris. Sed ultrices vel velit sollicitudin tincidunt. Nunc auctor metus at ligula gravida elementum. Praesent interdum eu elit et mollis. Duis egestas quam sit amet velit dignissim consequat. Aliquam ac turpis nec nunc convallis sagittis. Fusce blandit, erat ac fringilla consectetur, dolor eros sodales leo, vel aliquet risus nisl et diam. Aliquam luctus felis vitae est eleifend euismod facilisis et lacus. Sed leo tellus, auctor eu arcu in, volutpat sagittis nisl. Pellentesque nisl ligula, placerat vel ullamcorper at, vulputate ac odio. Morbi ac faucibus orci, et tempus nulla. Proin rhoncus rutrum dolor, in venenatis mauris. Suspendisse a fermentum augue, non semper mi. Nunc eget pretium neque. Phasellus augue erat, feugiat ac aliquam congue, rutrum non sapien. Pellentesque ac diam gravida, consectetur felis at, ornare neque. - -Nullam interdum mattis sapien quis porttitor. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus aliquet rutrum ipsum id euismod. Maecenas consectetur massa et mi porta viverra. Nunc quam nibh, dignissim vitae maximus et, ullamcorper nec lorem. Nunc vitae justo dapibus, luctus lacus vitae, pretium elit. Maecenas et efficitur leo. Curabitur mauris lectus, placerat quis vehicula vitae, auctor ut urna. Quisque rhoncus pharetra luctus. In hac habitasse platea dictumst. Integer sit amet metus nec eros malesuada aliquam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi hendrerit mi ac leo aliquam, sit amet ultricies libero commodo. Mauris dapibus purus metus, sit amet viverra nibh imperdiet et. Nullam porta nulla tellus, quis vehicula diam imperdiet non. Vivamus enim massa, bibendum in fermentum in, ultrices at ex. - -Suspendisse fermentum id nibh eget accumsan. Duis dapibus bibendum erat ut sollicitudin. Aliquam nec felis risus. Pellentesque rhoncus ligula id sem maximus mollis sed nec massa. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ipsum ipsum, sodales sed enim id, convallis faucibus eros. Donec ultricies dictum tincidunt. Cras vitae nibh arcu. Pellentesque cursus, sapien nec consequat fermentum, ipsum ante suscipit dui, imperdiet hendrerit est nisl eu massa. Quisque vitae sem ligula. Aenean iaculis metus ut mauris interdum laoreet. Vivamus sed gravida dolor. - -Morbi nulla metus, porttitor sed eros sit amet, efficitur efficitur est. In vel nisl urna. Ut aliquet tellus at congue convallis. Phasellus imperdiet lobortis sollicitudin. Integer sodales, sem eu ultricies pharetra, erat erat porttitor odio, eget dapibus libero ipsum eget velit. Phasellus gravida nulla nisl, eu pharetra mi auctor vel. Sed blandit pharetra velit, ut egestas libero placerat non. Aliquam a interdum quam. Proin at tortor nec dui sollicitudin tempus sed vestibulum elit. Nunc non sollicitudin velit. - -Aenean consequat diam velit, sed rutrum tortor faucibus dictum. Quisque at semper augue. Duis ut est eget mi ornare bibendum id et ligula. Phasellus consequat tortor non leo pulvinar posuere. Proin vestibulum eleifend felis, in hendrerit tortor sollicitudin eu. Phasellus hendrerit, lacus vel laoreet interdum, dui tortor consequat justo, commodo ultricies arcu felis vitae enim. Vivamus eu sapien at leo suscipit rutrum eu at justo. Aenean et dolor a libero ullamcorper posuere. Integer laoreet placerat nisi in vulputate. Mauris laoreet eget risus sed cursus. Donec scelerisque neque a libero eleifend hendrerit. Nulla varius condimentum nunc sit amet fermentum. Aliquam lorem ex, varius nec mollis ut, ultrices in neque. Morbi sit amet porta leo. Integer iaculis fermentum lacus in vestibulum. - -Ut gravida, tellus ut maximus ultrices, erat est venenatis nisl, vitae pretium massa ex ac magna. Sed non purus eget ligula aliquet volutpat non quis arcu. Nam aliquam tincidunt risus, sit amet fringilla sapien vulputate ut. Mauris luctus suscipit pellentesque. Nunc porttitor dapibus ex quis tempus. Ut ullamcorper metus a eros vulputate, vitae viverra lectus convallis. Mauris semper imperdiet augue quis tincidunt. Integer porta pretium magna, sed cursus sem scelerisque sollicitudin. Nam efficitur, nibh pretium eleifend vestibulum, purus diam posuere sem, in egestas mauris augue sit amet urna. - -Vestibulum tincidunt euismod massa in congue. Duis interdum metus non laoreet fringilla. Donec at ligula congue, tincidunt nunc non, scelerisque nunc. Donec bibendum magna non est scelerisque feugiat at nec neque. Ut orci tortor, tempus eget massa non, dignissim faucibus dolor. Nam odio risus, accumsan pretium neque eget, accumsan dignissim dui. In ut neque auctor, scelerisque tellus sed, ullamcorper nisi. Suspendisse varius cursus quam at hendrerit. Vivamus elit libero, sagittis vitae sem ac, vulputate iaculis ligula. - -Sed lobortis laoreet purus sit amet rutrum. Pellentesque feugiat non leo vel lacinia. Quisque feugiat nisl a orci bibendum vestibulum. In et sollicitudin urna. Morbi a arcu ac metus faucibus tempus. Nam eu imperdiet sapien, suscipit mattis tortor. Aenean blandit ipsum nisi, a eleifend ligula euismod at. Integer tincidunt pharetra felis, mollis placerat mauris hendrerit at. Curabitur convallis, est sit amet luctus volutpat, massa lacus cursus augue, sed eleifend magna quam et risus. Aliquam lobortis tincidunt metus vitae porttitor. Suspendisse potenti. Aenean ullamcorper, neque id commodo luctus, nulla nunc lobortis quam, id dapibus neque dui nec mauris. Etiam quis lorem quis elit commodo ornare. Ut pharetra purus ultricies enim ultrices efficitur. Proin vehicula tincidunt molestie. Mauris et placerat sem. - -Aliquam erat volutpat. Suspendisse velit turpis, posuere ac lacus eu, lacinia laoreet velit. Sed interdum felis neque, id blandit sem malesuada sit amet. Ut sagittis justo erat, efficitur semper orci tempor sed. Donec enim massa, posuere varius lectus egestas, pellentesque posuere mi. Cras tincidunt ut libero sed mattis. Suspendisse quis magna et tellus posuere interdum vel at purus. Pellentesque fringilla tristique neque, id aliquet tellus ultricies non. Duis ut tellus vel odio lobortis vulputate. - -Integer at magna ac erat convallis vestibulum. Sed lobortis porttitor mauris. Fusce varius lorem et volutpat pulvinar. Aenean ac vulputate lectus, vitae consequat velit. Suspendisse ex dui, varius ut risus ut, dictum scelerisque sem. Vivamus urna orci, volutpat ut convallis ac, venenatis vitae urna. In hac habitasse platea dictumst. Etiam eu purus arcu. Aenean vulputate leo urna, vel tristique dui sagittis euismod. Suspendisse non tellus efficitur ante rhoncus volutpat at et sapien. - -Sed dapibus accumsan porttitor. Phasellus facilisis lectus finibus ligula dignissim, id pulvinar lectus feugiat. Nullam egestas commodo nisi posuere aliquet. Morbi sit amet tortor sagittis, rutrum dui nec, dapibus sapien. Sed posuere tortor tortor, interdum auctor magna varius vitae. Vestibulum id sagittis augue. Curabitur fermentum arcu sem, eu condimentum quam rutrum non. Phasellus rutrum nibh quis lectus rhoncus pretium. Curabitur dictum interdum elit. Vestibulum maximus sodales imperdiet. Mauris auctor nec purus sed venenatis. In in urna purus. - -Duis placerat molestie suscipit. Morbi a elit id purus efficitur consequat. Nunc ac commodo turpis. Etiam sit amet lacus a ipsum tempus venenatis sed vel nibh. Duis elementum aliquam mi sed tristique. Morbi ligula tortor, semper ac est vel, lobortis maximus erat. Curabitur ipsum felis, laoreet vel condimentum eget, ullamcorper sit amet mauris. Nulla facilisi. Nam at purus sed mi egestas placerat vitae vel magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse at dignissim diam. Phasellus consectetur eget neque vel viverra. Donec sollicitudin mattis dolor vel malesuada. Vivamus vehicula leo neque, vitae fermentum leo posuere et. Praesent dui est, finibus sit amet tristique quis, pharetra vel nibh. - -Duis nulla leo, accumsan eu odio eget, sagittis semper orci. Quisque ullamcorper ligula quam, commodo porttitor mauris ullamcorper eu. Cras varius sagittis felis in aliquam. Duis sodales risus ac justo vehicula, nec mattis diam lacinia. Cras eget lectus ipsum. Ut commodo, enim vitae malesuada hendrerit, ex dolor egestas lectus, sit amet hendrerit metus diam nec est. Vestibulum tortor metus, lobortis sit amet ante eget, tempor molestie lacus. In molestie et urna et semper. Mauris mollis, sem non hendrerit condimentum, sapien nisi cursus est, non suscipit quam justo non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam enim est, porta ac feugiat vitae, rutrum in lorem. Duis vehicula tortor ut posuere maximus. - -Nullam vestibulum non tellus sed commodo. Quisque mattis elit sit amet sapien sollicitudin, ut condimentum nisl congue. Aenean sagittis massa vel elit faucibus fermentum. Donec tincidunt nisi nec nisl sodales pellentesque. Mauris congue congue ligula ut suscipit. Vivamus velit tortor, tempor et gravida eget, fermentum sit amet ante. Nullam fringilla, lorem at ultrices cursus, urna neque ornare dolor, eu lacinia orci enim sed nibh. Ut a ullamcorper lectus, id mattis purus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean maximus sollicitudin posuere. Nunc at augue lacus. Aenean efficitur leo sit amet lacinia efficitur. - -Quisque venenatis quam mi, in pharetra odio vulputate eu. In vel nisl pulvinar, pulvinar ligula ut, sodales risus. Sed efficitur lectus at vestibulum tincidunt. Vestibulum eu ullamcorper elit. Fusce vestibulum magna enim, et tempor lacus posuere vitae. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer leo elit, luctus nec mattis sit amet, sollicitudin in turpis. - -Proin convallis venenatis leo, vitae tristique erat iaculis nec. Nulla facilisi. Duis porttitor, sapien et bibendum vulputate, sem libero sodales lacus, non malesuada felis erat ut libero. Nam non felis semper, finibus est a, mattis mauris. Praesent nec eros quam. Nulla hendrerit, augue consectetur eleifend ultricies, purus mi condimentum nulla, eget dapibus est nunc sed libero. Nullam elementum dui erat, vitae luctus libero sollicitudin et. Nulla odio magna, placerat in augue eu, dapibus imperdiet odio. Suspendisse imperdiet metus sit amet rhoncus dapibus. Cras at enim et urna vehicula cursus eu a mauris. Integer magna ante, eleifend ac placerat vitae, porta at nisi. Cras eget malesuada orci. Curabitur nunc est, vulputate id viverra et, dignissim sed odio. Curabitur non mattis sem. Sed bibendum, turpis vitae vehicula faucibus, nunc quam ultricies lectus, vitae viverra felis turpis at libero. - -Nullam ut egestas ligula. Proin hendrerit justo a lectus commodo venenatis. Nulla facilisi. Ut cursus lorem quis est bibendum condimentum. Aenean in tristique odio. Fusce tempor hendrerit ipsum. Curabitur mollis felis justo, quis dapibus erat auctor vel. Sed augue lectus, finibus ut urna quis, ullamcorper vestibulum dui. Etiam molestie aliquam tempor. Integer mattis sollicitudin erat, et tristique elit varius vel. Mauris a ex justo. - -Nam eros est, imperdiet non volutpat rutrum, pellentesque accumsan ligula. Duis sit amet turpis metus. Aenean in rhoncus metus, ac fringilla ex. Suspendisse condimentum egestas purus, ut pharetra odio vulputate vel. Duis tincidunt massa a placerat ultrices. Mauris ultricies nibh sit amet condimentum malesuada. Duis tincidunt id ipsum sed congue. - -Praesent eu ex augue. Nullam in porta ligula. In tincidunt accumsan arcu, in pellentesque magna tristique in. Mauris eleifend libero ac nisl viverra faucibus. Nam sollicitudin dolor in commodo hendrerit. Cras at orci metus. Ut quis laoreet orci. Vivamus ultrices leo pellentesque tempor aliquet. Maecenas ut eros vitae purus placerat vestibulum. Etiam vitae gravida dolor, quis rhoncus diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. - -Suspendisse fringilla lacinia sagittis. Integer tincidunt consectetur tristique. Morbi non orci convallis, congue sapien quis, vulputate nunc. Donec a libero vel magna elementum facilisis non quis mi. Mauris posuere tellus non ipsum ultrices elementum. Vivamus massa velit, facilisis quis placerat aliquet, aliquet nec leo. Praesent a maximus sem. Sed neque elit, feugiat vel quam non, molestie sagittis nunc. Etiam luctus nunc ac mauris scelerisque, nec rhoncus lacus convallis. Nunc pharetra, nunc ac pulvinar aliquam, ex ipsum euismod augue, nec porttitor lacus turpis vitae neque. Fusce bibendum odio id tortor faucibus pellentesque. Sed ac porta nibh, eu gravida erat. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam quis ullamcorper felis. Nulla mattis sagittis ante ac tincidunt. Integer ac felis efficitur, viverra libero et, facilisis ligula. Suspendisse a metus a massa rhoncus posuere. Phasellus suscipit ligula ut lacus facilisis, ac pellentesque ex tempor. Quisque consectetur massa mi, ac molestie libero dictum quis. Proin porttitor ligula quis erat tincidunt venenatis. Proin congue nunc sed elit gravida, nec consectetur lectus sodales. Etiam tincidunt convallis ipsum at vestibulum. Quisque maximus enim et mauris porttitor, et molestie magna tristique. Morbi vitae metus elit. Maecenas sed volutpat turpis. Aliquam vitae dolor vestibulum, elementum purus eget, dapibus nibh. Nullam egestas dui ac rutrum semper. - -Etiam hendrerit est metus, et condimentum metus aliquam ac. Pellentesque id neque id ipsum rhoncus vulputate. Aliquam erat nisl, posuere sit amet ligula ac, fermentum blandit felis. Vivamus fermentum mi risus, non lacinia purus viverra id. Aenean ac sapien consequat, finibus mauris nec, porta sem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed quis consectetur ex, dignissim bibendum nulla. Phasellus ac libero at quam vehicula euismod non eu leo. Phasellus a sapien augue. - -Maecenas ligula dui, bibendum vitae mauris et, auctor laoreet felis. Duis non libero a mi semper mattis. Quisque consequat luctus massa, quis tristique eros auctor feugiat. Maecenas sodales euismod neque vitae facilisis. Nullam laoreet imperdiet velit at pellentesque. Etiam massa odio, facilisis a consequat vitae, placerat vel magna. Nunc sagittis eros nec urna fringilla, pulvinar vestibulum nibh scelerisque. Sed magna metus, cursus eu consequat et, pharetra a est. Suspendisse elementum neque a dui malesuada lacinia. Donec sed ipsum volutpat, cursus urna id, ullamcorper arcu. Maecenas laoreet nisl eget velit egestas sollicitudin. Etiam nisl turpis, mollis id dignissim vitae, tristique vehicula ante. Maecenas eget placerat est, at rutrum augue. Vivamus faucibus lacinia ullamcorper. Sed pulvinar urna sodales ante sodales, at gravida leo dictum. - -Morbi maximus, quam a lobortis bibendum, enim felis varius elit, ac vehicula elit nisl ut lacus. Quisque ut arcu augue. Praesent id turpis quam. Sed sed arcu eros. Maecenas at cursus lorem, ac eleifend nisi. Fusce mattis felis at commodo pharetra. Praesent ac commodo ipsum. Quisque finibus et eros vitae tincidunt. In hac habitasse platea dictumst. Praesent purus ipsum, luctus lobortis ornare quis, auctor eget justo. Nam vel enim sollicitudin, faucibus tortor eu, sagittis eros. Ut nec consectetur erat. Donec ultricies malesuada ligula, a hendrerit sapien volutpat in. Maecenas sed enim vitae sapien pulvinar faucibus. - -Proin semper nunc nibh, non consequat neque ullamcorper vel. Maecenas lobortis sagittis blandit. Aenean et arcu ultricies turpis malesuada malesuada. Ut quam ex, laoreet ut blandit cursus, feugiat vitae dolor. Etiam ex lacus, scelerisque vel erat vel, efficitur tincidunt magna. Morbi tristique lacinia dolor, in egestas magna ultrices vitae. Integer ultrices leo ac tempus venenatis. Praesent ac porta tortor. Vivamus ornare blandit tristique. Nulla rutrum finibus pellentesque. In non dui elementum, fermentum ipsum vel, varius magna. Pellentesque euismod tortor risus, ac pellentesque nisl faucibus eget. - -Vivamus eu enim purus. Cras ultrices rutrum egestas. Sed mollis erat nibh, at posuere nisl luctus nec. Nunc vulputate, sapien id auctor molestie, nisi diam tristique ante, non convallis tellus nibh at orci. Morbi a posuere purus, in ullamcorper ligula. Etiam elementum sit amet dui imperdiet iaculis. Proin vitae tincidunt ipsum, sit amet placerat lectus. Curabitur commodo sapien quam, et accumsan lectus fringilla non. Nullam eget accumsan enim, ac pharetra mauris. Sed quis tristique velit, vitae commodo nisi. Duis turpis dui, maximus ut risus at, finibus consequat nunc. Maecenas sed est accumsan, aliquet diam in, facilisis risus. Curabitur vehicula rutrum auctor. Nam iaculis risus pulvinar maximus viverra. Nulla vel augue et ex sagittis blandit. - -Ut sem nulla, porta ac ante ac, posuere laoreet eros. Donec sodales posuere justo a auctor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras mollis at orci hendrerit porta. Nullam sodales tortor tortor, non lacinia diam finibus id. Duis libero orci, suscipit ac odio et, dictum consequat ipsum. Pellentesque eu ligula sagittis, volutpat eros at, lacinia lorem. Cras euismod tellus in iaculis tempor. Quisque accumsan, magna a congue venenatis, ante ipsum aliquam lectus, at egestas enim nunc at justo. Quisque sem purus, viverra ut tristique ut, maximus id enim. Etiam quis placerat sem. In sollicitudin, lacus eu rutrum mollis, nulla eros luctus elit, vel dapibus urna purus nec urna. Phasellus egestas massa quam, ac molestie erat hendrerit a. Praesent ultrices neque ut turpis molestie auctor. Etiam molestie placerat purus, et euismod erat aliquam in. Morbi id suscipit justo. - -Proin est ante, consequat at varius a, mattis quis felis. Sed accumsan nibh sit amet ipsum elementum posuere. Vestibulum bibendum id diam sit amet gravida. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi nec dolor vel ipsum dignissim hendrerit vel non ipsum. Praesent facilisis orci quis elit auctor lobortis. Phasellus cursus risus lectus, vel lobortis libero dapibus in. Quisque tristique tempus leo a pulvinar. Pellentesque a magna tincidunt, pellentesque massa nec, laoreet orci. Morbi congue ornare dolor quis commodo. Phasellus massa nisi, tincidunt at eros dictum, hendrerit lobortis urna. Maecenas porta, magna id mattis molestie, nibh tellus lobortis sem, eget tincidunt ipsum quam eu turpis. - -Ut gravida orci risus, vel rutrum mauris vehicula id. Etiam bibendum, neque a placerat condimentum, ex orci imperdiet lectus, quis dapibus arcu lacus eget lectus. Sed consequat non mi sit amet venenatis. Fusce vestibulum erat libero, eget hendrerit risus vulputate sollicitudin. Integer sed eleifend felis. Donec commodo, sem eu mattis placerat, urna odio aliquam tellus, et laoreet justo tellus eget erat. Fusce sed suscipit tortor. Nam hendrerit nibh ac nunc auctor lacinia. Pellentesque placerat condimentum ipsum, eget semper tortor hendrerit vel. Nullam non urna eu lacus pellentesque congue ut id eros. - -Nunc finibus leo in rhoncus tristique. Sed eu ipsum nec nisl egestas faucibus eget a felis. Pellentesque vitae nisi in nulla accumsan fermentum. Sed venenatis feugiat eleifend. Fusce porttitor varius placerat. Aliquam aliquet lacus sit amet mattis mollis. Sed vel nulla quis dolor suscipit vehicula ac viverra lorem. Duis viverra ipsum eget nulla ullamcorper fermentum. Mauris tincidunt arcu quis quam fringilla ornare. Donec et iaculis tortor. Nam ultricies libero vel ipsum aliquet efficitur. Morbi eget dolor aliquam, tempus sapien eget, viverra ante. Donec varius mollis ex, sed efficitur purus euismod interdum. Quisque vel sapien non neque tincidunt semper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. - -Suspendisse sit amet purus leo. Fusce lectus lorem, aliquam ac nulla eget, imperdiet ornare eros. Nullam sem augue, varius in nisi non, sollicitudin pellentesque ante. Etiam eu odio condimentum, tempor libero et, egestas arcu. Cras pellentesque eleifend aliquet. Pellentesque non blandit ligula. Ut congue viverra rhoncus. Phasellus mattis mi ac eros placerat, eu feugiat tellus ultrices. Aenean mollis laoreet libero eu imperdiet. Cras sed pulvinar mi, ac vehicula ligula. Vestibulum sit amet ex massa. In a egestas eros. - -Mauris pretium ipsum risus, venenatis cursus ante imperdiet id. Praesent eu turpis nec risus feugiat maximus ullamcorper ac lectus. Integer placerat at mi vel dapibus. Vestibulum fermentum turpis sit amet turpis viverra, id aliquet diam suscipit. Nam nec ex sed ante ullamcorper pharetra quis sit amet risus. Sed ac faucibus velit, id feugiat nibh. Nullam eget ipsum ex. Vivamus tincidunt non nunc non faucibus. Quisque bibendum viverra facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at nisi hendrerit quam suscipit egestas. Curabitur laoreet maximus ultricies. Duis ut tellus ac augue molestie dictum. - -Suspendisse rhoncus iaculis erat, ut ullamcorper est tristique eget. Donec auctor nec risus at gravida. Vivamus volutpat vulputate tellus, vel ultricies eros suscipit eget. Ut pulvinar id mi eu tempus. Morbi malesuada augue in dui varius, nec blandit neque vehicula. Donec ornare nec nisl in mollis. Morbi enim nisi, rhoncus nec est id, dapibus tempus urna. Ut id elit a felis vestibulum consectetur. Duis lectus quam, pharetra sit amet diam sed, posuere vestibulum erat. Fusce vitae maximus massa. Nullam id metus tempus, iaculis risus eu, lobortis urna. Quisque in congue urna. Pellentesque placerat neque in augue dapibus, non varius ex malesuada. Curabitur ut eleifend libero. Fusce vitae ligula luctus, fermentum enim vitae, ultrices erat. - -Sed viverra augue turpis, scelerisque egestas sapien mattis eu. Duis laoreet magna at ex pharetra dapibus. Praesent eget odio vel quam venenatis dictum. Nulla in sollicitudin dolor. Mauris lobortis nec eros vel rhoncus. Vestibulum porta viverra venenatis. Curabitur vel scelerisque quam, a egestas velit. Praesent volutpat tincidunt magna at laoreet. - -Cras nec lorem odio. Pellentesque quis dui urna. Praesent at tellus ac lectus scelerisque placerat nec eu risus. Vestibulum sit amet mattis ligula. Vivamus sed nisi at leo elementum accumsan at sit amet arcu. Aenean mattis tellus nec leo gravida, eget hendrerit nisl faucibus. Mauris pellentesque luctus condimentum. Maecenas pretium sapien nunc, eget commodo dolor maximus id. Mauris vestibulum accumsan massa a dictum. Phasellus interdum quam ligula, ut maximus diam blandit aliquam. Nunc vitae ex eu erat condimentum consectetur. Maecenas interdum condimentum volutpat. - -Donec et enim a libero rutrum laoreet. Praesent a condimentum sem, at tincidunt quam. In vel molestie risus. Sed urna dui, molestie vitae mollis laoreet, tempor quis lectus. Praesent vitae auctor est, et aliquet nunc. Curabitur vulputate blandit nulla, at gravida metus. Maecenas gravida dui eu iaculis tristique. Pellentesque posuere turpis nec auctor eleifend. Suspendisse bibendum diam eu tellus lobortis, et laoreet quam congue. In hac habitasse platea dictumst. Morbi dictum neque velit, eget rutrum eros ultrices sit amet. - -Phasellus fermentum risus pharetra consectetur bibendum. Donec magna tortor, lacinia vitae nibh quis, aliquet pretium lorem. Donec turpis nisi, pretium eu enim volutpat, mattis malesuada augue. Nullam vel tellus iaculis, sollicitudin elit eget, tincidunt lacus. Fusce elementum elementum felis et iaculis. Suspendisse porta eros nec neque malesuada, in malesuada ante sollicitudin. Vivamus bibendum viverra molestie. - -Integer feugiat, erat nec convallis aliquam, velit felis congue erat, molestie eleifend tellus erat in tellus. Nunc et justo purus. Donec egestas fermentum dui non feugiat. Quisque in sapien sagittis, gravida quam id, iaculis lectus. Cras sagittis rhoncus bibendum. Fusce quis metus in velit scelerisque tincidunt at non ipsum. Vivamus efficitur ante eu odio vulputate, vitae ultricies risus vehicula. Proin eget odio eu sem tincidunt feugiat vel id lorem. - -Vestibulum sit amet nulla dignissim, euismod mi in, fermentum tortor. Donec ut aliquet libero, lacinia accumsan velit. Donec et nulla quam. Nullam laoreet odio nec nunc imperdiet, a congue eros venenatis. Quisque nec tellus sit amet neque interdum posuere. Duis quis mi gravida, tincidunt diam convallis, ultricies augue. Mauris consequat risus non porttitor congue. Ut in ligula consequat, viverra nunc a, eleifend enim. Duis ligula urna, imperdiet nec facilisis et, ornare eu ex. Proin lobortis lectus a lobortis porttitor. Nulla leo metus, egestas eu libero sed, pretium faucibus felis. Vestibulum non sem tortor. Nam cursus est leo. Vivamus luctus enim odio, non interdum sem dapibus a. Aenean accumsan consequat lectus in imperdiet. - -Donec vehicula laoreet ipsum in posuere. Quisque vel quam imperdiet, sollicitudin nisi quis, suscipit velit. Morbi id sodales mauris. Curabitur tellus arcu, feugiat sed dui sit amet, sodales sagittis libero. Aenean vel suscipit metus, non placerat leo. Vestibulum quis nulla elit. Proin scelerisque non ante ut commodo. Interdum et malesuada fames ac ante ipsum primis in faucibus. - -Sed non urna dolor. Suspendisse convallis mi porta pulvinar ultrices. Suspendisse quam ipsum, hendrerit non scelerisque molestie, interdum dictum nunc. Morbi condimentum condimentum turpis eu luctus. Pellentesque sagittis sollicitudin odio, sed ultricies felis ornare sit amet. Sed ultrices ex leo, a tincidunt nisl gravida sed. Nullam ornare accumsan porta. Praesent consectetur id est nec sollicitudin. - -In hac habitasse platea dictumst. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sed ultrices nibh. Duis accumsan suscipit eros, a dictum odio tempus sit amet. Aenean imperdiet erat ac lacus finibus, scelerisque cursus massa imperdiet. Mauris molestie risus ut lacinia posuere. Nulla et sodales purus. Maecenas orci erat, placerat in tristique quis, placerat in mi. - -Donec sollicitudin pellentesque odio in feugiat. Morbi eu dolor ut mauris congue sollicitudin. Aliquam erat volutpat. Nulla id varius dui. Curabitur finibus urna ante, consectetur interdum nisi volutpat a. Quisque quis mi tristique, consequat tellus eget, rutrum sapien. Vivamus vitae tellus vulputate, rutrum ex eu, vulputate sem. Suspendisse viverra lorem tellus, vel interdum orci gravida quis. Ut laoreet arcu at mi ullamcorper finibus. Duis porta sagittis vestibulum. Sed commodo nisl vitae urna sollicitudin, nec lacinia est sodales. Curabitur imperdiet sodales dui sed iaculis. Sed ac tellus maximus, eleifend quam sit amet, feugiat elit. Aenean viverra, dui at mattis varius, est odio vestibulum sapien, sit amet mollis libero massa nec velit. Etiam quis sodales justo. - -Ut ultricies, sem eget sodales feugiat, nunc arcu congue elit, ac tempor justo massa nec purus. Maecenas enim nunc, pharetra eget dictum sit amet, tempus pellentesque velit. Suspendisse venenatis ligula in nulla mattis, et imperdiet ex tincidunt. Etiam vulputate, tellus et ultrices suscipit, enim velit laoreet massa, vitae congue odio enim ac urna. Morbi quam lorem, iaculis ac varius sagittis, euismod quis dolor. In ut dui eu purus feugiat consectetur. Vestibulum cursus velit quis lacus pellentesque iaculis. Cras in risus sed mauris porta rutrum. Nulla facilisi. Nullam eu bibendum est, non pellentesque lectus. Sed imperdiet feugiat lorem, quis convallis ante auctor in. Maecenas justo magna, scelerisque sit amet tellus eget, varius elementum risus. Duis placerat et quam sed varius. - -Duis nec nibh vitae nibh dignissim mollis quis sed felis. Curabitur vitae quam placerat, venenatis purus ut, euismod nisl. Curabitur porttitor nibh eu pulvinar ullamcorper. Suspendisse posuere nec ipsum ac dapibus. Cras convallis consectetur urna. Phasellus a nibh in dolor lacinia posuere id eget augue. In eu pharetra lorem, vitae cursus lacus. Aliquam tincidunt nibh lectus. Aenean facilisis ultricies posuere. Sed ut placerat orci. Curabitur scelerisque gravida blandit. Maecenas placerat ligula eget suscipit fringilla. Mauris a tortor justo. Aliquam hendrerit semper mollis. Phasellus et tincidunt libero. Etiam vel quam libero. - -Quisque aliquet tempor ex. Ut ante sem, vehicula at enim vel, gravida porta elit. Etiam vitae lacus a neque lobortis consectetur. Mauris sed interdum odio. Mauris elementum ex blandit tempor cursus. Integer in enim in leo viverra elementum. Fusce consectetur metus et sem rutrum, mattis euismod diam semper. Nunc sed ipsum vel urna consequat vehicula. Donec cursus pretium lorem, vestibulum pretium felis commodo sit amet. Nam blandit felis enim, eget gravida ex faucibus a. In nec neque massa. Etiam laoreet posuere ipsum. Praesent volutpat nunc dolor, ac vulputate magna facilisis non. Aenean congue turpis vel lectus sollicitudin tristique. Sed nec consequat purus, non vehicula quam. Etiam ultricies, est ac dictum tincidunt, turpis turpis pretium massa, a vulputate libero justo at nibh. - -Aliquam erat volutpat. Cras ultrices augue ac sollicitudin lobortis. Curabitur et aliquet purus. Duis feugiat semper facilisis. Phasellus lobortis cursus velit, a sollicitudin tortor. Nam feugiat sapien non dapibus condimentum. Morbi at mi bibendum, commodo quam at, laoreet enim. Integer eu ultrices enim. Sed vestibulum eu urna ut dictum. Curabitur at mattis leo, sed cursus massa. Aliquam porttitor, felis quis fermentum porttitor, justo velit feugiat nulla, eget condimentum sem dui ut sapien. - -In fringilla elit eu orci aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut eget fringilla tellus. Curabitur fermentum, mi et condimentum suscipit, elit neque bibendum dui, et hendrerit nunc metus id ipsum. Morbi placerat mi in hendrerit congue. Ut feugiat mauris eget scelerisque viverra. Vivamus sit amet erat dictum, sagittis lectus nec, pulvinar lorem. Sed non enim ac dui sollicitudin aliquet. Quisque ut lacus dolor. Fusce hendrerit malesuada euismod. Nulla faucibus vel mauris eu mollis. Mauris est diam, fringilla ac arcu feugiat, efficitur volutpat turpis. Aliquam venenatis cursus massa sed porttitor. Ut ac finibus enim, in tincidunt sapien. - -Nunc faucibus semper turpis a lacinia. Phasellus gravida, libero vel pulvinar ornare, ex sem tincidunt lectus, sit amet convallis augue risus at tortor. Quisque sit amet ipsum id nulla posuere vestibulum. Pellentesque scelerisque mauris vel leo viverra sodales. Nulla viverra aliquam ex, ut rutrum enim fermentum venenatis. Aenean eget dapibus ex, eget faucibus metus. Vestibulum volutpat leo in diam semper, eget porta magna suscipit. Sed sit amet nulla blandit, aliquam dolor ac, gravida velit. Sed vel velit viverra, maximus est id, convallis justo. - -Curabitur nulla ante, vulputate at libero vel, ullamcorper rutrum nibh. Pellentesque porttitor eu mauris id mattis. Duis vulputate augue elit, eget interdum justo pretium vel. Maecenas eu vulputate arcu, eget posuere purus. Suspendisse viverra a velit dictum eleifend. Suspendisse vitae dapibus diam. Donec vehicula justo in ante interdum, eu luctus diam placerat. Vivamus convallis ipsum eu orci suscipit, sed fermentum enim euismod. Maecenas faucibus elit vitae ex ornare tristique. Donec vestibulum nec elit sit amet porttitor. Aenean tempor lectus eget tortor hendrerit luctus. Nullam interdum vitae lectus vel feugiat. Cras in risus non magna consectetur lobortis. Sed faucibus enim quis gravida convallis. - -Phasellus eget massa sit amet libero ultrices suscipit. Vivamus at risus sapien. Nam mollis nunc eget velit dictum maximus. Sed pellentesque, nunc ac fringilla lacinia, quam enim mattis ex, sed euismod tortor metus eu neque. Ut mattis nisl ut lectus rhoncus, sodales bibendum eros porta. Nulla porttitor enim nec diam sagittis, eget porta velit efficitur. Vestibulum ultricies eros neque. Phasellus rutrum suscipit enim, in interdum ante gravida vitae. Sed in sagittis diam, non commodo velit. - -Morbi hendrerit odio orci, nec tincidunt odio rhoncus nec. Mauris neque velit, vehicula a lorem at, suscipit tristique dui. Sed finibus, nisl in mattis convallis, turpis neque sodales lacus, eu porta enim magna non diam. Nam commodo sodales risus consectetur malesuada. In eget elementum justo. Phasellus sit amet massa imperdiet, dapibus nunc sit amet, suscipit orci. Fusce condimentum laoreet feugiat. Ut ut viverra ante. Praesent bibendum interdum commodo. Nulla mollis nisi a est ornare volutpat. Sed at ligula eu nisi dapibus tempus. Proin cursus vestibulum justo, nec efficitur justo dignissim vel. Nunc quis maximus eros. - -Cras viverra, diam a tristique mattis, libero felis vulputate tellus, a ornare felis leo a dui. Nulla ante nulla, finibus ut tellus ut, blandit pharetra nibh. Proin eleifend fermentum ex, eget auctor libero vulputate in. Nullam ultricies, mauris placerat pretium placerat, leo urna lobortis leo, vel placerat arcu libero sed mauris. Aliquam mauris ligula, ornare at urna at, eleifend gravida ligula. Vestibulum consectetur ut nulla non scelerisque. Donec ornare, sem nec elementum aliquam, urna nulla bibendum metus, eu euismod dui ligula ac est. Fusce laoreet erat eu ex lobortis, quis bibendum ligula interdum. Sed vel mi erat. Vivamus id lacus ac enim mattis tempor. Nunc ultricies pellentesque enim sed euismod. Fusce tincidunt convallis elit quis aliquam. Mauris nulla ipsum, sollicitudin quis diam ac, feugiat volutpat tellus. In nibh nibh, vulputate quis tincidunt quis, pulvinar eget magna. Pellentesque quis finibus dolor. Suspendisse viverra vitae lectus non eleifend. - -Nunc ut orci et sapien maximus semper. Nulla dignissim sem urna, ac varius lectus ultricies id. Quisque aliquet pulvinar pretium. In ultricies molestie tellus vehicula porta. Nam enim lorem, aliquam eget ex et, hendrerit volutpat quam. Maecenas diam lacus, pellentesque eget tempus ac, pharetra eu elit. Donec vel eros a sem facilisis vulputate. Nullam ac nisi vulputate, laoreet nisl ac, eleifend sem. Nullam mi massa, rhoncus sed pharetra interdum, tincidunt eget nunc. Aliquam viverra mattis posuere. Mauris et dui sed nisl sollicitudin fermentum quis ut arcu. Nam placerat eget orci at tincidunt. Curabitur vel turpis metus. Phasellus nibh nulla, fermentum scelerisque sem vel, gravida tincidunt velit. Pellentesque vel quam tempor, finibus massa pellentesque, condimentum dui. - -Donec at mattis neque. Etiam velit diam, consequat auctor mauris id, hendrerit faucibus metus. Maecenas ullamcorper eros a est sodales, ac consectetur odio scelerisque. Donec leo metus, imperdiet at pellentesque vel, feugiat id erat. Suspendisse at magna enim. Vestibulum placerat sodales lorem id sollicitudin. Aenean at euismod ligula, eget mollis diam. Phasellus pulvinar, orci nec pretium condimentum, est erat facilisis purus, quis feugiat augue elit aliquam nulla. Aenean vitae tortor id risus congue tincidunt. Sed dolor enim, mattis a ullamcorper id, volutpat ac leo. - -Proin vehicula feugiat augue, id feugiat quam sodales quis. Donec et ultricies massa, a lacinia nulla. Duis aliquam augue ornare euismod viverra. Ut lectus risus, rutrum sit amet efficitur a, luctus nec nisl. Cras volutpat ullamcorper congue. Sed vitae odio metus. Phasellus aliquet euismod varius. - -Nullam sem ex, malesuada ut magna ut, pretium mollis arcu. Nam porttitor eros cursus mi lacinia faucibus. Suspendisse aliquet eleifend iaculis. Maecenas sit amet viverra tortor. Nunc a mollis risus. Etiam tempus dolor in tortor malesuada mattis. Ut tincidunt venenatis est sit amet dignissim. Vestibulum massa enim, tristique sed scelerisque eu, fringilla ac velit. Donec efficitur quis urna sit amet malesuada. Vestibulum consequat ac ligula in dapibus. Maecenas massa massa, molestie non posuere nec, elementum ut magna. In nisi erat, mollis non venenatis eu, faucibus in justo. Morbi gravida non ex non egestas. Pellentesque finibus laoreet diam, eu commodo augue congue vitae. - -Aenean sem mi, ullamcorper dapibus lobortis vitae, interdum tincidunt tortor. Vivamus eget vulputate libero. Ut bibendum posuere lectus, vel tincidunt tortor aliquet at. Phasellus malesuada orci et bibendum accumsan. Aliquam quis libero vel leo mollis porta. Sed sagittis leo ac lacus dictum, ac malesuada elit finibus. Suspendisse pharetra luctus commodo. Vivamus ultricies a odio non interdum. Vivamus scelerisque tincidunt turpis quis tempor. Pellentesque tortor ligula, varius non nunc eu, blandit sollicitudin neque. Nunc imperdiet, diam et tristique luctus, ipsum ex condimentum nunc, sit amet aliquam justo velit sed libero. Duis vel suscipit ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed tincidunt neque vel massa ultricies, id dictum leo consequat. Curabitur lobortis ultricies tellus, eget mattis nisl aliquam sit amet. - -Proin at suscipit justo. Vivamus ut vestibulum nisl. Pellentesque enim odio, pharetra non magna sed, efficitur auctor magna. Praesent tincidunt ante quis ante hendrerit viverra. Pellentesque vel ipsum id magna vulputate efficitur. Sed nec neque accumsan, pulvinar sapien quis, euismod mauris. Donec condimentum laoreet sapien quis gravida. Quisque sed mattis purus. Vestibulum placerat vel neque maximus scelerisque. - -Vestibulum mattis quam quis efficitur elementum. Duis dictum dolor ac scelerisque commodo. Fusce sollicitudin nisi sit amet dictum placerat. Suspendisse euismod pharetra eleifend. In eros nisl, porttitor sed mauris at, consectetur aliquet mauris. Donec euismod viverra neque sed fermentum. Phasellus libero magna, accumsan ut ultricies vitae, dignissim eget metus. Donec tellus turpis, interdum eget maximus nec, hendrerit eget massa. Curabitur auctor ligula in iaculis auctor. In ultrices quam suscipit cursus finibus. Aenean id mi at dolor interdum iaculis vitae ut lorem. Nullam sed nibh fringilla, lacinia odio nec, placerat erat. In dui libero, viverra ac viverra ac, pellentesque sit amet turpis. - -Nulla in enim ex. Sed feugiat est et consectetur venenatis. Cras varius facilisis dui vel convallis. Vestibulum et elit eget tellus feugiat pellentesque. In ut ante eu purus aliquet posuere. Nulla nec ornare sem, sed luctus lorem. Nam varius iaculis odio, eget faucibus nisl ullamcorper in. Sed eget cursus felis, nec efficitur nisi. - -Vivamus commodo et sem quis pulvinar. Pellentesque libero ante, venenatis vitae ligula sit amet, ornare sollicitudin nulla. Mauris eget tellus hendrerit, pulvinar metus quis, tempor nisi. Proin magna ex, laoreet sed tortor quis, varius fermentum enim. Integer eu dolor dictum, vulputate tortor et, aliquet ligula. Vestibulum vitae justo id mauris luctus sollicitudin. Suspendisse eget auctor neque, sodales egestas lorem. Vestibulum lacinia egestas metus vitae euismod. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus ex tellus, volutpat nec pulvinar sit amet, condimentum vitae dui. Curabitur vel felis sodales, lacinia nunc iaculis, ullamcorper augue. Pellentesque consequat dolor quis eros efficitur malesuada. Nulla ut malesuada lectus. - -Morbi et tristique ante. Aliquam erat volutpat. Vivamus vitae dui nec turpis pellentesque fermentum. Quisque eget velit massa. Pellentesque tristique aliquam nisl, eu sollicitudin justo venenatis sed. Duis eleifend sem eros, ut aliquam libero porttitor id. Sed non nunc consequat, rhoncus diam eu, commodo erat. Praesent fermentum in lectus id blandit. Donec quis ipsum at justo volutpat finibus. Nulla blandit justo nulla, at mollis lacus consequat eget. Aenean sollicitudin quis eros ut ullamcorper. - -Pellentesque venenatis nulla ut mi aliquet feugiat. Cras semper vel magna nec pharetra. Integer mattis felis et sapien commodo imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis quis luctus felis. Vestibulum justo nibh, aliquam non lectus vitae, molestie placerat justo. Donec lorem nibh, gravida sit amet hendrerit ac, maximus id ipsum. Nunc ac libero sodales risus eleifend sagittis. Phasellus est massa, lobortis elementum ex sed, scelerisque consectetur neque. Nunc faucibus neque id lorem malesuada, eget convallis ex mattis. - -Sed turpis tortor, fermentum non turpis id, posuere varius nibh. Donec iaculis lorem dui. Etiam eros ante, sodales eget venenatis at, consectetur eget risus. Curabitur non aliquam ante, a pretium justo. Maecenas tempor nisl tortor, vitae dictum nisi ultrices eu. Duis eget dui ultrices, porttitor lacus sed, lobortis purus. Quisque mattis elit nec neque sagittis, sed commodo leo blandit. Mauris sodales interdum eleifend. Vestibulum condimentum consectetur augue, id luctus diam convallis et. - -Nunc suscipit risus in justo accumsan, a placerat magna tincidunt. Proin a nisl ipsum. Sed libero dui, tristique in augue quis, auctor tristique risus. Sed porttitor ex augue, eu porta augue molestie a. Duis rhoncus purus libero, eu tempus turpis condimentum at. Sed mollis nisi id lectus placerat tincidunt. Maecenas non scelerisque elit, quis rutrum orci. Donec in tellus pharetra urna ornare lobortis. Phasellus id risus at nisi varius rutrum eu ut turpis. - -Duis dictum justo quis nisl porta, eget tincidunt magna suscipit. Sed velit massa, ullamcorper eu sodales ac, pretium a massa. Duis et rutrum tortor. Nulla accumsan hendrerit sapien, cursus volutpat eros egestas eget. Donec sollicitudin at ante quis sollicitudin. Aenean blandit feugiat diam, id feugiat eros faucibus eget. Donec viverra dolor vel justo scelerisque dignissim. Nulla semper sem nunc, rhoncus semper tellus ultricies sed. Duis in ornare diam. Donec vehicula feugiat varius. Maecenas ut suscipit est. Vivamus sem sem, finibus at dolor sit amet, euismod dapibus ligula. Vestibulum fringilla odio dapibus, congue massa eget, congue sem. Donec feugiat magna eget tortor lacinia scelerisque non et ipsum. - -Suspendisse potenti. Nunc convallis sollicitudin ex eget venenatis. Sed iaculis nibh ex, vel ornare ligula congue dignissim. Quisque sollicitudin dolor ac dui vestibulum, sit amet molestie nisi aliquet. Donec at risus felis. Aenean sollicitudin metus a feugiat porta. Aenean a tortor ut dolor cursus sagittis. Vivamus consectetur porttitor nunc in facilisis. Proin sit amet mi vel lectus consectetur ultrices. - -Sed cursus lectus vitae nunc tristique, nec commodo turpis dapibus. Pellentesque luctus ex id facilisis ornare. Morbi quis placerat dolor. Donec in lectus in arcu mattis porttitor ac sit amet metus. Cras congue mauris non risus sodales, vitae feugiat ipsum bibendum. Nulla venenatis urna sed libero elementum, a cursus lorem commodo. Mauris faucibus lobortis eros nec commodo. - -Nullam suscipit ligula ullamcorper lorem commodo blandit. Nulla porta nibh quis pulvinar placerat. Vivamus eu arcu justo. Vestibulum imperdiet est ut fermentum porttitor. Pellentesque consectetur libero in sapien efficitur scelerisque. Curabitur ac erat sit amet odio aliquet dignissim. Pellentesque mi sem, rhoncus et luctus at, porttitor rutrum lectus. Vestibulum sollicitudin sollicitudin suscipit. Aenean efficitur dolor non ultrices imperdiet. Donec vel sem ex. - -Sed convallis mauris aliquam rutrum cursus. Ut tempor porttitor sodales. Etiam eu risus ac augue gravida egestas et eu dolor. Proin id magna ex. Suspendisse quis lectus quis lorem ultricies tempus. Donec porttitor velit vitae tincidunt faucibus. Aliquam vitae semper nisi. Morbi ultrices, leo non pretium dapibus, dui libero pellentesque ex, vel placerat enim ante vitae dui. Nunc varius, sem sit amet sagittis lobortis, lectus odio scelerisque mauris, ut vestibulum orci magna quis neque. Sed id congue justo. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris congue nisi est, malesuada mollis elit tincidunt sed. Curabitur sed ex sit amet felis tristique elementum vitae vel nibh. - -Etiam mollis pretium lobortis. Mauris augue lacus, efficitur at lacus sed, mollis tincidunt lectus. Aliquam erat volutpat. Donec at euismod elit, et mattis felis. Sed id lobortis urna. Morbi imperdiet vestibulum leo, sed maximus leo blandit eu. Aliquam semper lorem neque, nec euismod turpis mattis mollis. Quisque lobortis urna ultrices odio pretium, ac venenatis orci faucibus. Suspendisse bibendum odio ligula, sed lobortis massa pharetra nec. Donec turpis justo, iaculis at dictum ac, finibus eu libero. Maecenas quis porttitor mi, sit amet aliquet neque. - -Vivamus auctor vulputate ante, at egestas lorem. Donec eu risus in nulla mollis ultricies at et urna. Duis accumsan porta egestas. Ut vel euismod augue. Fusce convallis nulla ante, nec fringilla velit aliquet at. Nam malesuada dapibus ligula, a aliquam nibh scelerisque ac. Praesent malesuada neque et pellentesque interdum. Curabitur volutpat at turpis vitae tristique. Vivamus porttitor semper congue. Quisque suscipit lacus mi, rhoncus ultrices tortor auctor quis. Maecenas neque neque, molestie ac facilisis eget, luctus ac lorem. In ut odio ut lacus suscipit pulvinar vitae sed elit. Nulla imperdiet, sem quis euismod sagittis, dui erat luctus dolor, faucibus faucibus erat sem eget nunc. Nam accumsan placerat malesuada. Maecenas convallis finibus pulvinar. - -Cras at placerat tortor. Morbi facilisis auctor felis sit amet molestie. Donec sodales sed lorem vitae suscipit. Etiam fermentum pharetra ipsum, nec luctus orci gravida eu. Pellentesque gravida, est non condimentum tempus, mauris ligula molestie est, in congue dolor nisl vel sapien. Duis congue tempor augue, id rutrum eros porta dapibus. Etiam rutrum eget est eget vestibulum. Aenean mollis arcu vel consequat varius. Praesent at condimentum felis. Duis nec interdum nisl. Donec commodo lorem sed sapien scelerisque malesuada non eu urna. In blandit non ipsum at porta. Nam lobortis leo vitae dui auctor, non feugiat quam bibendum. Donec auctor lectus sagittis laoreet maximus. Maecenas rhoncus laoreet porttitor. Vestibulum porttitor augue ut lectus hendrerit, eget posuere mi gravida. - -Sed mattis ex in erat pulvinar, eu imperdiet magna dapibus. Etiam nisi nibh, tempus non tellus sit amet, mattis tempor odio. Quisque nec lorem feugiat, lobortis odio et, commodo nunc. Maecenas semper purus nisi, nec vehicula nibh eleifend vitae. Nulla fermentum a lectus at maximus. Phasellus finibus metus non euismod ultrices. Etiam a pulvinar ante. Quisque convallis nec metus sit amet facilisis. Praesent laoreet massa et sollicitudin laoreet. Vestibulum in mauris aliquet, convallis mi ut, elementum purus. Nulla purus nulla, sodales at hendrerit quis, tempus sed lectus. - -Nam ut laoreet neque, ut maximus nibh. Maecenas quis justo pellentesque, sollicitudin elit at, venenatis velit. Aenean nunc velit, vehicula scelerisque odio at, consectetur laoreet purus. Duis dui purus, malesuada quis ipsum sit amet, tempor interdum libero. Curabitur porta scelerisque sapien, vitae cursus diam condimentum eu. Phasellus sed orci quam. Nullam vitae dui quis purus tincidunt vestibulum. Curabitur quis nulla porta, cursus arcu non, auctor enim. Etiam sollicitudin ex id sem vehicula mollis. Morbi viverra laoreet tincidunt. Praesent ut semper dui. Nam sit amet pretium neque. Mauris vitae luctus diam, in lacinia purus. Maecenas ut placerat justo, ut porta felis. Integer eu mauris ante. - -Aenean porttitor tellus diam, tempor consequat metus efficitur id. Suspendisse ut felis at erat tempor dictum at nec sapien. Sed vestibulum interdum felis, ac mattis mauris porta in. Nunc et condimentum massa. Sed cursus dictum justo et luctus. Integer convallis enim nisl, a rutrum lectus ultricies in. Donec dapibus lacus at nulla dapibus, id sollicitudin velit hendrerit. Fusce a magna at orci mollis rutrum ac a dolor. Aliquam erat volutpat. Morbi varius porta nunc, sit amet sodales ex hendrerit commodo. Donec tincidunt tortor sapien, vitae egestas sapien vehicula eget. - -Suspendisse potenti. Donec pulvinar felis nec leo malesuada interdum. Integer posuere placerat maximus. Donec nibh ipsum, tincidunt vitae luctus vitae, bibendum at leo. Sed cursus nisl ut ex faucibus aliquet sed nec eros. Curabitur molestie posuere felis. Integer faucibus velit eget consequat iaculis. Mauris sed vulputate odio. Phasellus maximus, elit a pharetra egestas, lorem magna semper tellus, vestibulum semper diam felis at sapien. Suspendisse facilisis, nisl sit amet euismod vehicula, libero nulla vehicula dolor, quis fermentum nibh elit sit amet diam. - -Morbi lorem enim, euismod eu varius ut, scelerisque quis odio. Nam tempus vitae eros id molestie. Nunc pretium in nulla eget accumsan. Quisque mattis est ut semper aliquet. Maecenas eget diam elementum, fermentum ipsum a, euismod sapien. Duis quam ligula, cursus et velit nec, ullamcorper tincidunt magna. Donec vulputate nisl est, et ullamcorper urna tempor sit amet. - -Proin lacinia dui non turpis congue pretium. Morbi posuere metus vel purus imperdiet interdum. Morbi venenatis vel eros non ultricies. Nulla vel semper elit. Ut quis purus tincidunt, auctor justo ut, faucibus turpis. Proin quis mattis erat, at faucibus ligula. Mauris in mauris enim. Donec facilisis enim at est feugiat hendrerit. Nam vel nisi lorem. Fusce ultricies convallis diam, in feugiat tortor luctus quis. Donec tempor, leo vitae volutpat aliquam, magna elit feugiat leo, quis placerat sapien felis eget arcu. Donec ornare fermentum eleifend. Integer a est orci. - -Proin rhoncus egestas leo. Nulla ultricies porta elit quis ornare. Nunc fermentum interdum vehicula. In in ligula lorem. Donec nec arcu sit amet orci lobortis iaculis. Mauris at mollis erat, sit amet mollis tortor. Mauris laoreet justo ullamcorper porttitor auctor. Aenean sit amet aliquam lectus, id fermentum eros. Praesent urna sem, vehicula ac fermentum id, dapibus ut purus. Vestibulum vitae tempus nunc. Donec at nunc ornare metus volutpat porta at eget magna. Donec varius aliquet metus, eu lobortis risus aliquam sed. Ut dapibus fermentum velit, ac tincidunt libero faucibus at. - -In in purus auctor, feugiat massa quis, facilisis nisi. Donec dolor purus, gravida eget dolor ac, porttitor imperdiet urna. Donec faucibus placerat erat, a sagittis ante finibus ac. Sed venenatis dignissim elit, in iaculis felis posuere faucibus. Praesent sed viverra dolor. Mauris sed nulla consectetur nunc laoreet molestie in ut metus. Proin ac ex sit amet magna vulputate hendrerit ac condimentum urna. Proin ligula metus, gravida et sollicitudin facilisis, iaculis ut odio. Cras tincidunt urna et augue varius, ut facilisis urna consequat. Aenean vehicula finibus quam. Ut iaculis eu diam ac mollis. Nam mi lorem, tristique eget varius at, sodales at urna. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin vitae dictum erat, et auctor ipsum. Nullam nunc nunc, sollicitudin quis magna a, vestibulum fermentum mauris. Praesent at erat dolor. Proin laoreet tristique nulla vel efficitur. Nam sed ultrices nibh, id rutrum nunc. Curabitur eleifend a erat sit amet sollicitudin. Nullam metus quam, laoreet vitae dapibus id, placerat sed leo. Aliquam erat volutpat. Donec turpis nisl, cursus eu ex sit amet, lacinia pellentesque nisl. Sed id ipsum massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec interdum scelerisque lorem eu mattis. - -Vivamus ac tristique massa, nec facilisis nisl. Nam ipsum neque, tincidunt vel urna in, cursus imperdiet enim. Nam pellentesque egestas tempus. Morbi facilisis imperdiet libero vitae fringilla. Nam lacinia ligula at sapien facilisis malesuada. Nullam accumsan pulvinar sem, et cursus libero porta sit amet. Curabitur vulputate erat elit, ut pulvinar erat maximus vel. - -Cras aliquet metus ut purus sagittis, vel venenatis ante consectetur. Pellentesque nulla lacus, viverra viverra mattis non, placerat vitae nibh. Donec enim turpis, accumsan sit amet tincidunt eu, imperdiet non metus. Morbi ipsum eros, tincidunt vel est ac, tristique porttitor nibh. Praesent ut ullamcorper mauris. Sed laoreet sit amet diam congue venenatis. Integer porta purus nec orci sagittis posuere. - -Donec vehicula mauris eget lacus mollis venenatis et sed nibh. Nam sodales ligula ipsum, scelerisque lacinia ligula sagittis in. Nam sit amet ipsum at erat malesuada congue. Aenean ut sollicitudin sapien. Etiam at tempor odio. Mauris vitae purus ut magna suscipit consequat. Vivamus quis sapien neque. Nulla vulputate sem sit amet massa pellentesque, eleifend tristique ligula egestas. Suspendisse tincidunt gravida mi, in pulvinar lectus egestas non. Aenean imperdiet ex sit amet nunc sollicitudin porta. Integer justo odio, ultricies at interdum in, rhoncus vitae sem. Sed porttitor arcu quis purus aliquet hendrerit. Praesent tempor tortor at dolor dictum pulvinar. Nulla aliquet nunc non ligula scelerisque accumsan. Donec nulla justo, congue vitae massa in, faucibus hendrerit magna. Donec non egestas purus. - -¤¤¤åabc Vivamus iaculis, lacus efficitur faucibus porta, dui nulla facilisis ligula, ut sodales odio nunc id sapien. Cras viverra auctor ipsum, dapibus mattis neque dictum sed. Sed convallis fermentum molestie. Nulla facilisi turpis duis. \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_cp1252.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_cp1252.txt deleted file mode 100644 index f56b7cf1fcb..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_cp1252.txt +++ /dev/null @@ -1,283 +0,0 @@ -öäüß Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vulputate, ipsum quis interdum fermentum, lorem sem fermentum eros, vitae auctor neque lacus in nisi. Suspendisse potenti. Maecenas et scelerisque elit, in tincidunt quam. Sed eu tincidunt quam. Nullam justo ex, imperdiet a imperdiet et, fermentum sit amet eros. Aenean quis tempus sem. Pellentesque accumsan magna mi, ut mollis velit sagittis id. Etiam quis ipsum orci. Fusce purus ante, accumsan a lobortis at, venenatis eu nisl. Praesent ornare sed ante placerat accumsan. Suspendisse tempus dignissim fermentum. Nunc a leo ac lacus sodales iaculis eu vitae mi. In feugiat ante at massa finibus cursus. Suspendisse posuere fringilla ornare. Mauris elementum ac quam id convallis. Vestibulum non elit quis urna volutpat aliquam a eu lacus. - -Aliquam vestibulum imperdiet neque, suscipit aliquam elit ultrices bibendum. Suspendisse ultrices pulvinar cursus. Morbi risus nisi, cursus consequat rutrum vitae, molestie sed dui. Fusce posuere, augue quis dignissim aliquam, nisi ipsum porttitor ante, quis fringilla nisl turpis ac nisi. Nulla varius enim eget lorem vehicula gravida. Donec finibus malesuada leo nec semper. Proin ac enim eros. Vivamus non tincidunt nisi, vel tristique lorem. - -Nunc consequat ex id eros dignissim, id rutrum risus laoreet. Sed euismod non erat eu ultricies. Etiam vehicula gravida lacus ut porta. Vestibulum eu eros quis nunc aliquet luctus. Cras quis semper ligula. Nullam gravida vehicula quam sed porta. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In porta cursus vulputate. Quisque porta a nisi eget cursus. Aliquam risus leo, luctus ac magna in, efficitur cursus magna. In condimentum non mi id semper. Donec interdum ante eget commodo maximus. - -Vivamus sit amet vestibulum lectus. Fusce tincidunt mi sapien, dictum sollicitudin diam vulputate in. Integer fringilla consequat mollis. Cras aliquet consequat felis eget feugiat. Nunc tempor cursus arcu, vitae ornare nunc varius et. Vestibulum et tortor vel ante viverra porttitor. Nam at tortor ullamcorper, facilisis augue quis, tristique erat. Aenean ut euismod nibh. Quisque eu tincidunt est, nec euismod eros. - -Proin vehicula nibh non viverra egestas. Phasellus sem dolor, ultricies ac sagittis tristique, lacinia a purus. Vestibulum in ante eros. Pellentesque lacus nulla, tristique vitae interdum vel, malesuada ac diam. Aenean bibendum posuere turpis in accumsan. Ut est nulla, ullamcorper quis turpis at, viverra sagittis mauris. Sed in interdum purus. Praesent scelerisque nibh eget sem euismod, ut imperdiet mi venenatis. Vivamus pulvinar orci sed dapibus auctor. Nulla facilisi. Vestibulum tincidunt erat nec porttitor egestas. Mauris quis risus ante. Nulla facilisi. - -Aliquam ullamcorper ornare lobortis. Phasellus quis sem et ipsum mollis malesuada sed in ex. Ut aliquam ex eget metus finibus maximus. Proin suscipit mauris eu nibh lacinia, quis feugiat dui dapibus. Nam sed libero est. Aenean vulputate orci sit amet diam faucibus, eu sagittis sapien volutpat. Nam imperdiet felis turpis, at pretium odio pulvinar in. Sed vestibulum id eros nec ultricies. Sed quis aliquam tortor, vitae ullamcorper tellus. Donec egestas laoreet eros, id suscipit est rutrum nec. Sed auctor nulla eget metus aliquam, ut condimentum enim elementum. - -Aliquam suscipit non turpis sit amet bibendum. Fusce velit ligula, euismod et maximus at, luctus sed neque. Quisque pretium, nisl at ullamcorper finibus, lectus leo mattis sapien, vel euismod mauris diam ullamcorper ex. Nulla ut risus finibus, lacinia ligula at, auctor erat. Mauris consectetur sagittis ligula vel dapibus. Nullam libero libero, lobortis aliquam libero vel, venenatis ultricies leo. Duis porttitor, nibh congue fermentum posuere, erat libero pulvinar tortor, a pellentesque nunc ipsum vel sem. Nullam volutpat, eros sit amet facilisis consectetur, ipsum est vehicula massa, non vestibulum neque elit in mauris. Nunc hendrerit ipsum non enim bibendum, vitae rhoncus mi egestas. Etiam ullamcorper massa vel nisl sagittis, nec bibendum arcu malesuada. Aenean aliquet turpis justo, a consectetur arcu mollis convallis. Etiam tellus ipsum, ultricies vitae lorem et, ornare facilisis orci. Praesent fringilla justo urna, vel mollis neque pulvinar vestibulum. - -Donec non iaculis erat. Aliquam et mi sed nunc pulvinar ultricies in ut ipsum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent feugiat lacus ac dignissim semper. Phasellus vitae quam nisi. Morbi vel diam ultricies risus lobortis ornare. Fusce maximus et ligula quis iaculis. Sed congue ex eget felis convallis, sit amet hendrerit elit tempor. Donec vehicula blandit ante eget commodo. Vestibulum eleifend diam at feugiat euismod. Etiam magna tellus, dignissim eget fermentum vel, vestibulum vitae mauris. Nam accumsan et erat id sagittis. Donec lacinia, odio ut ornare ultricies, dolor velit accumsan tortor, non finibus erat tellus quis ligula. Nunc quis metus in leo volutpat ornare vulputate eu nisl. - -Donec quis viverra ex. Nullam id feugiat mauris, eu fringilla nulla. Vestibulum id maximus elit. Cras elementum elit sed felis lobortis, eget sagittis nisi hendrerit. Vivamus vitae elit neque. Donec vulputate lacus ut libero ultrices accumsan. Vivamus accumsan nulla orci, in dignissim est laoreet sagittis. Proin at commodo velit. Curabitur in velit felis. Aliquam erat volutpat. Sed consequat, nulla et cursus sodales, nisi lacus mattis risus, quis eleifend erat ex nec turpis. Sed suscipit ultrices lorem in hendrerit. - -Morbi vitae lacus nec libero ornare tempus eu et diam. Suspendisse magna ipsum, fermentum vel odio quis, molestie aliquam urna. Fusce mollis turpis a eros accumsan porttitor. Pellentesque rhoncus dolor sit amet magna rutrum, et dapibus justo tempor. Sed purus nisi, maximus vitae fringilla eu, molestie nec urna. Fusce malesuada finibus pretium. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec sed aliquet eros. Pellentesque luctus diam ante, eget euismod nisl aliquet eu. Sed accumsan elit purus, tempor varius ligula tempus nec. Curabitur ornare leo suscipit suscipit fermentum. Morbi eget nulla est. Maecenas faucibus interdum tristique. - -Etiam ut elit eros. Nulla pharetra suscipit molestie. Nulla facilisis bibendum nisl non molestie. Curabitur turpis lectus, facilisis vel diam non, vulputate ultrices mauris. Aenean placerat aliquam convallis. Suspendisse sed scelerisque tellus. Vivamus lacinia neque eget risus cursus suscipit. Proin consequat dolor vel neque tempor, eu aliquam sem scelerisque. Duis non eros a purus malesuada pharetra non et nulla. Suspendisse potenti. Mauris libero eros, finibus vel nulla id, sagittis dapibus ante. Proin iaculis sed nunc et cursus. - -Quisque accumsan lorem sit amet lorem aliquet euismod. Curabitur fermentum rutrum posuere. Etiam ultricies, sem id pellentesque suscipit, urna magna lacinia eros, quis efficitur risus nisl at lacus. Nulla quis lacus tortor. Mauris placerat ex in dolor tincidunt, vel aliquet nisi pretium. Cras iaculis risus vitae pellentesque aliquet. Quisque a enim imperdiet, ullamcorper arcu vitae, rutrum risus. Nullam consectetur libero at felis fringilla, nec congue nibh dignissim. Nam et lobortis felis, eu pellentesque ligula. Aenean facilisis, ligula non imperdiet maximus, massa orci gravida sapien, at sagittis lacus nisl in lacus. Nulla quis mauris luctus, scelerisque felis consequat, tempus risus. Fusce auctor nisl non nulla luctus molestie. Maecenas sapien nisl, auctor non dolor et, iaculis scelerisque lorem. Suspendisse egestas enim aliquet, accumsan mauris nec, posuere quam. Nulla iaculis dui dui, sit amet vestibulum erat ultricies ac. - -Cras eget dolor erat. Proin at nisl ut leo consectetur ultricies vel ut arcu. Nulla in felis malesuada, ullamcorper tortor et, convallis massa. Nunc urna justo, ornare in nibh vitae, hendrerit condimentum libero. Etiam vitae libero in purus venenatis fringilla. Nullam velit nulla, consequat ut turpis non, egestas hendrerit nibh. Duis tortor turpis, interdum non ante ac, cursus accumsan lectus. Cras pharetra bibendum augue quis dictum. Sed euismod vestibulum justo. Proin porta lobortis purus. Duis venenatis diam tortor, sit amet condimentum eros rhoncus a. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc at magna nec diam lobortis efficitur sit amet ut lacus. Nulla quis orci tortor. Pellentesque tempus velit a odio finibus porta. - -Proin feugiat mauris a tellus scelerisque convallis. Maecenas libero magna, blandit nec ultrices id, congue vel mi. Aliquam lacinia, quam vel condimentum convallis, tortor turpis aliquam odio, sed blandit libero lacus et eros. In eleifend iaculis magna ac finibus. Praesent auctor facilisis tellus in congue. Sed molestie lobortis dictum. Nam quis dignissim augue, vel euismod lorem. Curabitur posuere dapibus luctus. Donec ultricies dictum lectus, quis blandit arcu commodo ac. Aenean tincidunt ligula in nunc imperdiet dignissim. Curabitur egestas sollicitudin sapien ut semper. Aenean nec dignissim lacus. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec aliquam dictum vehicula. Donec tortor est, volutpat non nisi nec, varius gravida ex. Nunc vel tristique nunc, vitae mattis nisi. Nunc nec luctus ex, vitae tincidunt lectus. In hac habitasse platea dictumst. Curabitur lobortis ex eget tincidunt tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut a vehicula mi. - -Fusce eu libero finibus, interdum nulla a, placerat neque. Cras bibendum tempor libero nec feugiat. Cras ut sodales eros. Proin viverra, massa sit amet viverra egestas, neque nisl porta ex, sit amet hendrerit libero ligula vel urna. Mauris suscipit lacus id justo rhoncus suscipit. Etiam vel libero tellus. Maecenas non diam molestie, condimentum tellus a, bibendum enim. Mauris aliquet imperdiet tellus, eget sagittis dolor. Sed blandit in neque et luctus. Cras elementum sagittis nunc, vel mollis lorem euismod et. Donec posuere at lacus eget suscipit. - -Nulla nunc mi, pretium non massa vel, tempor semper magna. Nunc a leo pulvinar, tincidunt nunc at, dignissim mi. Aliquam erat volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut viverra nulla a nisl finibus, at hendrerit ligula ullamcorper. Donec a lorem semper, tempor magna et, lobortis libero. Mauris id sapien leo. Donec dignissim, quam vitae porttitor dignissim, quam justo mattis dui, vel consequat odio elit quis orci. Etiam nec pretium neque, sit amet pretium orci. Duis ac tortor venenatis, feugiat purus non, feugiat nunc. Proin scelerisque nisl in turpis aliquam vulputate. - -Praesent sed est semper, fringilla lorem vitae, tincidunt nibh. Cras eros metus, auctor at mauris sit amet, sodales semper orci. Nunc a ornare ex. Curabitur bibendum arcu congue urna vulputate egestas. Vestibulum finibus id risus et accumsan. Aenean ut volutpat tellus. Aenean tincidunt malesuada urna sit amet vestibulum. Mauris vel tellus dictum, varius lacus quis, dictum arcu. - -Aenean quis metus eu erat feugiat cursus vel at ligula. Proin dapibus sodales urna, id euismod lectus tempus id. Pellentesque ex ligula, convallis et erat vel, vulputate condimentum nisl. Pellentesque pharetra nulla quis massa eleifend hendrerit. Praesent sed massa ipsum. Maecenas vehicula dolor massa, id sodales urna faucibus et. Mauris ac quam non massa tincidunt feugiat et at lacus. Fusce libero massa, vulputate vel scelerisque non, mollis in leo. Ut sit amet ultricies odio. Suspendisse in sapien viverra, facilisis purus ut, pretium libero. - -Vivamus tristique pharetra molestie. Nam a volutpat purus. Praesent consequat gravida nisi, ac blandit nisi suscipit ut. Quisque posuere, ligula a ultrices laoreet, ligula nunc vulputate libero, ut rutrum erat odio tincidunt justo. Sed vitae leo at leo fringilla bibendum. Vestibulum ut augue nec dolor auctor accumsan. Praesent laoreet id eros pulvinar commodo. Suspendisse potenti. Ut pharetra, mauris vitae blandit fringilla, odio ante tincidunt lorem, sit amet tempor metus diam ut turpis. - -Praesent quis egestas arcu. Nullam at porta arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi vulputate ligula malesuada ligula luctus, vulputate tempus erat bibendum. Nunc ullamcorper non lectus at euismod. Etiam nibh felis, tincidunt a metus vel, pellentesque rhoncus neque. Etiam at diam in erat luctus interdum. Nunc vel ipsum pulvinar, sollicitudin lacus ac, tempus urna. Etiam vel lacinia sapien. Pellentesque sagittis velit vel mi efficitur iaculis. Integer euismod sit amet urna in sagittis. Cras eleifend ut nibh in facilisis. Donec et lacus vitae nunc placerat sodales. Nulla sed hendrerit ligula, at dapibus sapien. - -Praesent at iaculis ex. Curabitur est purus, cursus a faucibus quis, dictum id velit. Donec dignissim fringilla viverra. Nunc mauris felis, laoreet sit amet sagittis at, vestibulum in libero. Maecenas quis orci turpis. Quisque ut nibh vitae magna mollis consequat id at mauris. Aliquam eu odio eget nulla bibendum sodales. Quisque vel orci eleifend nisi pretium lacinia. Suspendisse eget risus eget mi volutpat molestie eget quis lacus. Duis nisi libero, tincidunt nec nulla id, faucibus cursus felis. - -Donec tempor eget risus pellentesque molestie. Phasellus porta neque vel arcu egestas, nec blandit velit fringilla. Nullam porta faucibus justo vitae laoreet. Pellentesque viverra id nunc eu varius. Nulla pulvinar lobortis iaculis. Etiam vestibulum odio nec velit tristique, a tristique nisi mattis. In sed fringilla orci, vitae efficitur odio. Quisque dui odio, ornare eget velit at, lacinia consequat libero. Quisque lectus nulla, aliquet eu leo in, porta rutrum diam. Donec nec mattis neque. Nam rutrum, odio ac eleifend bibendum, dolor arcu rutrum neque, eget porta elit tellus a lacus. Sed massa metus, sollicitudin et sapien eu, finibus tempus orci. Proin et sapien sit amet erat molestie interdum. In quis rutrum velit, faucibus ultrices tellus. - -Sed sagittis sed justo eget tincidunt. Maecenas ut leo sagittis, feugiat magna et, viverra velit. Maecenas ex arcu, feugiat at consequat vitae, auctor eu massa. Integer egestas, enim vitae maximus convallis, est lectus pretium mauris, ac posuere lectus nisl quis quam. Aliquam tempus laoreet mi, vitae dapibus dolor varius dapibus. Suspendisse potenti. Donec sit amet purus nec libero dapibus tristique. Pellentesque viverra bibendum ligula. Donec sed felis et ex lobortis laoreet. Phasellus a fringilla libero, vitae malesuada nulla. Pellentesque blandit mattis lacus, et blandit tortor laoreet consequat. Suspendisse libero nunc, viverra sed fermentum in, accumsan egestas arcu. Proin in placerat elit. Sed interdum imperdiet malesuada. Suspendisse aliquet quis mauris eget sollicitudin. - -Vivamus accumsan tellus non erat volutpat, quis dictum dolor feugiat. Praesent rutrum nunc ac est mollis cursus. Fusce semper volutpat dui ut egestas. Curabitur sit amet posuere massa. Cras tincidunt nulla et mi mollis imperdiet. Suspendisse scelerisque ex id sodales vulputate. In nunc augue, pharetra in placerat eu, mattis id tellus. Vivamus cursus efficitur vehicula. Nulla aliquet vehicula aliquet. - -Sed cursus tellus sed porta pulvinar. Sed vitae nisi neque. Nullam aliquet, lorem et efficitur scelerisque, arcu diam aliquam felis, sed pulvinar lorem odio et turpis. Praesent convallis pulvinar turpis eu iaculis. Aliquam nec gravida mi. Curabitur eu nibh tempor, blandit justo in, ultrices felis. Fusce placerat metus non mi sagittis rutrum. Morbi sed dui fringilla, sagittis mauris eget, imperdiet nunc. Phasellus hendrerit sem elit, id hendrerit libero auctor sit amet. Integer sodales elit sit amet consequat cursus. - -Nam semper est eget nunc mollis, in pellentesque lectus fringilla. In finibus vel diam id semper. Nunc mattis quis erat eu consectetur. In hac habitasse platea dictumst. Nullam et ipsum vestibulum ex pulvinar ultricies sit amet id velit. Aenean suscipit mi tortor, a lobortis magna viverra non. Nulla condimentum aliquet ante et ullamcorper. Pellentesque porttitor arcu a posuere tempus. Aenean lacus quam, imperdiet eu justo vitae, pretium efficitur ex. Duis id purus id magna rhoncus ultrices id eu risus. Nunc dignissim et libero id dictum. - -Quisque a tincidunt neque. Phasellus commodo mi sit amet tempor fringilla. Ut rhoncus, neque non porttitor elementum, libero nulla egestas augue, sed fringilla sapien felis ac velit. Phasellus viverra rhoncus mollis. Nam ullamcorper leo vel erat laoreet luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus semper a metus a cursus. Nulla sed orci egestas, efficitur purus ac, malesuada tellus. Aenean rutrum velit at tellus fermentum mollis. Aliquam eleifend euismod metus. - -In hac habitasse platea dictumst. Vestibulum volutpat neque vitae porttitor laoreet. Nam at tellus consequat, sodales quam in, pulvinar arcu. Maecenas varius convallis diam, ac lobortis tellus pellentesque quis. Maecenas eget augue massa. Nullam volutpat nibh ac justo rhoncus, ut iaculis tellus rutrum. Fusce efficitur efficitur libero quis condimentum. Curabitur congue neque non tincidunt tristique. Fusce eget tempor ex, at pellentesque odio. Praesent luctus dictum vestibulum. Etiam non orci nunc. Vivamus vitae laoreet purus, a lobortis velit. Curabitur tincidunt purus ac lectus elementum pellentesque. Quisque sed tincidunt est. - -Sed vel ultrices massa, vitae ultricies justo. Cras finibus mauris nec lacus tempus dignissim. Cras faucibus maximus velit, eget faucibus orci luctus vehicula. Nulla massa nunc, porta ac consequat eget, rhoncus non tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce sed maximus metus, vel imperdiet ipsum. Ut scelerisque lectus at blandit porttitor. Ut vulputate nunc pharetra, aliquet sapien ac, sollicitudin sapien. Aenean eget ante lorem. Nam accumsan venenatis tellus id dignissim. - -Curabitur fringilla, magna non maximus dapibus, nulla sapien vestibulum lectus, sit amet semper dolor neque vitae nisl. Nunc ultrices vehicula augue sed iaculis. Maecenas nec diam mollis, suscipit orci et, vestibulum ante. Pellentesque eu nisl tortor. Nunc eleifend, lacus quis volutpat volutpat, nisi mi molestie sem, quis mollis ipsum libero a tellus. Ut viverra dolor mattis convallis interdum. Sed tempus nisl at nunc scelerisque aliquet. Quisque tempor tempor lorem id feugiat. Nullam blandit lectus velit, vitae porta lacus tincidunt a. Vivamus sit amet arcu ultrices, tincidunt mi quis, viverra quam. Aenean fringilla libero elementum lorem semper, quis pulvinar eros gravida. Nullam sodales blandit mauris, sed fermentum velit fermentum sit amet. Donec malesuada mauris in augue sodales vulputate. Vestibulum gravida turpis id elit rhoncus dignissim. Integer non congue lorem, eu viverra orci. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec at dolor magna. Aliquam consectetur erat augue, id iaculis velit pharetra ac. Integer rutrum venenatis dignissim. Integer non sodales elit. Curabitur ut magna ut nibh feugiat aliquam ac ut risus. Morbi nibh quam, aliquam id placerat nec, vestibulum eget velit. Suspendisse at dignissim quam. Vivamus aliquet sem sed nisl volutpat, ut cursus orci ultrices. Aliquam ultrices lacinia enim, vitae aliquet neque. - -Quisque scelerisque finibus diam in mattis. Cras cursus auctor velit. Aliquam sem leo, fermentum et maximus et, molestie a libero. Aenean justo elit, rutrum a ornare id, egestas eget enim. Aenean auctor tristique erat. Curabitur condimentum libero lacus, nec consequat orci vestibulum sed. Fusce elit ligula, blandit vitae sapien vitae, dictum ultrices risus. Nam laoreet suscipit sapien, at interdum velit faucibus sit amet. Duis quis metus egestas lectus elementum posuere non nec libero. Aliquam a dolor bibendum, facilisis nunc a, maximus diam. Vestibulum suscipit tristique magna, non dignissim turpis sodales sed. Nunc ornare, velit ac facilisis fringilla, dolor mi consectetur lorem, vitae finibus erat justo suscipit urna. Maecenas sit amet eros erat. Nunc non arcu ornare, suscipit lorem eget, sodales mauris. Aliquam tincidunt, quam nec mollis lacinia, nisi orci fermentum libero, consequat eleifend lectus quam et sapien. Vestibulum a quam urna. - -Cras arcu leo, euismod ac ullamcorper at, faucibus sed massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus porttitor velit in enim interdum, non commodo metus ornare. Morbi vel lorem quis nisl luctus tristique quis vitae nisl. Suspendisse condimentum tortor enim, nec eleifend ipsum euismod et. Sed gravida quam ut tristique lacinia. Mauris eu interdum ipsum, ac ultrices odio. Nullam auctor tellus a risus porttitor vehicula. Nulla blandit euismod dictum. In pharetra, enim iaculis pulvinar interdum, dui nunc placerat nunc, sit amet pretium lectus nulla vitae quam. Phasellus quis enim sollicitudin, varius nulla id, ornare purus. Donec quam lacus, vestibulum quis nunc ac, mollis dictum nisi. Cras ut mollis elit. Maecenas ultrices ligula at risus faucibus scelerisque. Etiam vitae porttitor purus. Curabitur blandit lectus urna, ut hendrerit tortor feugiat ut. - -Phasellus fringilla, sapien pellentesque commodo pharetra, ante libero aliquam tellus, ut consectetur augue libero a sapien. Maecenas blandit luctus nisl eget aliquet. Maecenas vitae porta dolor, faucibus laoreet sapien. Suspendisse lobortis, ipsum sed vehicula aliquam, elit purus scelerisque dui, rutrum consectetur diam odio et lorem. In nec lacinia metus. Donec viverra libero est, vel bibendum erat condimentum quis. Donec feugiat purus leo. In laoreet vitae felis a porttitor. Mauris ullamcorper, lacus id condimentum suscipit, neque magna pellentesque arcu, eget cursus neque tellus id metus. Curabitur volutpat ac orci vel ultricies. - -Sed ut finibus erat. Sed diam purus, varius non tincidunt quis, ultrices sit amet ipsum. Donec et egestas nulla. Suspendisse placerat nisi at dui laoreet iaculis. Aliquam aliquet leo at augue faucibus molestie. Nullam lacus augue, hendrerit sed nisi eu, faucibus porta est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam ut leo aliquet sem fermentum rutrum quis ac justo. Integer placerat aliquam nisl ut sagittis. Proin erat orci, lobortis et sem eget, eleifend fringilla augue. Mauris varius laoreet arcu, sed tincidunt felis. Pellentesque venenatis lorem odio, id pulvinar velit molestie feugiat. Donec mattis lacus sed eleifend pulvinar. - -Sed condimentum ex in tincidunt hendrerit. Etiam eget risus lacinia, euismod nibh eu, pellentesque quam. Proin elit eros, convallis id mauris ac, bibendum ultrices lectus. Morbi venenatis, purus id fermentum consequat, nunc libero tincidunt ligula, non dictum ligula orci nec quam. Nulla nec ultrices lorem. Aenean maximus augue vel dictum pharetra. Etiam turpis urna, pellentesque quis malesuada eu, molestie faucibus felis. - -Vestibulum pharetra augue ut quam blandit congue in nec risus. Proin eu nibh eu dui eleifend porta vitae id lectus. Proin lacus nibh, lobortis sed ligula vitae, interdum lobortis erat. Suspendisse potenti. In sollicitudin quis sapien ut aliquet. Mauris ac nulla arcu. Fusce tristique justo quis lectus mollis, eu volutpat lectus finibus. Vivamus venenatis facilisis ex ut vestibulum. - -Etiam varius lobortis purus, in hendrerit elit tristique at. In tempus, augue vestibulum fermentum gravida, ligula tellus vulputate arcu, eu molestie ex sapien at purus. Vestibulum nec egestas metus. Duis pulvinar quam nec consequat interdum. Aenean non dapibus lacus. Aliquam sit amet aliquet nulla. Sed venenatis volutpat purus nec convallis. Phasellus aliquet semper sodales. Cras risus sapien, condimentum auctor urna a, pulvinar ornare nisl. Sed tincidunt felis elit, ut elementum est bibendum ac. Morbi interdum justo vel dui faucibus condimentum. - -Sed convallis eu sem at tincidunt. Nullam at auctor est, et ullamcorper ipsum. Pellentesque eget ante ante. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer euismod, sapien sed dapibus ornare, nibh enim maximus lacus, lacinia placerat urna quam quis felis. Morbi accumsan id nisl ut condimentum. Donec bibendum nisi est, sed volutpat lorem rhoncus in. Vestibulum ac lacinia nunc, eget volutpat magna. Integer aliquam pharetra ipsum, id placerat nunc volutpat quis. Etiam urna diam, rhoncus sit amet varius vel, euismod vel sem. Nullam vel molestie urna. Vivamus ornare erat at venenatis euismod. Suspendisse potenti. Fusce diam justo, tincidunt vel sem at, commodo faucibus nisl. Duis gravida efficitur diam, vel sagittis erat pulvinar ut. - -Quisque vel pharetra felis. Duis efficitur tortor dolor, vitae porttitor erat fermentum sed. Sed eu mi purus. Etiam dignissim tortor eu tempus molestie. Aenean pretium erat enim, in hendrerit ante hendrerit at. Sed ut risus vel nunc venenatis ultricies quis in lacus. Pellentesque vitae purus euismod, placerat risus non, ullamcorper augue. Quisque varius quam ligula, nec aliquet ex faucibus vitae. Quisque rhoncus sit amet leo tincidunt mattis. Cras id mauris eget purus pretium gravida sit amet eu augue. Aliquam dapibus odio augue, id lacinia velit pulvinar eu. - -Mauris fringilla, tellus nec pharetra iaculis, neque nisi ultrices massa, et tincidunt sem dui sed mi. Curabitur erat lorem, venenatis quis tempus lacinia, tempus sit amet nunc. Aliquam at neque ac metus commodo dictum quis vitae justo. Phasellus eget lacus tempus, blandit lorem vel, rutrum est. Aenean pharetra sem ut augue lobortis dignissim. Sed rhoncus at nulla id ultrices. Cras id condimentum felis. In suscipit luctus vulputate. Donec tincidunt lacus nec enim tincidunt sollicitudin ut quis enim. Nam at libero urna. Praesent sit amet massa vitae massa ullamcorper vehicula. - -Nullam bibendum augue ut turpis condimentum bibendum. Proin sit amet urna hendrerit, sodales tortor a, lobortis lectus. Integer sagittis velit turpis, et tincidunt nisi commodo eget. Duis tincidunt elit finibus accumsan cursus. Aenean dignissim scelerisque felis vel lacinia. Nunc lacinia maximus luctus. In hac habitasse platea dictumst. Vestibulum eget urna et enim tempor tempor. Nam feugiat, felis vel vestibulum tempus, orci justo viverra diam, id dapibus lorem justo in ligula. - -Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In ac pellentesque sem. Vestibulum lacinia magna dui, eu lacinia augue placerat et. Maecenas pulvinar congue est. Pellentesque commodo dui non pulvinar scelerisque. Etiam interdum est posuere sem bibendum, ac commodo magna dictum. Cras ipsum turpis, rhoncus nec posuere vitae, laoreet a arcu. Integer ac massa sit amet enim placerat lacinia sed ultrices arcu. Suspendisse sem nibh, luctus sit amet volutpat in, pellentesque eu metus. Ut gravida neque eget mi accumsan tempus. Nam sit amet aliquet nibh. - -Pellentesque a purus cursus nulla hendrerit congue quis et odio. Aenean hendrerit, leo ullamcorper sagittis hendrerit, erat dui molestie quam, sed condimentum lacus risus sed tellus. Morbi a dapibus lectus, ut feugiat ex. Phasellus pretium quam et sapien mollis, vel iaculis dui dignissim. Sed ullamcorper est turpis, a viverra lorem consectetur in. Aenean aliquet nibh non cursus rutrum. Suspendisse at tristique urna, id lobortis urna. In hac habitasse platea dictumst. Phasellus libero velit, rutrum sed tellus nec, dapibus tincidunt ligula. Quisque vel dui venenatis, consequat nisl ut, lacinia ipsum. Phasellus vitae magna pellentesque, lobortis est id, faucibus quam. Nam eleifend faucibus dui vel pellentesque. - -Etiam ut est non lacus tincidunt interdum. Maecenas sed massa urna. Quisque ut nibh tortor. Pellentesque felis ipsum, tempor finibus ipsum et, euismod pretium metus. Donec sit amet est ipsum. Quisque rhoncus justo non finibus elementum. Nulla nec lectus ac tortor placerat fringilla. Phasellus ac ultrices nunc, eu efficitur nisl. Nulla rhoncus nunc vitae ante dictum tincidunt. Nunc ultrices, massa sit amet malesuada dignissim, lectus lacus consequat sapien, non eleifend metus sem in eros. Phasellus mauris ante, dictum sit amet suscipit ac, rhoncus eget nisi. Phasellus at orci mollis, imperdiet neque eget, faucibus nulla. In at purus massa. Pellentesque quis rutrum lectus. - -Integer eu faucibus turpis, sit amet mollis massa. Vestibulum id nulla commodo, rutrum ipsum sed, semper ante. Phasellus condimentum orci nec nibh convallis, ac maximus orci ullamcorper. Maecenas vitae sollicitudin mi. Integer et finibus lectus, et condimentum ligula. Donec elementum tristique quam vitae dapibus. Morbi euismod ipsum in tristique ullamcorper. - -Duis fermentum non enim eu auctor. Quisque lacinia nibh vehicula nibh posuere, eu volutpat turpis facilisis. Ut ac faucibus nulla. Sed eleifend quis ex et pellentesque. Vestibulum sollicitudin in libero id fringilla. Phasellus dignissim purus consequat, condimentum dui sit amet, condimentum ante. Pellentesque ac consectetur massa, quis sagittis est. Nulla maximus tristique risus accumsan convallis. Curabitur imperdiet ac lacus a ultrices. Nulla facilisi. Sed quis quam quis lectus placerat lobortis vel sed turpis. In mollis dui id neque iaculis, ut aliquet tellus malesuada. Proin at luctus odio, vel blandit sapien. Praesent dignissim tortor vehicula libero fringilla, nec ultrices erat suscipit. Maecenas scelerisque purus in dapibus fermentum. - -Curabitur magna odio, mattis in tortor ut, porttitor congue est. Vestibulum mollis lacinia elementum. Fusce maximus erat vitae nunc rutrum lobortis. Integer ligula eros, auctor vel elit non, posuere luctus lacus. Maecenas quis auctor massa. Ut ipsum lacus, efficitur posuere euismod et, hendrerit efficitur est. Phasellus fringilla, quam id tincidunt pretium, nunc dui sollicitudin orci, eu dignissim nisi metus ut magna. Integer lobortis interdum dolor, non bibendum purus posuere et. Donec non lectus aliquet, pretium dolor eu, cursus massa. Sed ut dui sapien. In sed vestibulum massa. Pellentesque blandit, dui non sodales vehicula, orci metus mollis nunc, non pharetra ex tellus ac est. Mauris sagittis metus et fermentum pretium. Nulla facilisi. Quisque quis ante ut nulla placerat mattis ut quis nisi. - -Sed quis nulla ligula. Quisque dignissim ligula urna, sed aliquam purus semper at. Suspendisse potenti. Nunc massa lectus, pharetra vehicula arcu bibendum, imperdiet sodales ipsum. Nam ac sapien diam. Mauris iaculis fringilla mattis. Pellentesque tempus eros sit amet justo volutpat mollis. Phasellus ac turpis ipsum. Morbi vel ante elit. Aenean posuere quam consequat velit varius suscipit. Donec tempor quam ut nibh cursus efficitur. - -Morbi molestie dolor nec sem egestas suscipit. Etiam placerat pharetra lectus, et ullamcorper risus tristique in. Sed faucibus ullamcorper lectus eget fringilla. Maecenas malesuada hendrerit congue. Sed eget neque a erat placerat tincidunt. Aliquam vitae dignissim turpis. Fusce at placerat magna, a laoreet lectus. Maecenas a purus nec diam gravida fringilla. Nam malesuada euismod ante non vehicula. In faucibus bibendum leo, faucibus posuere nisl pretium quis. Fusce finibus bibendum finibus. Vestibulum eu justo maximus, hendrerit diam nec, dignissim sapien. Aenean dolor lacus, malesuada quis vestibulum ac, venenatis ac ipsum. Cras a est id nunc finibus facilisis. Cras lacinia neque et interdum vehicula. Suspendisse vulputate tellus elit, eget tempor dui finibus vel. - -Cras sed pretium odio. Proin hendrerit elementum felis in tincidunt. Nam sed turpis vel justo molestie accumsan condimentum eu nunc. Praesent lobortis euismod rhoncus. Nulla vitae euismod nibh, quis mattis mi. Fusce ultrices placerat porttitor. Duis sem ipsum, pellentesque sit amet odio a, molestie vulputate mauris. - -Duis blandit mollis ligula, sit amet mattis ligula finibus sit amet. Nunc a leo molestie, placerat diam et, vestibulum leo. Suspendisse facilisis neque purus, nec pellentesque ligula fermentum nec. Aenean malesuada mauris lorem, eu blandit arcu pulvinar quis. Duis laoreet urna lacus, non maximus arcu rutrum ultricies. Nulla augue dolor, suscipit eu mollis eu, aliquam condimentum diam. Ut semper orci luctus, pharetra turpis at, euismod mi. Nulla leo diam, finibus sit amet purus sed, maximus dictum lorem. Integer eu mi id turpis laoreet rhoncus. - -Integer a mauris tincidunt, finibus orci ut, pretium mauris. Nulla molestie nunc mi, id finibus lorem elementum sed. Proin quis laoreet ante. Integer nulla augue, commodo id molestie quis, rutrum ut turpis. Suspendisse et tortor turpis. Sed ut pharetra massa. Pellentesque elementum blandit sem, ut elementum tellus egestas a. Fusce eu purus nibh. - -Cras dignissim ligula scelerisque magna faucibus ullamcorper. Proin at condimentum risus, auctor malesuada quam. Nullam interdum interdum egestas. Nulla aliquam nisi vitae felis mollis dictum. Suspendisse dapibus consectetur tortor. Ut ut nisi non sem bibendum tincidunt. Vivamus suscipit leo quis gravida dignissim. - -Aliquam interdum, leo id vehicula mollis, eros eros rhoncus diam, non mollis ligula mi eu mauris. Sed ultrices vel velit sollicitudin tincidunt. Nunc auctor metus at ligula gravida elementum. Praesent interdum eu elit et mollis. Duis egestas quam sit amet velit dignissim consequat. Aliquam ac turpis nec nunc convallis sagittis. Fusce blandit, erat ac fringilla consectetur, dolor eros sodales leo, vel aliquet risus nisl et diam. Aliquam luctus felis vitae est eleifend euismod facilisis et lacus. Sed leo tellus, auctor eu arcu in, volutpat sagittis nisl. Pellentesque nisl ligula, placerat vel ullamcorper at, vulputate ac odio. Morbi ac faucibus orci, et tempus nulla. Proin rhoncus rutrum dolor, in venenatis mauris. Suspendisse a fermentum augue, non semper mi. Nunc eget pretium neque. Phasellus augue erat, feugiat ac aliquam congue, rutrum non sapien. Pellentesque ac diam gravida, consectetur felis at, ornare neque. - -Nullam interdum mattis sapien quis porttitor. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus aliquet rutrum ipsum id euismod. Maecenas consectetur massa et mi porta viverra. Nunc quam nibh, dignissim vitae maximus et, ullamcorper nec lorem. Nunc vitae justo dapibus, luctus lacus vitae, pretium elit. Maecenas et efficitur leo. Curabitur mauris lectus, placerat quis vehicula vitae, auctor ut urna. Quisque rhoncus pharetra luctus. In hac habitasse platea dictumst. Integer sit amet metus nec eros malesuada aliquam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi hendrerit mi ac leo aliquam, sit amet ultricies libero commodo. Mauris dapibus purus metus, sit amet viverra nibh imperdiet et. Nullam porta nulla tellus, quis vehicula diam imperdiet non. Vivamus enim massa, bibendum in fermentum in, ultrices at ex. - -Suspendisse fermentum id nibh eget accumsan. Duis dapibus bibendum erat ut sollicitudin. Aliquam nec felis risus. Pellentesque rhoncus ligula id sem maximus mollis sed nec massa. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ipsum ipsum, sodales sed enim id, convallis faucibus eros. Donec ultricies dictum tincidunt. Cras vitae nibh arcu. Pellentesque cursus, sapien nec consequat fermentum, ipsum ante suscipit dui, imperdiet hendrerit est nisl eu massa. Quisque vitae sem ligula. Aenean iaculis metus ut mauris interdum laoreet. Vivamus sed gravida dolor. - -Morbi nulla metus, porttitor sed eros sit amet, efficitur efficitur est. In vel nisl urna. Ut aliquet tellus at congue convallis. Phasellus imperdiet lobortis sollicitudin. Integer sodales, sem eu ultricies pharetra, erat erat porttitor odio, eget dapibus libero ipsum eget velit. Phasellus gravida nulla nisl, eu pharetra mi auctor vel. Sed blandit pharetra velit, ut egestas libero placerat non. Aliquam a interdum quam. Proin at tortor nec dui sollicitudin tempus sed vestibulum elit. Nunc non sollicitudin velit. - -Aenean consequat diam velit, sed rutrum tortor faucibus dictum. Quisque at semper augue. Duis ut est eget mi ornare bibendum id et ligula. Phasellus consequat tortor non leo pulvinar posuere. Proin vestibulum eleifend felis, in hendrerit tortor sollicitudin eu. Phasellus hendrerit, lacus vel laoreet interdum, dui tortor consequat justo, commodo ultricies arcu felis vitae enim. Vivamus eu sapien at leo suscipit rutrum eu at justo. Aenean et dolor a libero ullamcorper posuere. Integer laoreet placerat nisi in vulputate. Mauris laoreet eget risus sed cursus. Donec scelerisque neque a libero eleifend hendrerit. Nulla varius condimentum nunc sit amet fermentum. Aliquam lorem ex, varius nec mollis ut, ultrices in neque. Morbi sit amet porta leo. Integer iaculis fermentum lacus in vestibulum. - -Ut gravida, tellus ut maximus ultrices, erat est venenatis nisl, vitae pretium massa ex ac magna. Sed non purus eget ligula aliquet volutpat non quis arcu. Nam aliquam tincidunt risus, sit amet fringilla sapien vulputate ut. Mauris luctus suscipit pellentesque. Nunc porttitor dapibus ex quis tempus. Ut ullamcorper metus a eros vulputate, vitae viverra lectus convallis. Mauris semper imperdiet augue quis tincidunt. Integer porta pretium magna, sed cursus sem scelerisque sollicitudin. Nam efficitur, nibh pretium eleifend vestibulum, purus diam posuere sem, in egestas mauris augue sit amet urna. - -Vestibulum tincidunt euismod massa in congue. Duis interdum metus non laoreet fringilla. Donec at ligula congue, tincidunt nunc non, scelerisque nunc. Donec bibendum magna non est scelerisque feugiat at nec neque. Ut orci tortor, tempus eget massa non, dignissim faucibus dolor. Nam odio risus, accumsan pretium neque eget, accumsan dignissim dui. In ut neque auctor, scelerisque tellus sed, ullamcorper nisi. Suspendisse varius cursus quam at hendrerit. Vivamus elit libero, sagittis vitae sem ac, vulputate iaculis ligula. - -Sed lobortis laoreet purus sit amet rutrum. Pellentesque feugiat non leo vel lacinia. Quisque feugiat nisl a orci bibendum vestibulum. In et sollicitudin urna. Morbi a arcu ac metus faucibus tempus. Nam eu imperdiet sapien, suscipit mattis tortor. Aenean blandit ipsum nisi, a eleifend ligula euismod at. Integer tincidunt pharetra felis, mollis placerat mauris hendrerit at. Curabitur convallis, est sit amet luctus volutpat, massa lacus cursus augue, sed eleifend magna quam et risus. Aliquam lobortis tincidunt metus vitae porttitor. Suspendisse potenti. Aenean ullamcorper, neque id commodo luctus, nulla nunc lobortis quam, id dapibus neque dui nec mauris. Etiam quis lorem quis elit commodo ornare. Ut pharetra purus ultricies enim ultrices efficitur. Proin vehicula tincidunt molestie. Mauris et placerat sem. - -Aliquam erat volutpat. Suspendisse velit turpis, posuere ac lacus eu, lacinia laoreet velit. Sed interdum felis neque, id blandit sem malesuada sit amet. Ut sagittis justo erat, efficitur semper orci tempor sed. Donec enim massa, posuere varius lectus egestas, pellentesque posuere mi. Cras tincidunt ut libero sed mattis. Suspendisse quis magna et tellus posuere interdum vel at purus. Pellentesque fringilla tristique neque, id aliquet tellus ultricies non. Duis ut tellus vel odio lobortis vulputate. - -Integer at magna ac erat convallis vestibulum. Sed lobortis porttitor mauris. Fusce varius lorem et volutpat pulvinar. Aenean ac vulputate lectus, vitae consequat velit. Suspendisse ex dui, varius ut risus ut, dictum scelerisque sem. Vivamus urna orci, volutpat ut convallis ac, venenatis vitae urna. In hac habitasse platea dictumst. Etiam eu purus arcu. Aenean vulputate leo urna, vel tristique dui sagittis euismod. Suspendisse non tellus efficitur ante rhoncus volutpat at et sapien. - -Sed dapibus accumsan porttitor. Phasellus facilisis lectus finibus ligula dignissim, id pulvinar lectus feugiat. Nullam egestas commodo nisi posuere aliquet. Morbi sit amet tortor sagittis, rutrum dui nec, dapibus sapien. Sed posuere tortor tortor, interdum auctor magna varius vitae. Vestibulum id sagittis augue. Curabitur fermentum arcu sem, eu condimentum quam rutrum non. Phasellus rutrum nibh quis lectus rhoncus pretium. Curabitur dictum interdum elit. Vestibulum maximus sodales imperdiet. Mauris auctor nec purus sed venenatis. In in urna purus. - -Duis placerat molestie suscipit. Morbi a elit id purus efficitur consequat. Nunc ac commodo turpis. Etiam sit amet lacus a ipsum tempus venenatis sed vel nibh. Duis elementum aliquam mi sed tristique. Morbi ligula tortor, semper ac est vel, lobortis maximus erat. Curabitur ipsum felis, laoreet vel condimentum eget, ullamcorper sit amet mauris. Nulla facilisi. Nam at purus sed mi egestas placerat vitae vel magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse at dignissim diam. Phasellus consectetur eget neque vel viverra. Donec sollicitudin mattis dolor vel malesuada. Vivamus vehicula leo neque, vitae fermentum leo posuere et. Praesent dui est, finibus sit amet tristique quis, pharetra vel nibh. - -Duis nulla leo, accumsan eu odio eget, sagittis semper orci. Quisque ullamcorper ligula quam, commodo porttitor mauris ullamcorper eu. Cras varius sagittis felis in aliquam. Duis sodales risus ac justo vehicula, nec mattis diam lacinia. Cras eget lectus ipsum. Ut commodo, enim vitae malesuada hendrerit, ex dolor egestas lectus, sit amet hendrerit metus diam nec est. Vestibulum tortor metus, lobortis sit amet ante eget, tempor molestie lacus. In molestie et urna et semper. Mauris mollis, sem non hendrerit condimentum, sapien nisi cursus est, non suscipit quam justo non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam enim est, porta ac feugiat vitae, rutrum in lorem. Duis vehicula tortor ut posuere maximus. - -Nullam vestibulum non tellus sed commodo. Quisque mattis elit sit amet sapien sollicitudin, ut condimentum nisl congue. Aenean sagittis massa vel elit faucibus fermentum. Donec tincidunt nisi nec nisl sodales pellentesque. Mauris congue congue ligula ut suscipit. Vivamus velit tortor, tempor et gravida eget, fermentum sit amet ante. Nullam fringilla, lorem at ultrices cursus, urna neque ornare dolor, eu lacinia orci enim sed nibh. Ut a ullamcorper lectus, id mattis purus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean maximus sollicitudin posuere. Nunc at augue lacus. Aenean efficitur leo sit amet lacinia efficitur. - -Quisque venenatis quam mi, in pharetra odio vulputate eu. In vel nisl pulvinar, pulvinar ligula ut, sodales risus. Sed efficitur lectus at vestibulum tincidunt. Vestibulum eu ullamcorper elit. Fusce vestibulum magna enim, et tempor lacus posuere vitae. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer leo elit, luctus nec mattis sit amet, sollicitudin in turpis. - -Proin convallis venenatis leo, vitae tristique erat iaculis nec. Nulla facilisi. Duis porttitor, sapien et bibendum vulputate, sem libero sodales lacus, non malesuada felis erat ut libero. Nam non felis semper, finibus est a, mattis mauris. Praesent nec eros quam. Nulla hendrerit, augue consectetur eleifend ultricies, purus mi condimentum nulla, eget dapibus est nunc sed libero. Nullam elementum dui erat, vitae luctus libero sollicitudin et. Nulla odio magna, placerat in augue eu, dapibus imperdiet odio. Suspendisse imperdiet metus sit amet rhoncus dapibus. Cras at enim et urna vehicula cursus eu a mauris. Integer magna ante, eleifend ac placerat vitae, porta at nisi. Cras eget malesuada orci. Curabitur nunc est, vulputate id viverra et, dignissim sed odio. Curabitur non mattis sem. Sed bibendum, turpis vitae vehicula faucibus, nunc quam ultricies lectus, vitae viverra felis turpis at libero. - -Nullam ut egestas ligula. Proin hendrerit justo a lectus commodo venenatis. Nulla facilisi. Ut cursus lorem quis est bibendum condimentum. Aenean in tristique odio. Fusce tempor hendrerit ipsum. Curabitur mollis felis justo, quis dapibus erat auctor vel. Sed augue lectus, finibus ut urna quis, ullamcorper vestibulum dui. Etiam molestie aliquam tempor. Integer mattis sollicitudin erat, et tristique elit varius vel. Mauris a ex justo. - -Nam eros est, imperdiet non volutpat rutrum, pellentesque accumsan ligula. Duis sit amet turpis metus. Aenean in rhoncus metus, ac fringilla ex. Suspendisse condimentum egestas purus, ut pharetra odio vulputate vel. Duis tincidunt massa a placerat ultrices. Mauris ultricies nibh sit amet condimentum malesuada. Duis tincidunt id ipsum sed congue. - -Praesent eu ex augue. Nullam in porta ligula. In tincidunt accumsan arcu, in pellentesque magna tristique in. Mauris eleifend libero ac nisl viverra faucibus. Nam sollicitudin dolor in commodo hendrerit. Cras at orci metus. Ut quis laoreet orci. Vivamus ultrices leo pellentesque tempor aliquet. Maecenas ut eros vitae purus placerat vestibulum. Etiam vitae gravida dolor, quis rhoncus diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. - -Suspendisse fringilla lacinia sagittis. Integer tincidunt consectetur tristique. Morbi non orci convallis, congue sapien quis, vulputate nunc. Donec a libero vel magna elementum facilisis non quis mi. Mauris posuere tellus non ipsum ultrices elementum. Vivamus massa velit, facilisis quis placerat aliquet, aliquet nec leo. Praesent a maximus sem. Sed neque elit, feugiat vel quam non, molestie sagittis nunc. Etiam luctus nunc ac mauris scelerisque, nec rhoncus lacus convallis. Nunc pharetra, nunc ac pulvinar aliquam, ex ipsum euismod augue, nec porttitor lacus turpis vitae neque. Fusce bibendum odio id tortor faucibus pellentesque. Sed ac porta nibh, eu gravida erat. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam quis ullamcorper felis. Nulla mattis sagittis ante ac tincidunt. Integer ac felis efficitur, viverra libero et, facilisis ligula. Suspendisse a metus a massa rhoncus posuere. Phasellus suscipit ligula ut lacus facilisis, ac pellentesque ex tempor. Quisque consectetur massa mi, ac molestie libero dictum quis. Proin porttitor ligula quis erat tincidunt venenatis. Proin congue nunc sed elit gravida, nec consectetur lectus sodales. Etiam tincidunt convallis ipsum at vestibulum. Quisque maximus enim et mauris porttitor, et molestie magna tristique. Morbi vitae metus elit. Maecenas sed volutpat turpis. Aliquam vitae dolor vestibulum, elementum purus eget, dapibus nibh. Nullam egestas dui ac rutrum semper. - -Etiam hendrerit est metus, et condimentum metus aliquam ac. Pellentesque id neque id ipsum rhoncus vulputate. Aliquam erat nisl, posuere sit amet ligula ac, fermentum blandit felis. Vivamus fermentum mi risus, non lacinia purus viverra id. Aenean ac sapien consequat, finibus mauris nec, porta sem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed quis consectetur ex, dignissim bibendum nulla. Phasellus ac libero at quam vehicula euismod non eu leo. Phasellus a sapien augue. - -Maecenas ligula dui, bibendum vitae mauris et, auctor laoreet felis. Duis non libero a mi semper mattis. Quisque consequat luctus massa, quis tristique eros auctor feugiat. Maecenas sodales euismod neque vitae facilisis. Nullam laoreet imperdiet velit at pellentesque. Etiam massa odio, facilisis a consequat vitae, placerat vel magna. Nunc sagittis eros nec urna fringilla, pulvinar vestibulum nibh scelerisque. Sed magna metus, cursus eu consequat et, pharetra a est. Suspendisse elementum neque a dui malesuada lacinia. Donec sed ipsum volutpat, cursus urna id, ullamcorper arcu. Maecenas laoreet nisl eget velit egestas sollicitudin. Etiam nisl turpis, mollis id dignissim vitae, tristique vehicula ante. Maecenas eget placerat est, at rutrum augue. Vivamus faucibus lacinia ullamcorper. Sed pulvinar urna sodales ante sodales, at gravida leo dictum. - -Morbi maximus, quam a lobortis bibendum, enim felis varius elit, ac vehicula elit nisl ut lacus. Quisque ut arcu augue. Praesent id turpis quam. Sed sed arcu eros. Maecenas at cursus lorem, ac eleifend nisi. Fusce mattis felis at commodo pharetra. Praesent ac commodo ipsum. Quisque finibus et eros vitae tincidunt. In hac habitasse platea dictumst. Praesent purus ipsum, luctus lobortis ornare quis, auctor eget justo. Nam vel enim sollicitudin, faucibus tortor eu, sagittis eros. Ut nec consectetur erat. Donec ultricies malesuada ligula, a hendrerit sapien volutpat in. Maecenas sed enim vitae sapien pulvinar faucibus. - -Proin semper nunc nibh, non consequat neque ullamcorper vel. Maecenas lobortis sagittis blandit. Aenean et arcu ultricies turpis malesuada malesuada. Ut quam ex, laoreet ut blandit cursus, feugiat vitae dolor. Etiam ex lacus, scelerisque vel erat vel, efficitur tincidunt magna. Morbi tristique lacinia dolor, in egestas magna ultrices vitae. Integer ultrices leo ac tempus venenatis. Praesent ac porta tortor. Vivamus ornare blandit tristique. Nulla rutrum finibus pellentesque. In non dui elementum, fermentum ipsum vel, varius magna. Pellentesque euismod tortor risus, ac pellentesque nisl faucibus eget. - -Vivamus eu enim purus. Cras ultrices rutrum egestas. Sed mollis erat nibh, at posuere nisl luctus nec. Nunc vulputate, sapien id auctor molestie, nisi diam tristique ante, non convallis tellus nibh at orci. Morbi a posuere purus, in ullamcorper ligula. Etiam elementum sit amet dui imperdiet iaculis. Proin vitae tincidunt ipsum, sit amet placerat lectus. Curabitur commodo sapien quam, et accumsan lectus fringilla non. Nullam eget accumsan enim, ac pharetra mauris. Sed quis tristique velit, vitae commodo nisi. Duis turpis dui, maximus ut risus at, finibus consequat nunc. Maecenas sed est accumsan, aliquet diam in, facilisis risus. Curabitur vehicula rutrum auctor. Nam iaculis risus pulvinar maximus viverra. Nulla vel augue et ex sagittis blandit. - -Ut sem nulla, porta ac ante ac, posuere laoreet eros. Donec sodales posuere justo a auctor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras mollis at orci hendrerit porta. Nullam sodales tortor tortor, non lacinia diam finibus id. Duis libero orci, suscipit ac odio et, dictum consequat ipsum. Pellentesque eu ligula sagittis, volutpat eros at, lacinia lorem. Cras euismod tellus in iaculis tempor. Quisque accumsan, magna a congue venenatis, ante ipsum aliquam lectus, at egestas enim nunc at justo. Quisque sem purus, viverra ut tristique ut, maximus id enim. Etiam quis placerat sem. In sollicitudin, lacus eu rutrum mollis, nulla eros luctus elit, vel dapibus urna purus nec urna. Phasellus egestas massa quam, ac molestie erat hendrerit a. Praesent ultrices neque ut turpis molestie auctor. Etiam molestie placerat purus, et euismod erat aliquam in. Morbi id suscipit justo. - -Proin est ante, consequat at varius a, mattis quis felis. Sed accumsan nibh sit amet ipsum elementum posuere. Vestibulum bibendum id diam sit amet gravida. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi nec dolor vel ipsum dignissim hendrerit vel non ipsum. Praesent facilisis orci quis elit auctor lobortis. Phasellus cursus risus lectus, vel lobortis libero dapibus in. Quisque tristique tempus leo a pulvinar. Pellentesque a magna tincidunt, pellentesque massa nec, laoreet orci. Morbi congue ornare dolor quis commodo. Phasellus massa nisi, tincidunt at eros dictum, hendrerit lobortis urna. Maecenas porta, magna id mattis molestie, nibh tellus lobortis sem, eget tincidunt ipsum quam eu turpis. - -Ut gravida orci risus, vel rutrum mauris vehicula id. Etiam bibendum, neque a placerat condimentum, ex orci imperdiet lectus, quis dapibus arcu lacus eget lectus. Sed consequat non mi sit amet venenatis. Fusce vestibulum erat libero, eget hendrerit risus vulputate sollicitudin. Integer sed eleifend felis. Donec commodo, sem eu mattis placerat, urna odio aliquam tellus, et laoreet justo tellus eget erat. Fusce sed suscipit tortor. Nam hendrerit nibh ac nunc auctor lacinia. Pellentesque placerat condimentum ipsum, eget semper tortor hendrerit vel. Nullam non urna eu lacus pellentesque congue ut id eros. - -Nunc finibus leo in rhoncus tristique. Sed eu ipsum nec nisl egestas faucibus eget a felis. Pellentesque vitae nisi in nulla accumsan fermentum. Sed venenatis feugiat eleifend. Fusce porttitor varius placerat. Aliquam aliquet lacus sit amet mattis mollis. Sed vel nulla quis dolor suscipit vehicula ac viverra lorem. Duis viverra ipsum eget nulla ullamcorper fermentum. Mauris tincidunt arcu quis quam fringilla ornare. Donec et iaculis tortor. Nam ultricies libero vel ipsum aliquet efficitur. Morbi eget dolor aliquam, tempus sapien eget, viverra ante. Donec varius mollis ex, sed efficitur purus euismod interdum. Quisque vel sapien non neque tincidunt semper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. - -Suspendisse sit amet purus leo. Fusce lectus lorem, aliquam ac nulla eget, imperdiet ornare eros. Nullam sem augue, varius in nisi non, sollicitudin pellentesque ante. Etiam eu odio condimentum, tempor libero et, egestas arcu. Cras pellentesque eleifend aliquet. Pellentesque non blandit ligula. Ut congue viverra rhoncus. Phasellus mattis mi ac eros placerat, eu feugiat tellus ultrices. Aenean mollis laoreet libero eu imperdiet. Cras sed pulvinar mi, ac vehicula ligula. Vestibulum sit amet ex massa. In a egestas eros. - -Mauris pretium ipsum risus, venenatis cursus ante imperdiet id. Praesent eu turpis nec risus feugiat maximus ullamcorper ac lectus. Integer placerat at mi vel dapibus. Vestibulum fermentum turpis sit amet turpis viverra, id aliquet diam suscipit. Nam nec ex sed ante ullamcorper pharetra quis sit amet risus. Sed ac faucibus velit, id feugiat nibh. Nullam eget ipsum ex. Vivamus tincidunt non nunc non faucibus. Quisque bibendum viverra facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at nisi hendrerit quam suscipit egestas. Curabitur laoreet maximus ultricies. Duis ut tellus ac augue molestie dictum. - -Suspendisse rhoncus iaculis erat, ut ullamcorper est tristique eget. Donec auctor nec risus at gravida. Vivamus volutpat vulputate tellus, vel ultricies eros suscipit eget. Ut pulvinar id mi eu tempus. Morbi malesuada augue in dui varius, nec blandit neque vehicula. Donec ornare nec nisl in mollis. Morbi enim nisi, rhoncus nec est id, dapibus tempus urna. Ut id elit a felis vestibulum consectetur. Duis lectus quam, pharetra sit amet diam sed, posuere vestibulum erat. Fusce vitae maximus massa. Nullam id metus tempus, iaculis risus eu, lobortis urna. Quisque in congue urna. Pellentesque placerat neque in augue dapibus, non varius ex malesuada. Curabitur ut eleifend libero. Fusce vitae ligula luctus, fermentum enim vitae, ultrices erat. - -Sed viverra augue turpis, scelerisque egestas sapien mattis eu. Duis laoreet magna at ex pharetra dapibus. Praesent eget odio vel quam venenatis dictum. Nulla in sollicitudin dolor. Mauris lobortis nec eros vel rhoncus. Vestibulum porta viverra venenatis. Curabitur vel scelerisque quam, a egestas velit. Praesent volutpat tincidunt magna at laoreet. - -Cras nec lorem odio. Pellentesque quis dui urna. Praesent at tellus ac lectus scelerisque placerat nec eu risus. Vestibulum sit amet mattis ligula. Vivamus sed nisi at leo elementum accumsan at sit amet arcu. Aenean mattis tellus nec leo gravida, eget hendrerit nisl faucibus. Mauris pellentesque luctus condimentum. Maecenas pretium sapien nunc, eget commodo dolor maximus id. Mauris vestibulum accumsan massa a dictum. Phasellus interdum quam ligula, ut maximus diam blandit aliquam. Nunc vitae ex eu erat condimentum consectetur. Maecenas interdum condimentum volutpat. - -Donec et enim a libero rutrum laoreet. Praesent a condimentum sem, at tincidunt quam. In vel molestie risus. Sed urna dui, molestie vitae mollis laoreet, tempor quis lectus. Praesent vitae auctor est, et aliquet nunc. Curabitur vulputate blandit nulla, at gravida metus. Maecenas gravida dui eu iaculis tristique. Pellentesque posuere turpis nec auctor eleifend. Suspendisse bibendum diam eu tellus lobortis, et laoreet quam congue. In hac habitasse platea dictumst. Morbi dictum neque velit, eget rutrum eros ultrices sit amet. - -Phasellus fermentum risus pharetra consectetur bibendum. Donec magna tortor, lacinia vitae nibh quis, aliquet pretium lorem. Donec turpis nisi, pretium eu enim volutpat, mattis malesuada augue. Nullam vel tellus iaculis, sollicitudin elit eget, tincidunt lacus. Fusce elementum elementum felis et iaculis. Suspendisse porta eros nec neque malesuada, in malesuada ante sollicitudin. Vivamus bibendum viverra molestie. - -Integer feugiat, erat nec convallis aliquam, velit felis congue erat, molestie eleifend tellus erat in tellus. Nunc et justo purus. Donec egestas fermentum dui non feugiat. Quisque in sapien sagittis, gravida quam id, iaculis lectus. Cras sagittis rhoncus bibendum. Fusce quis metus in velit scelerisque tincidunt at non ipsum. Vivamus efficitur ante eu odio vulputate, vitae ultricies risus vehicula. Proin eget odio eu sem tincidunt feugiat vel id lorem. - -Vestibulum sit amet nulla dignissim, euismod mi in, fermentum tortor. Donec ut aliquet libero, lacinia accumsan velit. Donec et nulla quam. Nullam laoreet odio nec nunc imperdiet, a congue eros venenatis. Quisque nec tellus sit amet neque interdum posuere. Duis quis mi gravida, tincidunt diam convallis, ultricies augue. Mauris consequat risus non porttitor congue. Ut in ligula consequat, viverra nunc a, eleifend enim. Duis ligula urna, imperdiet nec facilisis et, ornare eu ex. Proin lobortis lectus a lobortis porttitor. Nulla leo metus, egestas eu libero sed, pretium faucibus felis. Vestibulum non sem tortor. Nam cursus est leo. Vivamus luctus enim odio, non interdum sem dapibus a. Aenean accumsan consequat lectus in imperdiet. - -Donec vehicula laoreet ipsum in posuere. Quisque vel quam imperdiet, sollicitudin nisi quis, suscipit velit. Morbi id sodales mauris. Curabitur tellus arcu, feugiat sed dui sit amet, sodales sagittis libero. Aenean vel suscipit metus, non placerat leo. Vestibulum quis nulla elit. Proin scelerisque non ante ut commodo. Interdum et malesuada fames ac ante ipsum primis in faucibus. - -Sed non urna dolor. Suspendisse convallis mi porta pulvinar ultrices. Suspendisse quam ipsum, hendrerit non scelerisque molestie, interdum dictum nunc. Morbi condimentum condimentum turpis eu luctus. Pellentesque sagittis sollicitudin odio, sed ultricies felis ornare sit amet. Sed ultrices ex leo, a tincidunt nisl gravida sed. Nullam ornare accumsan porta. Praesent consectetur id est nec sollicitudin. - -In hac habitasse platea dictumst. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sed ultrices nibh. Duis accumsan suscipit eros, a dictum odio tempus sit amet. Aenean imperdiet erat ac lacus finibus, scelerisque cursus massa imperdiet. Mauris molestie risus ut lacinia posuere. Nulla et sodales purus. Maecenas orci erat, placerat in tristique quis, placerat in mi. - -Donec sollicitudin pellentesque odio in feugiat. Morbi eu dolor ut mauris congue sollicitudin. Aliquam erat volutpat. Nulla id varius dui. Curabitur finibus urna ante, consectetur interdum nisi volutpat a. Quisque quis mi tristique, consequat tellus eget, rutrum sapien. Vivamus vitae tellus vulputate, rutrum ex eu, vulputate sem. Suspendisse viverra lorem tellus, vel interdum orci gravida quis. Ut laoreet arcu at mi ullamcorper finibus. Duis porta sagittis vestibulum. Sed commodo nisl vitae urna sollicitudin, nec lacinia est sodales. Curabitur imperdiet sodales dui sed iaculis. Sed ac tellus maximus, eleifend quam sit amet, feugiat elit. Aenean viverra, dui at mattis varius, est odio vestibulum sapien, sit amet mollis libero massa nec velit. Etiam quis sodales justo. - -Ut ultricies, sem eget sodales feugiat, nunc arcu congue elit, ac tempor justo massa nec purus. Maecenas enim nunc, pharetra eget dictum sit amet, tempus pellentesque velit. Suspendisse venenatis ligula in nulla mattis, et imperdiet ex tincidunt. Etiam vulputate, tellus et ultrices suscipit, enim velit laoreet massa, vitae congue odio enim ac urna. Morbi quam lorem, iaculis ac varius sagittis, euismod quis dolor. In ut dui eu purus feugiat consectetur. Vestibulum cursus velit quis lacus pellentesque iaculis. Cras in risus sed mauris porta rutrum. Nulla facilisi. Nullam eu bibendum est, non pellentesque lectus. Sed imperdiet feugiat lorem, quis convallis ante auctor in. Maecenas justo magna, scelerisque sit amet tellus eget, varius elementum risus. Duis placerat et quam sed varius. - -Duis nec nibh vitae nibh dignissim mollis quis sed felis. Curabitur vitae quam placerat, venenatis purus ut, euismod nisl. Curabitur porttitor nibh eu pulvinar ullamcorper. Suspendisse posuere nec ipsum ac dapibus. Cras convallis consectetur urna. Phasellus a nibh in dolor lacinia posuere id eget augue. In eu pharetra lorem, vitae cursus lacus. Aliquam tincidunt nibh lectus. Aenean facilisis ultricies posuere. Sed ut placerat orci. Curabitur scelerisque gravida blandit. Maecenas placerat ligula eget suscipit fringilla. Mauris a tortor justo. Aliquam hendrerit semper mollis. Phasellus et tincidunt libero. Etiam vel quam libero. - -Quisque aliquet tempor ex. Ut ante sem, vehicula at enim vel, gravida porta elit. Etiam vitae lacus a neque lobortis consectetur. Mauris sed interdum odio. Mauris elementum ex blandit tempor cursus. Integer in enim in leo viverra elementum. Fusce consectetur metus et sem rutrum, mattis euismod diam semper. Nunc sed ipsum vel urna consequat vehicula. Donec cursus pretium lorem, vestibulum pretium felis commodo sit amet. Nam blandit felis enim, eget gravida ex faucibus a. In nec neque massa. Etiam laoreet posuere ipsum. Praesent volutpat nunc dolor, ac vulputate magna facilisis non. Aenean congue turpis vel lectus sollicitudin tristique. Sed nec consequat purus, non vehicula quam. Etiam ultricies, est ac dictum tincidunt, turpis turpis pretium massa, a vulputate libero justo at nibh. - -Aliquam erat volutpat. Cras ultrices augue ac sollicitudin lobortis. Curabitur et aliquet purus. Duis feugiat semper facilisis. Phasellus lobortis cursus velit, a sollicitudin tortor. Nam feugiat sapien non dapibus condimentum. Morbi at mi bibendum, commodo quam at, laoreet enim. Integer eu ultrices enim. Sed vestibulum eu urna ut dictum. Curabitur at mattis leo, sed cursus massa. Aliquam porttitor, felis quis fermentum porttitor, justo velit feugiat nulla, eget condimentum sem dui ut sapien. - -In fringilla elit eu orci aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut eget fringilla tellus. Curabitur fermentum, mi et condimentum suscipit, elit neque bibendum dui, et hendrerit nunc metus id ipsum. Morbi placerat mi in hendrerit congue. Ut feugiat mauris eget scelerisque viverra. Vivamus sit amet erat dictum, sagittis lectus nec, pulvinar lorem. Sed non enim ac dui sollicitudin aliquet. Quisque ut lacus dolor. Fusce hendrerit malesuada euismod. Nulla faucibus vel mauris eu mollis. Mauris est diam, fringilla ac arcu feugiat, efficitur volutpat turpis. Aliquam venenatis cursus massa sed porttitor. Ut ac finibus enim, in tincidunt sapien. - -Nunc faucibus semper turpis a lacinia. Phasellus gravida, libero vel pulvinar ornare, ex sem tincidunt lectus, sit amet convallis augue risus at tortor. Quisque sit amet ipsum id nulla posuere vestibulum. Pellentesque scelerisque mauris vel leo viverra sodales. Nulla viverra aliquam ex, ut rutrum enim fermentum venenatis. Aenean eget dapibus ex, eget faucibus metus. Vestibulum volutpat leo in diam semper, eget porta magna suscipit. Sed sit amet nulla blandit, aliquam dolor ac, gravida velit. Sed vel velit viverra, maximus est id, convallis justo. - -Curabitur nulla ante, vulputate at libero vel, ullamcorper rutrum nibh. Pellentesque porttitor eu mauris id mattis. Duis vulputate augue elit, eget interdum justo pretium vel. Maecenas eu vulputate arcu, eget posuere purus. Suspendisse viverra a velit dictum eleifend. Suspendisse vitae dapibus diam. Donec vehicula justo in ante interdum, eu luctus diam placerat. Vivamus convallis ipsum eu orci suscipit, sed fermentum enim euismod. Maecenas faucibus elit vitae ex ornare tristique. Donec vestibulum nec elit sit amet porttitor. Aenean tempor lectus eget tortor hendrerit luctus. Nullam interdum vitae lectus vel feugiat. Cras in risus non magna consectetur lobortis. Sed faucibus enim quis gravida convallis. - -Phasellus eget massa sit amet libero ultrices suscipit. Vivamus at risus sapien. Nam mollis nunc eget velit dictum maximus. Sed pellentesque, nunc ac fringilla lacinia, quam enim mattis ex, sed euismod tortor metus eu neque. Ut mattis nisl ut lectus rhoncus, sodales bibendum eros porta. Nulla porttitor enim nec diam sagittis, eget porta velit efficitur. Vestibulum ultricies eros neque. Phasellus rutrum suscipit enim, in interdum ante gravida vitae. Sed in sagittis diam, non commodo velit. - -Morbi hendrerit odio orci, nec tincidunt odio rhoncus nec. Mauris neque velit, vehicula a lorem at, suscipit tristique dui. Sed finibus, nisl in mattis convallis, turpis neque sodales lacus, eu porta enim magna non diam. Nam commodo sodales risus consectetur malesuada. In eget elementum justo. Phasellus sit amet massa imperdiet, dapibus nunc sit amet, suscipit orci. Fusce condimentum laoreet feugiat. Ut ut viverra ante. Praesent bibendum interdum commodo. Nulla mollis nisi a est ornare volutpat. Sed at ligula eu nisi dapibus tempus. Proin cursus vestibulum justo, nec efficitur justo dignissim vel. Nunc quis maximus eros. - -Cras viverra, diam a tristique mattis, libero felis vulputate tellus, a ornare felis leo a dui. Nulla ante nulla, finibus ut tellus ut, blandit pharetra nibh. Proin eleifend fermentum ex, eget auctor libero vulputate in. Nullam ultricies, mauris placerat pretium placerat, leo urna lobortis leo, vel placerat arcu libero sed mauris. Aliquam mauris ligula, ornare at urna at, eleifend gravida ligula. Vestibulum consectetur ut nulla non scelerisque. Donec ornare, sem nec elementum aliquam, urna nulla bibendum metus, eu euismod dui ligula ac est. Fusce laoreet erat eu ex lobortis, quis bibendum ligula interdum. Sed vel mi erat. Vivamus id lacus ac enim mattis tempor. Nunc ultricies pellentesque enim sed euismod. Fusce tincidunt convallis elit quis aliquam. Mauris nulla ipsum, sollicitudin quis diam ac, feugiat volutpat tellus. In nibh nibh, vulputate quis tincidunt quis, pulvinar eget magna. Pellentesque quis finibus dolor. Suspendisse viverra vitae lectus non eleifend. - -Nunc ut orci et sapien maximus semper. Nulla dignissim sem urna, ac varius lectus ultricies id. Quisque aliquet pulvinar pretium. In ultricies molestie tellus vehicula porta. Nam enim lorem, aliquam eget ex et, hendrerit volutpat quam. Maecenas diam lacus, pellentesque eget tempus ac, pharetra eu elit. Donec vel eros a sem facilisis vulputate. Nullam ac nisi vulputate, laoreet nisl ac, eleifend sem. Nullam mi massa, rhoncus sed pharetra interdum, tincidunt eget nunc. Aliquam viverra mattis posuere. Mauris et dui sed nisl sollicitudin fermentum quis ut arcu. Nam placerat eget orci at tincidunt. Curabitur vel turpis metus. Phasellus nibh nulla, fermentum scelerisque sem vel, gravida tincidunt velit. Pellentesque vel quam tempor, finibus massa pellentesque, condimentum dui. - -Donec at mattis neque. Etiam velit diam, consequat auctor mauris id, hendrerit faucibus metus. Maecenas ullamcorper eros a est sodales, ac consectetur odio scelerisque. Donec leo metus, imperdiet at pellentesque vel, feugiat id erat. Suspendisse at magna enim. Vestibulum placerat sodales lorem id sollicitudin. Aenean at euismod ligula, eget mollis diam. Phasellus pulvinar, orci nec pretium condimentum, est erat facilisis purus, quis feugiat augue elit aliquam nulla. Aenean vitae tortor id risus congue tincidunt. Sed dolor enim, mattis a ullamcorper id, volutpat ac leo. - -Proin vehicula feugiat augue, id feugiat quam sodales quis. Donec et ultricies massa, a lacinia nulla. Duis aliquam augue ornare euismod viverra. Ut lectus risus, rutrum sit amet efficitur a, luctus nec nisl. Cras volutpat ullamcorper congue. Sed vitae odio metus. Phasellus aliquet euismod varius. - -Nullam sem ex, malesuada ut magna ut, pretium mollis arcu. Nam porttitor eros cursus mi lacinia faucibus. Suspendisse aliquet eleifend iaculis. Maecenas sit amet viverra tortor. Nunc a mollis risus. Etiam tempus dolor in tortor malesuada mattis. Ut tincidunt venenatis est sit amet dignissim. Vestibulum massa enim, tristique sed scelerisque eu, fringilla ac velit. Donec efficitur quis urna sit amet malesuada. Vestibulum consequat ac ligula in dapibus. Maecenas massa massa, molestie non posuere nec, elementum ut magna. In nisi erat, mollis non venenatis eu, faucibus in justo. Morbi gravida non ex non egestas. Pellentesque finibus laoreet diam, eu commodo augue congue vitae. - -Aenean sem mi, ullamcorper dapibus lobortis vitae, interdum tincidunt tortor. Vivamus eget vulputate libero. Ut bibendum posuere lectus, vel tincidunt tortor aliquet at. Phasellus malesuada orci et bibendum accumsan. Aliquam quis libero vel leo mollis porta. Sed sagittis leo ac lacus dictum, ac malesuada elit finibus. Suspendisse pharetra luctus commodo. Vivamus ultricies a odio non interdum. Vivamus scelerisque tincidunt turpis quis tempor. Pellentesque tortor ligula, varius non nunc eu, blandit sollicitudin neque. Nunc imperdiet, diam et tristique luctus, ipsum ex condimentum nunc, sit amet aliquam justo velit sed libero. Duis vel suscipit ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed tincidunt neque vel massa ultricies, id dictum leo consequat. Curabitur lobortis ultricies tellus, eget mattis nisl aliquam sit amet. - -Proin at suscipit justo. Vivamus ut vestibulum nisl. Pellentesque enim odio, pharetra non magna sed, efficitur auctor magna. Praesent tincidunt ante quis ante hendrerit viverra. Pellentesque vel ipsum id magna vulputate efficitur. Sed nec neque accumsan, pulvinar sapien quis, euismod mauris. Donec condimentum laoreet sapien quis gravida. Quisque sed mattis purus. Vestibulum placerat vel neque maximus scelerisque. - -Vestibulum mattis quam quis efficitur elementum. Duis dictum dolor ac scelerisque commodo. Fusce sollicitudin nisi sit amet dictum placerat. Suspendisse euismod pharetra eleifend. In eros nisl, porttitor sed mauris at, consectetur aliquet mauris. Donec euismod viverra neque sed fermentum. Phasellus libero magna, accumsan ut ultricies vitae, dignissim eget metus. Donec tellus turpis, interdum eget maximus nec, hendrerit eget massa. Curabitur auctor ligula in iaculis auctor. In ultrices quam suscipit cursus finibus. Aenean id mi at dolor interdum iaculis vitae ut lorem. Nullam sed nibh fringilla, lacinia odio nec, placerat erat. In dui libero, viverra ac viverra ac, pellentesque sit amet turpis. - -Nulla in enim ex. Sed feugiat est et consectetur venenatis. Cras varius facilisis dui vel convallis. Vestibulum et elit eget tellus feugiat pellentesque. In ut ante eu purus aliquet posuere. Nulla nec ornare sem, sed luctus lorem. Nam varius iaculis odio, eget faucibus nisl ullamcorper in. Sed eget cursus felis, nec efficitur nisi. - -Vivamus commodo et sem quis pulvinar. Pellentesque libero ante, venenatis vitae ligula sit amet, ornare sollicitudin nulla. Mauris eget tellus hendrerit, pulvinar metus quis, tempor nisi. Proin magna ex, laoreet sed tortor quis, varius fermentum enim. Integer eu dolor dictum, vulputate tortor et, aliquet ligula. Vestibulum vitae justo id mauris luctus sollicitudin. Suspendisse eget auctor neque, sodales egestas lorem. Vestibulum lacinia egestas metus vitae euismod. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus ex tellus, volutpat nec pulvinar sit amet, condimentum vitae dui. Curabitur vel felis sodales, lacinia nunc iaculis, ullamcorper augue. Pellentesque consequat dolor quis eros efficitur malesuada. Nulla ut malesuada lectus. - -Morbi et tristique ante. Aliquam erat volutpat. Vivamus vitae dui nec turpis pellentesque fermentum. Quisque eget velit massa. Pellentesque tristique aliquam nisl, eu sollicitudin justo venenatis sed. Duis eleifend sem eros, ut aliquam libero porttitor id. Sed non nunc consequat, rhoncus diam eu, commodo erat. Praesent fermentum in lectus id blandit. Donec quis ipsum at justo volutpat finibus. Nulla blandit justo nulla, at mollis lacus consequat eget. Aenean sollicitudin quis eros ut ullamcorper. - -Pellentesque venenatis nulla ut mi aliquet feugiat. Cras semper vel magna nec pharetra. Integer mattis felis et sapien commodo imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis quis luctus felis. Vestibulum justo nibh, aliquam non lectus vitae, molestie placerat justo. Donec lorem nibh, gravida sit amet hendrerit ac, maximus id ipsum. Nunc ac libero sodales risus eleifend sagittis. Phasellus est massa, lobortis elementum ex sed, scelerisque consectetur neque. Nunc faucibus neque id lorem malesuada, eget convallis ex mattis. - -Sed turpis tortor, fermentum non turpis id, posuere varius nibh. Donec iaculis lorem dui. Etiam eros ante, sodales eget venenatis at, consectetur eget risus. Curabitur non aliquam ante, a pretium justo. Maecenas tempor nisl tortor, vitae dictum nisi ultrices eu. Duis eget dui ultrices, porttitor lacus sed, lobortis purus. Quisque mattis elit nec neque sagittis, sed commodo leo blandit. Mauris sodales interdum eleifend. Vestibulum condimentum consectetur augue, id luctus diam convallis et. - -Nunc suscipit risus in justo accumsan, a placerat magna tincidunt. Proin a nisl ipsum. Sed libero dui, tristique in augue quis, auctor tristique risus. Sed porttitor ex augue, eu porta augue molestie a. Duis rhoncus purus libero, eu tempus turpis condimentum at. Sed mollis nisi id lectus placerat tincidunt. Maecenas non scelerisque elit, quis rutrum orci. Donec in tellus pharetra urna ornare lobortis. Phasellus id risus at nisi varius rutrum eu ut turpis. - -Duis dictum justo quis nisl porta, eget tincidunt magna suscipit. Sed velit massa, ullamcorper eu sodales ac, pretium a massa. Duis et rutrum tortor. Nulla accumsan hendrerit sapien, cursus volutpat eros egestas eget. Donec sollicitudin at ante quis sollicitudin. Aenean blandit feugiat diam, id feugiat eros faucibus eget. Donec viverra dolor vel justo scelerisque dignissim. Nulla semper sem nunc, rhoncus semper tellus ultricies sed. Duis in ornare diam. Donec vehicula feugiat varius. Maecenas ut suscipit est. Vivamus sem sem, finibus at dolor sit amet, euismod dapibus ligula. Vestibulum fringilla odio dapibus, congue massa eget, congue sem. Donec feugiat magna eget tortor lacinia scelerisque non et ipsum. - -Suspendisse potenti. Nunc convallis sollicitudin ex eget venenatis. Sed iaculis nibh ex, vel ornare ligula congue dignissim. Quisque sollicitudin dolor ac dui vestibulum, sit amet molestie nisi aliquet. Donec at risus felis. Aenean sollicitudin metus a feugiat porta. Aenean a tortor ut dolor cursus sagittis. Vivamus consectetur porttitor nunc in facilisis. Proin sit amet mi vel lectus consectetur ultrices. - -Sed cursus lectus vitae nunc tristique, nec commodo turpis dapibus. Pellentesque luctus ex id facilisis ornare. Morbi quis placerat dolor. Donec in lectus in arcu mattis porttitor ac sit amet metus. Cras congue mauris non risus sodales, vitae feugiat ipsum bibendum. Nulla venenatis urna sed libero elementum, a cursus lorem commodo. Mauris faucibus lobortis eros nec commodo. - -Nullam suscipit ligula ullamcorper lorem commodo blandit. Nulla porta nibh quis pulvinar placerat. Vivamus eu arcu justo. Vestibulum imperdiet est ut fermentum porttitor. Pellentesque consectetur libero in sapien efficitur scelerisque. Curabitur ac erat sit amet odio aliquet dignissim. Pellentesque mi sem, rhoncus et luctus at, porttitor rutrum lectus. Vestibulum sollicitudin sollicitudin suscipit. Aenean efficitur dolor non ultrices imperdiet. Donec vel sem ex. - -Sed convallis mauris aliquam rutrum cursus. Ut tempor porttitor sodales. Etiam eu risus ac augue gravida egestas et eu dolor. Proin id magna ex. Suspendisse quis lectus quis lorem ultricies tempus. Donec porttitor velit vitae tincidunt faucibus. Aliquam vitae semper nisi. Morbi ultrices, leo non pretium dapibus, dui libero pellentesque ex, vel placerat enim ante vitae dui. Nunc varius, sem sit amet sagittis lobortis, lectus odio scelerisque mauris, ut vestibulum orci magna quis neque. Sed id congue justo. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris congue nisi est, malesuada mollis elit tincidunt sed. Curabitur sed ex sit amet felis tristique elementum vitae vel nibh. - -Etiam mollis pretium lobortis. Mauris augue lacus, efficitur at lacus sed, mollis tincidunt lectus. Aliquam erat volutpat. Donec at euismod elit, et mattis felis. Sed id lobortis urna. Morbi imperdiet vestibulum leo, sed maximus leo blandit eu. Aliquam semper lorem neque, nec euismod turpis mattis mollis. Quisque lobortis urna ultrices odio pretium, ac venenatis orci faucibus. Suspendisse bibendum odio ligula, sed lobortis massa pharetra nec. Donec turpis justo, iaculis at dictum ac, finibus eu libero. Maecenas quis porttitor mi, sit amet aliquet neque. - -Vivamus auctor vulputate ante, at egestas lorem. Donec eu risus in nulla mollis ultricies at et urna. Duis accumsan porta egestas. Ut vel euismod augue. Fusce convallis nulla ante, nec fringilla velit aliquet at. Nam malesuada dapibus ligula, a aliquam nibh scelerisque ac. Praesent malesuada neque et pellentesque interdum. Curabitur volutpat at turpis vitae tristique. Vivamus porttitor semper congue. Quisque suscipit lacus mi, rhoncus ultrices tortor auctor quis. Maecenas neque neque, molestie ac facilisis eget, luctus ac lorem. In ut odio ut lacus suscipit pulvinar vitae sed elit. Nulla imperdiet, sem quis euismod sagittis, dui erat luctus dolor, faucibus faucibus erat sem eget nunc. Nam accumsan placerat malesuada. Maecenas convallis finibus pulvinar. - -Cras at placerat tortor. Morbi facilisis auctor felis sit amet molestie. Donec sodales sed lorem vitae suscipit. Etiam fermentum pharetra ipsum, nec luctus orci gravida eu. Pellentesque gravida, est non condimentum tempus, mauris ligula molestie est, in congue dolor nisl vel sapien. Duis congue tempor augue, id rutrum eros porta dapibus. Etiam rutrum eget est eget vestibulum. Aenean mollis arcu vel consequat varius. Praesent at condimentum felis. Duis nec interdum nisl. Donec commodo lorem sed sapien scelerisque malesuada non eu urna. In blandit non ipsum at porta. Nam lobortis leo vitae dui auctor, non feugiat quam bibendum. Donec auctor lectus sagittis laoreet maximus. Maecenas rhoncus laoreet porttitor. Vestibulum porttitor augue ut lectus hendrerit, eget posuere mi gravida. - -Sed mattis ex in erat pulvinar, eu imperdiet magna dapibus. Etiam nisi nibh, tempus non tellus sit amet, mattis tempor odio. Quisque nec lorem feugiat, lobortis odio et, commodo nunc. Maecenas semper purus nisi, nec vehicula nibh eleifend vitae. Nulla fermentum a lectus at maximus. Phasellus finibus metus non euismod ultrices. Etiam a pulvinar ante. Quisque convallis nec metus sit amet facilisis. Praesent laoreet massa et sollicitudin laoreet. Vestibulum in mauris aliquet, convallis mi ut, elementum purus. Nulla purus nulla, sodales at hendrerit quis, tempus sed lectus. - -Nam ut laoreet neque, ut maximus nibh. Maecenas quis justo pellentesque, sollicitudin elit at, venenatis velit. Aenean nunc velit, vehicula scelerisque odio at, consectetur laoreet purus. Duis dui purus, malesuada quis ipsum sit amet, tempor interdum libero. Curabitur porta scelerisque sapien, vitae cursus diam condimentum eu. Phasellus sed orci quam. Nullam vitae dui quis purus tincidunt vestibulum. Curabitur quis nulla porta, cursus arcu non, auctor enim. Etiam sollicitudin ex id sem vehicula mollis. Morbi viverra laoreet tincidunt. Praesent ut semper dui. Nam sit amet pretium neque. Mauris vitae luctus diam, in lacinia purus. Maecenas ut placerat justo, ut porta felis. Integer eu mauris ante. - -Aenean porttitor tellus diam, tempor consequat metus efficitur id. Suspendisse ut felis at erat tempor dictum at nec sapien. Sed vestibulum interdum felis, ac mattis mauris porta in. Nunc et condimentum massa. Sed cursus dictum justo et luctus. Integer convallis enim nisl, a rutrum lectus ultricies in. Donec dapibus lacus at nulla dapibus, id sollicitudin velit hendrerit. Fusce a magna at orci mollis rutrum ac a dolor. Aliquam erat volutpat. Morbi varius porta nunc, sit amet sodales ex hendrerit commodo. Donec tincidunt tortor sapien, vitae egestas sapien vehicula eget. - -Suspendisse potenti. Donec pulvinar felis nec leo malesuada interdum. Integer posuere placerat maximus. Donec nibh ipsum, tincidunt vitae luctus vitae, bibendum at leo. Sed cursus nisl ut ex faucibus aliquet sed nec eros. Curabitur molestie posuere felis. Integer faucibus velit eget consequat iaculis. Mauris sed vulputate odio. Phasellus maximus, elit a pharetra egestas, lorem magna semper tellus, vestibulum semper diam felis at sapien. Suspendisse facilisis, nisl sit amet euismod vehicula, libero nulla vehicula dolor, quis fermentum nibh elit sit amet diam. - -Morbi lorem enim, euismod eu varius ut, scelerisque quis odio. Nam tempus vitae eros id molestie. Nunc pretium in nulla eget accumsan. Quisque mattis est ut semper aliquet. Maecenas eget diam elementum, fermentum ipsum a, euismod sapien. Duis quam ligula, cursus et velit nec, ullamcorper tincidunt magna. Donec vulputate nisl est, et ullamcorper urna tempor sit amet. - -Proin lacinia dui non turpis congue pretium. Morbi posuere metus vel purus imperdiet interdum. Morbi venenatis vel eros non ultricies. Nulla vel semper elit. Ut quis purus tincidunt, auctor justo ut, faucibus turpis. Proin quis mattis erat, at faucibus ligula. Mauris in mauris enim. Donec facilisis enim at est feugiat hendrerit. Nam vel nisi lorem. Fusce ultricies convallis diam, in feugiat tortor luctus quis. Donec tempor, leo vitae volutpat aliquam, magna elit feugiat leo, quis placerat sapien felis eget arcu. Donec ornare fermentum eleifend. Integer a est orci. - -Proin rhoncus egestas leo. Nulla ultricies porta elit quis ornare. Nunc fermentum interdum vehicula. In in ligula lorem. Donec nec arcu sit amet orci lobortis iaculis. Mauris at mollis erat, sit amet mollis tortor. Mauris laoreet justo ullamcorper porttitor auctor. Aenean sit amet aliquam lectus, id fermentum eros. Praesent urna sem, vehicula ac fermentum id, dapibus ut purus. Vestibulum vitae tempus nunc. Donec at nunc ornare metus volutpat porta at eget magna. Donec varius aliquet metus, eu lobortis risus aliquam sed. Ut dapibus fermentum velit, ac tincidunt libero faucibus at. - -In in purus auctor, feugiat massa quis, facilisis nisi. Donec dolor purus, gravida eget dolor ac, porttitor imperdiet urna. Donec faucibus placerat erat, a sagittis ante finibus ac. Sed venenatis dignissim elit, in iaculis felis posuere faucibus. Praesent sed viverra dolor. Mauris sed nulla consectetur nunc laoreet molestie in ut metus. Proin ac ex sit amet magna vulputate hendrerit ac condimentum urna. Proin ligula metus, gravida et sollicitudin facilisis, iaculis ut odio. Cras tincidunt urna et augue varius, ut facilisis urna consequat. Aenean vehicula finibus quam. Ut iaculis eu diam ac mollis. Nam mi lorem, tristique eget varius at, sodales at urna. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin vitae dictum erat, et auctor ipsum. Nullam nunc nunc, sollicitudin quis magna a, vestibulum fermentum mauris. Praesent at erat dolor. Proin laoreet tristique nulla vel efficitur. Nam sed ultrices nibh, id rutrum nunc. Curabitur eleifend a erat sit amet sollicitudin. Nullam metus quam, laoreet vitae dapibus id, placerat sed leo. Aliquam erat volutpat. Donec turpis nisl, cursus eu ex sit amet, lacinia pellentesque nisl. Sed id ipsum massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec interdum scelerisque lorem eu mattis. - -Vivamus ac tristique massa, nec facilisis nisl. Nam ipsum neque, tincidunt vel urna in, cursus imperdiet enim. Nam pellentesque egestas tempus. Morbi facilisis imperdiet libero vitae fringilla. Nam lacinia ligula at sapien facilisis malesuada. Nullam accumsan pulvinar sem, et cursus libero porta sit amet. Curabitur vulputate erat elit, ut pulvinar erat maximus vel. - -Cras aliquet metus ut purus sagittis, vel venenatis ante consectetur. Pellentesque nulla lacus, viverra viverra mattis non, placerat vitae nibh. Donec enim turpis, accumsan sit amet tincidunt eu, imperdiet non metus. Morbi ipsum eros, tincidunt vel est ac, tristique porttitor nibh. Praesent ut ullamcorper mauris. Sed laoreet sit amet diam congue venenatis. Integer porta purus nec orci sagittis posuere. - -Donec vehicula mauris eget lacus mollis venenatis et sed nibh. Nam sodales ligula ipsum, scelerisque lacinia ligula sagittis in. Nam sit amet ipsum at erat malesuada congue. Aenean ut sollicitudin sapien. Etiam at tempor odio. Mauris vitae purus ut magna suscipit consequat. Vivamus quis sapien neque. Nulla vulputate sem sit amet massa pellentesque, eleifend tristique ligula egestas. Suspendisse tincidunt gravida mi, in pulvinar lectus egestas non. Aenean imperdiet ex sit amet nunc sollicitudin porta. Integer justo odio, ultricies at interdum in, rhoncus vitae sem. Sed porttitor arcu quis purus aliquet hendrerit. Praesent tempor tortor at dolor dictum pulvinar. Nulla aliquet nunc non ligula scelerisque accumsan. Donec nulla justo, congue vitae massa in, faucibus hendrerit magna. Donec non egestas purus. - -öäüß Vivamus iaculis, lacus efficitur faucibus porta, dui nulla facilisis ligula, ut sodales odio nunc id sapien. Cras viverra auctor ipsum, dapibus mattis neque dictum sed. Sed convallis fermentum molestie. Nulla facilisi turpis duis. \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_cp866.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_cp866.txt deleted file mode 100644 index b11625814d9..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_cp866.txt +++ /dev/null @@ -1,283 +0,0 @@ -€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯àáâãäåæçèéêëìíîï Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vulputate, ipsum quis interdum fermentum, lorem sem fermentum eros, vitae auctor neque lacus in nisi. Suspendisse potenti. Maecenas et scelerisque elit, in tincidunt quam. Sed eu tincidunt quam. Nullam justo ex, imperdiet a imperdiet et, fermentum sit amet eros. Aenean quis tempus sem. Pellentesque accumsan magna mi, ut mollis velit sagittis id. Etiam quis ipsum orci. Fusce purus ante, accumsan a lobortis at, venenatis eu nisl. Praesent ornare sed ante placerat accumsan. Suspendisse tempus dignissim fermentum. Nunc a leo ac lacus sodales iaculis eu vitae mi. In feugiat ante at massa finibus cursus. Suspendisse posuere fringilla ornare. Mauris elementum ac quam id convallis. Vestibulum non elit quis urna volutpat aliquam a eu lacus. - -Aliquam vestibulum imperdiet neque, suscipit aliquam elit ultrices bibendum. Suspendisse ultrices pulvinar cursus. Morbi risus nisi, cursus consequat rutrum vitae, molestie sed dui. Fusce posuere, augue quis dignissim aliquam, nisi ipsum porttitor ante, quis fringilla nisl turpis ac nisi. Nulla varius enim eget lorem vehicula gravida. Donec finibus malesuada leo nec semper. Proin ac enim eros. Vivamus non tincidunt nisi, vel tristique lorem. - -Nunc consequat ex id eros dignissim, id rutrum risus laoreet. Sed euismod non erat eu ultricies. Etiam vehicula gravida lacus ut porta. Vestibulum eu eros quis nunc aliquet luctus. Cras quis semper ligula. Nullam gravida vehicula quam sed porta. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In porta cursus vulputate. Quisque porta a nisi eget cursus. Aliquam risus leo, luctus ac magna in, efficitur cursus magna. In condimentum non mi id semper. Donec interdum ante eget commodo maximus. - -Vivamus sit amet vestibulum lectus. Fusce tincidunt mi sapien, dictum sollicitudin diam vulputate in. Integer fringilla consequat mollis. Cras aliquet consequat felis eget feugiat. Nunc tempor cursus arcu, vitae ornare nunc varius et. Vestibulum et tortor vel ante viverra porttitor. Nam at tortor ullamcorper, facilisis augue quis, tristique erat. Aenean ut euismod nibh. Quisque eu tincidunt est, nec euismod eros. - -Proin vehicula nibh non viverra egestas. Phasellus sem dolor, ultricies ac sagittis tristique, lacinia a purus. Vestibulum in ante eros. Pellentesque lacus nulla, tristique vitae interdum vel, malesuada ac diam. Aenean bibendum posuere turpis in accumsan. Ut est nulla, ullamcorper quis turpis at, viverra sagittis mauris. Sed in interdum purus. Praesent scelerisque nibh eget sem euismod, ut imperdiet mi venenatis. Vivamus pulvinar orci sed dapibus auctor. Nulla facilisi. Vestibulum tincidunt erat nec porttitor egestas. Mauris quis risus ante. Nulla facilisi. - -Aliquam ullamcorper ornare lobortis. Phasellus quis sem et ipsum mollis malesuada sed in ex. Ut aliquam ex eget metus finibus maximus. Proin suscipit mauris eu nibh lacinia, quis feugiat dui dapibus. Nam sed libero est. Aenean vulputate orci sit amet diam faucibus, eu sagittis sapien volutpat. Nam imperdiet felis turpis, at pretium odio pulvinar in. Sed vestibulum id eros nec ultricies. Sed quis aliquam tortor, vitae ullamcorper tellus. Donec egestas laoreet eros, id suscipit est rutrum nec. Sed auctor nulla eget metus aliquam, ut condimentum enim elementum. - -Aliquam suscipit non turpis sit amet bibendum. Fusce velit ligula, euismod et maximus at, luctus sed neque. Quisque pretium, nisl at ullamcorper finibus, lectus leo mattis sapien, vel euismod mauris diam ullamcorper ex. Nulla ut risus finibus, lacinia ligula at, auctor erat. Mauris consectetur sagittis ligula vel dapibus. Nullam libero libero, lobortis aliquam libero vel, venenatis ultricies leo. Duis porttitor, nibh congue fermentum posuere, erat libero pulvinar tortor, a pellentesque nunc ipsum vel sem. Nullam volutpat, eros sit amet facilisis consectetur, ipsum est vehicula massa, non vestibulum neque elit in mauris. Nunc hendrerit ipsum non enim bibendum, vitae rhoncus mi egestas. Etiam ullamcorper massa vel nisl sagittis, nec bibendum arcu malesuada. Aenean aliquet turpis justo, a consectetur arcu mollis convallis. Etiam tellus ipsum, ultricies vitae lorem et, ornare facilisis orci. Praesent fringilla justo urna, vel mollis neque pulvinar vestibulum. - -Donec non iaculis erat. Aliquam et mi sed nunc pulvinar ultricies in ut ipsum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent feugiat lacus ac dignissim semper. Phasellus vitae quam nisi. Morbi vel diam ultricies risus lobortis ornare. Fusce maximus et ligula quis iaculis. Sed congue ex eget felis convallis, sit amet hendrerit elit tempor. Donec vehicula blandit ante eget commodo. Vestibulum eleifend diam at feugiat euismod. Etiam magna tellus, dignissim eget fermentum vel, vestibulum vitae mauris. Nam accumsan et erat id sagittis. Donec lacinia, odio ut ornare ultricies, dolor velit accumsan tortor, non finibus erat tellus quis ligula. Nunc quis metus in leo volutpat ornare vulputate eu nisl. - -Donec quis viverra ex. Nullam id feugiat mauris, eu fringilla nulla. Vestibulum id maximus elit. Cras elementum elit sed felis lobortis, eget sagittis nisi hendrerit. Vivamus vitae elit neque. Donec vulputate lacus ut libero ultrices accumsan. Vivamus accumsan nulla orci, in dignissim est laoreet sagittis. Proin at commodo velit. Curabitur in velit felis. Aliquam erat volutpat. Sed consequat, nulla et cursus sodales, nisi lacus mattis risus, quis eleifend erat ex nec turpis. Sed suscipit ultrices lorem in hendrerit. - -Morbi vitae lacus nec libero ornare tempus eu et diam. Suspendisse magna ipsum, fermentum vel odio quis, molestie aliquam urna. Fusce mollis turpis a eros accumsan porttitor. Pellentesque rhoncus dolor sit amet magna rutrum, et dapibus justo tempor. Sed purus nisi, maximus vitae fringilla eu, molestie nec urna. Fusce malesuada finibus pretium. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec sed aliquet eros. Pellentesque luctus diam ante, eget euismod nisl aliquet eu. Sed accumsan elit purus, tempor varius ligula tempus nec. Curabitur ornare leo suscipit suscipit fermentum. Morbi eget nulla est. Maecenas faucibus interdum tristique. - -Etiam ut elit eros. Nulla pharetra suscipit molestie. Nulla facilisis bibendum nisl non molestie. Curabitur turpis lectus, facilisis vel diam non, vulputate ultrices mauris. Aenean placerat aliquam convallis. Suspendisse sed scelerisque tellus. Vivamus lacinia neque eget risus cursus suscipit. Proin consequat dolor vel neque tempor, eu aliquam sem scelerisque. Duis non eros a purus malesuada pharetra non et nulla. Suspendisse potenti. Mauris libero eros, finibus vel nulla id, sagittis dapibus ante. Proin iaculis sed nunc et cursus. - -Quisque accumsan lorem sit amet lorem aliquet euismod. Curabitur fermentum rutrum posuere. Etiam ultricies, sem id pellentesque suscipit, urna magna lacinia eros, quis efficitur risus nisl at lacus. Nulla quis lacus tortor. Mauris placerat ex in dolor tincidunt, vel aliquet nisi pretium. Cras iaculis risus vitae pellentesque aliquet. Quisque a enim imperdiet, ullamcorper arcu vitae, rutrum risus. Nullam consectetur libero at felis fringilla, nec congue nibh dignissim. Nam et lobortis felis, eu pellentesque ligula. Aenean facilisis, ligula non imperdiet maximus, massa orci gravida sapien, at sagittis lacus nisl in lacus. Nulla quis mauris luctus, scelerisque felis consequat, tempus risus. Fusce auctor nisl non nulla luctus molestie. Maecenas sapien nisl, auctor non dolor et, iaculis scelerisque lorem. Suspendisse egestas enim aliquet, accumsan mauris nec, posuere quam. Nulla iaculis dui dui, sit amet vestibulum erat ultricies ac. - -Cras eget dolor erat. Proin at nisl ut leo consectetur ultricies vel ut arcu. Nulla in felis malesuada, ullamcorper tortor et, convallis massa. Nunc urna justo, ornare in nibh vitae, hendrerit condimentum libero. Etiam vitae libero in purus venenatis fringilla. Nullam velit nulla, consequat ut turpis non, egestas hendrerit nibh. Duis tortor turpis, interdum non ante ac, cursus accumsan lectus. Cras pharetra bibendum augue quis dictum. Sed euismod vestibulum justo. Proin porta lobortis purus. Duis venenatis diam tortor, sit amet condimentum eros rhoncus a. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc at magna nec diam lobortis efficitur sit amet ut lacus. Nulla quis orci tortor. Pellentesque tempus velit a odio finibus porta. - -Proin feugiat mauris a tellus scelerisque convallis. Maecenas libero magna, blandit nec ultrices id, congue vel mi. Aliquam lacinia, quam vel condimentum convallis, tortor turpis aliquam odio, sed blandit libero lacus et eros. In eleifend iaculis magna ac finibus. Praesent auctor facilisis tellus in congue. Sed molestie lobortis dictum. Nam quis dignissim augue, vel euismod lorem. Curabitur posuere dapibus luctus. Donec ultricies dictum lectus, quis blandit arcu commodo ac. Aenean tincidunt ligula in nunc imperdiet dignissim. Curabitur egestas sollicitudin sapien ut semper. Aenean nec dignissim lacus. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec aliquam dictum vehicula. Donec tortor est, volutpat non nisi nec, varius gravida ex. Nunc vel tristique nunc, vitae mattis nisi. Nunc nec luctus ex, vitae tincidunt lectus. In hac habitasse platea dictumst. Curabitur lobortis ex eget tincidunt tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut a vehicula mi. - -Fusce eu libero finibus, interdum nulla a, placerat neque. Cras bibendum tempor libero nec feugiat. Cras ut sodales eros. Proin viverra, massa sit amet viverra egestas, neque nisl porta ex, sit amet hendrerit libero ligula vel urna. Mauris suscipit lacus id justo rhoncus suscipit. Etiam vel libero tellus. Maecenas non diam molestie, condimentum tellus a, bibendum enim. Mauris aliquet imperdiet tellus, eget sagittis dolor. Sed blandit in neque et luctus. Cras elementum sagittis nunc, vel mollis lorem euismod et. Donec posuere at lacus eget suscipit. - -Nulla nunc mi, pretium non massa vel, tempor semper magna. Nunc a leo pulvinar, tincidunt nunc at, dignissim mi. Aliquam erat volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut viverra nulla a nisl finibus, at hendrerit ligula ullamcorper. Donec a lorem semper, tempor magna et, lobortis libero. Mauris id sapien leo. Donec dignissim, quam vitae porttitor dignissim, quam justo mattis dui, vel consequat odio elit quis orci. Etiam nec pretium neque, sit amet pretium orci. Duis ac tortor venenatis, feugiat purus non, feugiat nunc. Proin scelerisque nisl in turpis aliquam vulputate. - -Praesent sed est semper, fringilla lorem vitae, tincidunt nibh. Cras eros metus, auctor at mauris sit amet, sodales semper orci. Nunc a ornare ex. Curabitur bibendum arcu congue urna vulputate egestas. Vestibulum finibus id risus et accumsan. Aenean ut volutpat tellus. Aenean tincidunt malesuada urna sit amet vestibulum. Mauris vel tellus dictum, varius lacus quis, dictum arcu. - -Aenean quis metus eu erat feugiat cursus vel at ligula. Proin dapibus sodales urna, id euismod lectus tempus id. Pellentesque ex ligula, convallis et erat vel, vulputate condimentum nisl. Pellentesque pharetra nulla quis massa eleifend hendrerit. Praesent sed massa ipsum. Maecenas vehicula dolor massa, id sodales urna faucibus et. Mauris ac quam non massa tincidunt feugiat et at lacus. Fusce libero massa, vulputate vel scelerisque non, mollis in leo. Ut sit amet ultricies odio. Suspendisse in sapien viverra, facilisis purus ut, pretium libero. - -Vivamus tristique pharetra molestie. Nam a volutpat purus. Praesent consequat gravida nisi, ac blandit nisi suscipit ut. Quisque posuere, ligula a ultrices laoreet, ligula nunc vulputate libero, ut rutrum erat odio tincidunt justo. Sed vitae leo at leo fringilla bibendum. Vestibulum ut augue nec dolor auctor accumsan. Praesent laoreet id eros pulvinar commodo. Suspendisse potenti. Ut pharetra, mauris vitae blandit fringilla, odio ante tincidunt lorem, sit amet tempor metus diam ut turpis. - -Praesent quis egestas arcu. Nullam at porta arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi vulputate ligula malesuada ligula luctus, vulputate tempus erat bibendum. Nunc ullamcorper non lectus at euismod. Etiam nibh felis, tincidunt a metus vel, pellentesque rhoncus neque. Etiam at diam in erat luctus interdum. Nunc vel ipsum pulvinar, sollicitudin lacus ac, tempus urna. Etiam vel lacinia sapien. Pellentesque sagittis velit vel mi efficitur iaculis. Integer euismod sit amet urna in sagittis. Cras eleifend ut nibh in facilisis. Donec et lacus vitae nunc placerat sodales. Nulla sed hendrerit ligula, at dapibus sapien. - -Praesent at iaculis ex. Curabitur est purus, cursus a faucibus quis, dictum id velit. Donec dignissim fringilla viverra. Nunc mauris felis, laoreet sit amet sagittis at, vestibulum in libero. Maecenas quis orci turpis. Quisque ut nibh vitae magna mollis consequat id at mauris. Aliquam eu odio eget nulla bibendum sodales. Quisque vel orci eleifend nisi pretium lacinia. Suspendisse eget risus eget mi volutpat molestie eget quis lacus. Duis nisi libero, tincidunt nec nulla id, faucibus cursus felis. - -Donec tempor eget risus pellentesque molestie. Phasellus porta neque vel arcu egestas, nec blandit velit fringilla. Nullam porta faucibus justo vitae laoreet. Pellentesque viverra id nunc eu varius. Nulla pulvinar lobortis iaculis. Etiam vestibulum odio nec velit tristique, a tristique nisi mattis. In sed fringilla orci, vitae efficitur odio. Quisque dui odio, ornare eget velit at, lacinia consequat libero. Quisque lectus nulla, aliquet eu leo in, porta rutrum diam. Donec nec mattis neque. Nam rutrum, odio ac eleifend bibendum, dolor arcu rutrum neque, eget porta elit tellus a lacus. Sed massa metus, sollicitudin et sapien eu, finibus tempus orci. Proin et sapien sit amet erat molestie interdum. In quis rutrum velit, faucibus ultrices tellus. - -Sed sagittis sed justo eget tincidunt. Maecenas ut leo sagittis, feugiat magna et, viverra velit. Maecenas ex arcu, feugiat at consequat vitae, auctor eu massa. Integer egestas, enim vitae maximus convallis, est lectus pretium mauris, ac posuere lectus nisl quis quam. Aliquam tempus laoreet mi, vitae dapibus dolor varius dapibus. Suspendisse potenti. Donec sit amet purus nec libero dapibus tristique. Pellentesque viverra bibendum ligula. Donec sed felis et ex lobortis laoreet. Phasellus a fringilla libero, vitae malesuada nulla. Pellentesque blandit mattis lacus, et blandit tortor laoreet consequat. Suspendisse libero nunc, viverra sed fermentum in, accumsan egestas arcu. Proin in placerat elit. Sed interdum imperdiet malesuada. Suspendisse aliquet quis mauris eget sollicitudin. - -Vivamus accumsan tellus non erat volutpat, quis dictum dolor feugiat. Praesent rutrum nunc ac est mollis cursus. Fusce semper volutpat dui ut egestas. Curabitur sit amet posuere massa. Cras tincidunt nulla et mi mollis imperdiet. Suspendisse scelerisque ex id sodales vulputate. In nunc augue, pharetra in placerat eu, mattis id tellus. Vivamus cursus efficitur vehicula. Nulla aliquet vehicula aliquet. - -Sed cursus tellus sed porta pulvinar. Sed vitae nisi neque. Nullam aliquet, lorem et efficitur scelerisque, arcu diam aliquam felis, sed pulvinar lorem odio et turpis. Praesent convallis pulvinar turpis eu iaculis. Aliquam nec gravida mi. Curabitur eu nibh tempor, blandit justo in, ultrices felis. Fusce placerat metus non mi sagittis rutrum. Morbi sed dui fringilla, sagittis mauris eget, imperdiet nunc. Phasellus hendrerit sem elit, id hendrerit libero auctor sit amet. Integer sodales elit sit amet consequat cursus. - -Nam semper est eget nunc mollis, in pellentesque lectus fringilla. In finibus vel diam id semper. Nunc mattis quis erat eu consectetur. In hac habitasse platea dictumst. Nullam et ipsum vestibulum ex pulvinar ultricies sit amet id velit. Aenean suscipit mi tortor, a lobortis magna viverra non. Nulla condimentum aliquet ante et ullamcorper. Pellentesque porttitor arcu a posuere tempus. Aenean lacus quam, imperdiet eu justo vitae, pretium efficitur ex. Duis id purus id magna rhoncus ultrices id eu risus. Nunc dignissim et libero id dictum. - -Quisque a tincidunt neque. Phasellus commodo mi sit amet tempor fringilla. Ut rhoncus, neque non porttitor elementum, libero nulla egestas augue, sed fringilla sapien felis ac velit. Phasellus viverra rhoncus mollis. Nam ullamcorper leo vel erat laoreet luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus semper a metus a cursus. Nulla sed orci egestas, efficitur purus ac, malesuada tellus. Aenean rutrum velit at tellus fermentum mollis. Aliquam eleifend euismod metus. - -In hac habitasse platea dictumst. Vestibulum volutpat neque vitae porttitor laoreet. Nam at tellus consequat, sodales quam in, pulvinar arcu. Maecenas varius convallis diam, ac lobortis tellus pellentesque quis. Maecenas eget augue massa. Nullam volutpat nibh ac justo rhoncus, ut iaculis tellus rutrum. Fusce efficitur efficitur libero quis condimentum. Curabitur congue neque non tincidunt tristique. Fusce eget tempor ex, at pellentesque odio. Praesent luctus dictum vestibulum. Etiam non orci nunc. Vivamus vitae laoreet purus, a lobortis velit. Curabitur tincidunt purus ac lectus elementum pellentesque. Quisque sed tincidunt est. - -Sed vel ultrices massa, vitae ultricies justo. Cras finibus mauris nec lacus tempus dignissim. Cras faucibus maximus velit, eget faucibus orci luctus vehicula. Nulla massa nunc, porta ac consequat eget, rhoncus non tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce sed maximus metus, vel imperdiet ipsum. Ut scelerisque lectus at blandit porttitor. Ut vulputate nunc pharetra, aliquet sapien ac, sollicitudin sapien. Aenean eget ante lorem. Nam accumsan venenatis tellus id dignissim. - -Curabitur fringilla, magna non maximus dapibus, nulla sapien vestibulum lectus, sit amet semper dolor neque vitae nisl. Nunc ultrices vehicula augue sed iaculis. Maecenas nec diam mollis, suscipit orci et, vestibulum ante. Pellentesque eu nisl tortor. Nunc eleifend, lacus quis volutpat volutpat, nisi mi molestie sem, quis mollis ipsum libero a tellus. Ut viverra dolor mattis convallis interdum. Sed tempus nisl at nunc scelerisque aliquet. Quisque tempor tempor lorem id feugiat. Nullam blandit lectus velit, vitae porta lacus tincidunt a. Vivamus sit amet arcu ultrices, tincidunt mi quis, viverra quam. Aenean fringilla libero elementum lorem semper, quis pulvinar eros gravida. Nullam sodales blandit mauris, sed fermentum velit fermentum sit amet. Donec malesuada mauris in augue sodales vulputate. Vestibulum gravida turpis id elit rhoncus dignissim. Integer non congue lorem, eu viverra orci. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec at dolor magna. Aliquam consectetur erat augue, id iaculis velit pharetra ac. Integer rutrum venenatis dignissim. Integer non sodales elit. Curabitur ut magna ut nibh feugiat aliquam ac ut risus. Morbi nibh quam, aliquam id placerat nec, vestibulum eget velit. Suspendisse at dignissim quam. Vivamus aliquet sem sed nisl volutpat, ut cursus orci ultrices. Aliquam ultrices lacinia enim, vitae aliquet neque. - -Quisque scelerisque finibus diam in mattis. Cras cursus auctor velit. Aliquam sem leo, fermentum et maximus et, molestie a libero. Aenean justo elit, rutrum a ornare id, egestas eget enim. Aenean auctor tristique erat. Curabitur condimentum libero lacus, nec consequat orci vestibulum sed. Fusce elit ligula, blandit vitae sapien vitae, dictum ultrices risus. Nam laoreet suscipit sapien, at interdum velit faucibus sit amet. Duis quis metus egestas lectus elementum posuere non nec libero. Aliquam a dolor bibendum, facilisis nunc a, maximus diam. Vestibulum suscipit tristique magna, non dignissim turpis sodales sed. Nunc ornare, velit ac facilisis fringilla, dolor mi consectetur lorem, vitae finibus erat justo suscipit urna. Maecenas sit amet eros erat. Nunc non arcu ornare, suscipit lorem eget, sodales mauris. Aliquam tincidunt, quam nec mollis lacinia, nisi orci fermentum libero, consequat eleifend lectus quam et sapien. Vestibulum a quam urna. - -Cras arcu leo, euismod ac ullamcorper at, faucibus sed massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus porttitor velit in enim interdum, non commodo metus ornare. Morbi vel lorem quis nisl luctus tristique quis vitae nisl. Suspendisse condimentum tortor enim, nec eleifend ipsum euismod et. Sed gravida quam ut tristique lacinia. Mauris eu interdum ipsum, ac ultrices odio. Nullam auctor tellus a risus porttitor vehicula. Nulla blandit euismod dictum. In pharetra, enim iaculis pulvinar interdum, dui nunc placerat nunc, sit amet pretium lectus nulla vitae quam. Phasellus quis enim sollicitudin, varius nulla id, ornare purus. Donec quam lacus, vestibulum quis nunc ac, mollis dictum nisi. Cras ut mollis elit. Maecenas ultrices ligula at risus faucibus scelerisque. Etiam vitae porttitor purus. Curabitur blandit lectus urna, ut hendrerit tortor feugiat ut. - -Phasellus fringilla, sapien pellentesque commodo pharetra, ante libero aliquam tellus, ut consectetur augue libero a sapien. Maecenas blandit luctus nisl eget aliquet. Maecenas vitae porta dolor, faucibus laoreet sapien. Suspendisse lobortis, ipsum sed vehicula aliquam, elit purus scelerisque dui, rutrum consectetur diam odio et lorem. In nec lacinia metus. Donec viverra libero est, vel bibendum erat condimentum quis. Donec feugiat purus leo. In laoreet vitae felis a porttitor. Mauris ullamcorper, lacus id condimentum suscipit, neque magna pellentesque arcu, eget cursus neque tellus id metus. Curabitur volutpat ac orci vel ultricies. - -Sed ut finibus erat. Sed diam purus, varius non tincidunt quis, ultrices sit amet ipsum. Donec et egestas nulla. Suspendisse placerat nisi at dui laoreet iaculis. Aliquam aliquet leo at augue faucibus molestie. Nullam lacus augue, hendrerit sed nisi eu, faucibus porta est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam ut leo aliquet sem fermentum rutrum quis ac justo. Integer placerat aliquam nisl ut sagittis. Proin erat orci, lobortis et sem eget, eleifend fringilla augue. Mauris varius laoreet arcu, sed tincidunt felis. Pellentesque venenatis lorem odio, id pulvinar velit molestie feugiat. Donec mattis lacus sed eleifend pulvinar. - -Sed condimentum ex in tincidunt hendrerit. Etiam eget risus lacinia, euismod nibh eu, pellentesque quam. Proin elit eros, convallis id mauris ac, bibendum ultrices lectus. Morbi venenatis, purus id fermentum consequat, nunc libero tincidunt ligula, non dictum ligula orci nec quam. Nulla nec ultrices lorem. Aenean maximus augue vel dictum pharetra. Etiam turpis urna, pellentesque quis malesuada eu, molestie faucibus felis. - -Vestibulum pharetra augue ut quam blandit congue in nec risus. Proin eu nibh eu dui eleifend porta vitae id lectus. Proin lacus nibh, lobortis sed ligula vitae, interdum lobortis erat. Suspendisse potenti. In sollicitudin quis sapien ut aliquet. Mauris ac nulla arcu. Fusce tristique justo quis lectus mollis, eu volutpat lectus finibus. Vivamus venenatis facilisis ex ut vestibulum. - -Etiam varius lobortis purus, in hendrerit elit tristique at. In tempus, augue vestibulum fermentum gravida, ligula tellus vulputate arcu, eu molestie ex sapien at purus. Vestibulum nec egestas metus. Duis pulvinar quam nec consequat interdum. Aenean non dapibus lacus. Aliquam sit amet aliquet nulla. Sed venenatis volutpat purus nec convallis. Phasellus aliquet semper sodales. Cras risus sapien, condimentum auctor urna a, pulvinar ornare nisl. Sed tincidunt felis elit, ut elementum est bibendum ac. Morbi interdum justo vel dui faucibus condimentum. - -Sed convallis eu sem at tincidunt. Nullam at auctor est, et ullamcorper ipsum. Pellentesque eget ante ante. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer euismod, sapien sed dapibus ornare, nibh enim maximus lacus, lacinia placerat urna quam quis felis. Morbi accumsan id nisl ut condimentum. Donec bibendum nisi est, sed volutpat lorem rhoncus in. Vestibulum ac lacinia nunc, eget volutpat magna. Integer aliquam pharetra ipsum, id placerat nunc volutpat quis. Etiam urna diam, rhoncus sit amet varius vel, euismod vel sem. Nullam vel molestie urna. Vivamus ornare erat at venenatis euismod. Suspendisse potenti. Fusce diam justo, tincidunt vel sem at, commodo faucibus nisl. Duis gravida efficitur diam, vel sagittis erat pulvinar ut. - -Quisque vel pharetra felis. Duis efficitur tortor dolor, vitae porttitor erat fermentum sed. Sed eu mi purus. Etiam dignissim tortor eu tempus molestie. Aenean pretium erat enim, in hendrerit ante hendrerit at. Sed ut risus vel nunc venenatis ultricies quis in lacus. Pellentesque vitae purus euismod, placerat risus non, ullamcorper augue. Quisque varius quam ligula, nec aliquet ex faucibus vitae. Quisque rhoncus sit amet leo tincidunt mattis. Cras id mauris eget purus pretium gravida sit amet eu augue. Aliquam dapibus odio augue, id lacinia velit pulvinar eu. - -Mauris fringilla, tellus nec pharetra iaculis, neque nisi ultrices massa, et tincidunt sem dui sed mi. Curabitur erat lorem, venenatis quis tempus lacinia, tempus sit amet nunc. Aliquam at neque ac metus commodo dictum quis vitae justo. Phasellus eget lacus tempus, blandit lorem vel, rutrum est. Aenean pharetra sem ut augue lobortis dignissim. Sed rhoncus at nulla id ultrices. Cras id condimentum felis. In suscipit luctus vulputate. Donec tincidunt lacus nec enim tincidunt sollicitudin ut quis enim. Nam at libero urna. Praesent sit amet massa vitae massa ullamcorper vehicula. - -Nullam bibendum augue ut turpis condimentum bibendum. Proin sit amet urna hendrerit, sodales tortor a, lobortis lectus. Integer sagittis velit turpis, et tincidunt nisi commodo eget. Duis tincidunt elit finibus accumsan cursus. Aenean dignissim scelerisque felis vel lacinia. Nunc lacinia maximus luctus. In hac habitasse platea dictumst. Vestibulum eget urna et enim tempor tempor. Nam feugiat, felis vel vestibulum tempus, orci justo viverra diam, id dapibus lorem justo in ligula. - -Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In ac pellentesque sem. Vestibulum lacinia magna dui, eu lacinia augue placerat et. Maecenas pulvinar congue est. Pellentesque commodo dui non pulvinar scelerisque. Etiam interdum est posuere sem bibendum, ac commodo magna dictum. Cras ipsum turpis, rhoncus nec posuere vitae, laoreet a arcu. Integer ac massa sit amet enim placerat lacinia sed ultrices arcu. Suspendisse sem nibh, luctus sit amet volutpat in, pellentesque eu metus. Ut gravida neque eget mi accumsan tempus. Nam sit amet aliquet nibh. - -Pellentesque a purus cursus nulla hendrerit congue quis et odio. Aenean hendrerit, leo ullamcorper sagittis hendrerit, erat dui molestie quam, sed condimentum lacus risus sed tellus. Morbi a dapibus lectus, ut feugiat ex. Phasellus pretium quam et sapien mollis, vel iaculis dui dignissim. Sed ullamcorper est turpis, a viverra lorem consectetur in. Aenean aliquet nibh non cursus rutrum. Suspendisse at tristique urna, id lobortis urna. In hac habitasse platea dictumst. Phasellus libero velit, rutrum sed tellus nec, dapibus tincidunt ligula. Quisque vel dui venenatis, consequat nisl ut, lacinia ipsum. Phasellus vitae magna pellentesque, lobortis est id, faucibus quam. Nam eleifend faucibus dui vel pellentesque. - -Etiam ut est non lacus tincidunt interdum. Maecenas sed massa urna. Quisque ut nibh tortor. Pellentesque felis ipsum, tempor finibus ipsum et, euismod pretium metus. Donec sit amet est ipsum. Quisque rhoncus justo non finibus elementum. Nulla nec lectus ac tortor placerat fringilla. Phasellus ac ultrices nunc, eu efficitur nisl. Nulla rhoncus nunc vitae ante dictum tincidunt. Nunc ultrices, massa sit amet malesuada dignissim, lectus lacus consequat sapien, non eleifend metus sem in eros. Phasellus mauris ante, dictum sit amet suscipit ac, rhoncus eget nisi. Phasellus at orci mollis, imperdiet neque eget, faucibus nulla. In at purus massa. Pellentesque quis rutrum lectus. - -Integer eu faucibus turpis, sit amet mollis massa. Vestibulum id nulla commodo, rutrum ipsum sed, semper ante. Phasellus condimentum orci nec nibh convallis, ac maximus orci ullamcorper. Maecenas vitae sollicitudin mi. Integer et finibus lectus, et condimentum ligula. Donec elementum tristique quam vitae dapibus. Morbi euismod ipsum in tristique ullamcorper. - -Duis fermentum non enim eu auctor. Quisque lacinia nibh vehicula nibh posuere, eu volutpat turpis facilisis. Ut ac faucibus nulla. Sed eleifend quis ex et pellentesque. Vestibulum sollicitudin in libero id fringilla. Phasellus dignissim purus consequat, condimentum dui sit amet, condimentum ante. Pellentesque ac consectetur massa, quis sagittis est. Nulla maximus tristique risus accumsan convallis. Curabitur imperdiet ac lacus a ultrices. Nulla facilisi. Sed quis quam quis lectus placerat lobortis vel sed turpis. In mollis dui id neque iaculis, ut aliquet tellus malesuada. Proin at luctus odio, vel blandit sapien. Praesent dignissim tortor vehicula libero fringilla, nec ultrices erat suscipit. Maecenas scelerisque purus in dapibus fermentum. - -Curabitur magna odio, mattis in tortor ut, porttitor congue est. Vestibulum mollis lacinia elementum. Fusce maximus erat vitae nunc rutrum lobortis. Integer ligula eros, auctor vel elit non, posuere luctus lacus. Maecenas quis auctor massa. Ut ipsum lacus, efficitur posuere euismod et, hendrerit efficitur est. Phasellus fringilla, quam id tincidunt pretium, nunc dui sollicitudin orci, eu dignissim nisi metus ut magna. Integer lobortis interdum dolor, non bibendum purus posuere et. Donec non lectus aliquet, pretium dolor eu, cursus massa. Sed ut dui sapien. In sed vestibulum massa. Pellentesque blandit, dui non sodales vehicula, orci metus mollis nunc, non pharetra ex tellus ac est. Mauris sagittis metus et fermentum pretium. Nulla facilisi. Quisque quis ante ut nulla placerat mattis ut quis nisi. - -Sed quis nulla ligula. Quisque dignissim ligula urna, sed aliquam purus semper at. Suspendisse potenti. Nunc massa lectus, pharetra vehicula arcu bibendum, imperdiet sodales ipsum. Nam ac sapien diam. Mauris iaculis fringilla mattis. Pellentesque tempus eros sit amet justo volutpat mollis. Phasellus ac turpis ipsum. Morbi vel ante elit. Aenean posuere quam consequat velit varius suscipit. Donec tempor quam ut nibh cursus efficitur. - -Morbi molestie dolor nec sem egestas suscipit. Etiam placerat pharetra lectus, et ullamcorper risus tristique in. Sed faucibus ullamcorper lectus eget fringilla. Maecenas malesuada hendrerit congue. Sed eget neque a erat placerat tincidunt. Aliquam vitae dignissim turpis. Fusce at placerat magna, a laoreet lectus. Maecenas a purus nec diam gravida fringilla. Nam malesuada euismod ante non vehicula. In faucibus bibendum leo, faucibus posuere nisl pretium quis. Fusce finibus bibendum finibus. Vestibulum eu justo maximus, hendrerit diam nec, dignissim sapien. Aenean dolor lacus, malesuada quis vestibulum ac, venenatis ac ipsum. Cras a est id nunc finibus facilisis. Cras lacinia neque et interdum vehicula. Suspendisse vulputate tellus elit, eget tempor dui finibus vel. - -Cras sed pretium odio. Proin hendrerit elementum felis in tincidunt. Nam sed turpis vel justo molestie accumsan condimentum eu nunc. Praesent lobortis euismod rhoncus. Nulla vitae euismod nibh, quis mattis mi. Fusce ultrices placerat porttitor. Duis sem ipsum, pellentesque sit amet odio a, molestie vulputate mauris. - -Duis blandit mollis ligula, sit amet mattis ligula finibus sit amet. Nunc a leo molestie, placerat diam et, vestibulum leo. Suspendisse facilisis neque purus, nec pellentesque ligula fermentum nec. Aenean malesuada mauris lorem, eu blandit arcu pulvinar quis. Duis laoreet urna lacus, non maximus arcu rutrum ultricies. Nulla augue dolor, suscipit eu mollis eu, aliquam condimentum diam. Ut semper orci luctus, pharetra turpis at, euismod mi. Nulla leo diam, finibus sit amet purus sed, maximus dictum lorem. Integer eu mi id turpis laoreet rhoncus. - -Integer a mauris tincidunt, finibus orci ut, pretium mauris. Nulla molestie nunc mi, id finibus lorem elementum sed. Proin quis laoreet ante. Integer nulla augue, commodo id molestie quis, rutrum ut turpis. Suspendisse et tortor turpis. Sed ut pharetra massa. Pellentesque elementum blandit sem, ut elementum tellus egestas a. Fusce eu purus nibh. - -Cras dignissim ligula scelerisque magna faucibus ullamcorper. Proin at condimentum risus, auctor malesuada quam. Nullam interdum interdum egestas. Nulla aliquam nisi vitae felis mollis dictum. Suspendisse dapibus consectetur tortor. Ut ut nisi non sem bibendum tincidunt. Vivamus suscipit leo quis gravida dignissim. - -Aliquam interdum, leo id vehicula mollis, eros eros rhoncus diam, non mollis ligula mi eu mauris. Sed ultrices vel velit sollicitudin tincidunt. Nunc auctor metus at ligula gravida elementum. Praesent interdum eu elit et mollis. Duis egestas quam sit amet velit dignissim consequat. Aliquam ac turpis nec nunc convallis sagittis. Fusce blandit, erat ac fringilla consectetur, dolor eros sodales leo, vel aliquet risus nisl et diam. Aliquam luctus felis vitae est eleifend euismod facilisis et lacus. Sed leo tellus, auctor eu arcu in, volutpat sagittis nisl. Pellentesque nisl ligula, placerat vel ullamcorper at, vulputate ac odio. Morbi ac faucibus orci, et tempus nulla. Proin rhoncus rutrum dolor, in venenatis mauris. Suspendisse a fermentum augue, non semper mi. Nunc eget pretium neque. Phasellus augue erat, feugiat ac aliquam congue, rutrum non sapien. Pellentesque ac diam gravida, consectetur felis at, ornare neque. - -Nullam interdum mattis sapien quis porttitor. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus aliquet rutrum ipsum id euismod. Maecenas consectetur massa et mi porta viverra. Nunc quam nibh, dignissim vitae maximus et, ullamcorper nec lorem. Nunc vitae justo dapibus, luctus lacus vitae, pretium elit. Maecenas et efficitur leo. Curabitur mauris lectus, placerat quis vehicula vitae, auctor ut urna. Quisque rhoncus pharetra luctus. In hac habitasse platea dictumst. Integer sit amet metus nec eros malesuada aliquam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi hendrerit mi ac leo aliquam, sit amet ultricies libero commodo. Mauris dapibus purus metus, sit amet viverra nibh imperdiet et. Nullam porta nulla tellus, quis vehicula diam imperdiet non. Vivamus enim massa, bibendum in fermentum in, ultrices at ex. - -Suspendisse fermentum id nibh eget accumsan. Duis dapibus bibendum erat ut sollicitudin. Aliquam nec felis risus. Pellentesque rhoncus ligula id sem maximus mollis sed nec massa. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ipsum ipsum, sodales sed enim id, convallis faucibus eros. Donec ultricies dictum tincidunt. Cras vitae nibh arcu. Pellentesque cursus, sapien nec consequat fermentum, ipsum ante suscipit dui, imperdiet hendrerit est nisl eu massa. Quisque vitae sem ligula. Aenean iaculis metus ut mauris interdum laoreet. Vivamus sed gravida dolor. - -Morbi nulla metus, porttitor sed eros sit amet, efficitur efficitur est. In vel nisl urna. Ut aliquet tellus at congue convallis. Phasellus imperdiet lobortis sollicitudin. Integer sodales, sem eu ultricies pharetra, erat erat porttitor odio, eget dapibus libero ipsum eget velit. Phasellus gravida nulla nisl, eu pharetra mi auctor vel. Sed blandit pharetra velit, ut egestas libero placerat non. Aliquam a interdum quam. Proin at tortor nec dui sollicitudin tempus sed vestibulum elit. Nunc non sollicitudin velit. - -Aenean consequat diam velit, sed rutrum tortor faucibus dictum. Quisque at semper augue. Duis ut est eget mi ornare bibendum id et ligula. Phasellus consequat tortor non leo pulvinar posuere. Proin vestibulum eleifend felis, in hendrerit tortor sollicitudin eu. Phasellus hendrerit, lacus vel laoreet interdum, dui tortor consequat justo, commodo ultricies arcu felis vitae enim. Vivamus eu sapien at leo suscipit rutrum eu at justo. Aenean et dolor a libero ullamcorper posuere. Integer laoreet placerat nisi in vulputate. Mauris laoreet eget risus sed cursus. Donec scelerisque neque a libero eleifend hendrerit. Nulla varius condimentum nunc sit amet fermentum. Aliquam lorem ex, varius nec mollis ut, ultrices in neque. Morbi sit amet porta leo. Integer iaculis fermentum lacus in vestibulum. - -Ut gravida, tellus ut maximus ultrices, erat est venenatis nisl, vitae pretium massa ex ac magna. Sed non purus eget ligula aliquet volutpat non quis arcu. Nam aliquam tincidunt risus, sit amet fringilla sapien vulputate ut. Mauris luctus suscipit pellentesque. Nunc porttitor dapibus ex quis tempus. Ut ullamcorper metus a eros vulputate, vitae viverra lectus convallis. Mauris semper imperdiet augue quis tincidunt. Integer porta pretium magna, sed cursus sem scelerisque sollicitudin. Nam efficitur, nibh pretium eleifend vestibulum, purus diam posuere sem, in egestas mauris augue sit amet urna. - -Vestibulum tincidunt euismod massa in congue. Duis interdum metus non laoreet fringilla. Donec at ligula congue, tincidunt nunc non, scelerisque nunc. Donec bibendum magna non est scelerisque feugiat at nec neque. Ut orci tortor, tempus eget massa non, dignissim faucibus dolor. Nam odio risus, accumsan pretium neque eget, accumsan dignissim dui. In ut neque auctor, scelerisque tellus sed, ullamcorper nisi. Suspendisse varius cursus quam at hendrerit. Vivamus elit libero, sagittis vitae sem ac, vulputate iaculis ligula. - -Sed lobortis laoreet purus sit amet rutrum. Pellentesque feugiat non leo vel lacinia. Quisque feugiat nisl a orci bibendum vestibulum. In et sollicitudin urna. Morbi a arcu ac metus faucibus tempus. Nam eu imperdiet sapien, suscipit mattis tortor. Aenean blandit ipsum nisi, a eleifend ligula euismod at. Integer tincidunt pharetra felis, mollis placerat mauris hendrerit at. Curabitur convallis, est sit amet luctus volutpat, massa lacus cursus augue, sed eleifend magna quam et risus. Aliquam lobortis tincidunt metus vitae porttitor. Suspendisse potenti. Aenean ullamcorper, neque id commodo luctus, nulla nunc lobortis quam, id dapibus neque dui nec mauris. Etiam quis lorem quis elit commodo ornare. Ut pharetra purus ultricies enim ultrices efficitur. Proin vehicula tincidunt molestie. Mauris et placerat sem. - -Aliquam erat volutpat. Suspendisse velit turpis, posuere ac lacus eu, lacinia laoreet velit. Sed interdum felis neque, id blandit sem malesuada sit amet. Ut sagittis justo erat, efficitur semper orci tempor sed. Donec enim massa, posuere varius lectus egestas, pellentesque posuere mi. Cras tincidunt ut libero sed mattis. Suspendisse quis magna et tellus posuere interdum vel at purus. Pellentesque fringilla tristique neque, id aliquet tellus ultricies non. Duis ut tellus vel odio lobortis vulputate. - -Integer at magna ac erat convallis vestibulum. Sed lobortis porttitor mauris. Fusce varius lorem et volutpat pulvinar. Aenean ac vulputate lectus, vitae consequat velit. Suspendisse ex dui, varius ut risus ut, dictum scelerisque sem. Vivamus urna orci, volutpat ut convallis ac, venenatis vitae urna. In hac habitasse platea dictumst. Etiam eu purus arcu. Aenean vulputate leo urna, vel tristique dui sagittis euismod. Suspendisse non tellus efficitur ante rhoncus volutpat at et sapien. - -Sed dapibus accumsan porttitor. Phasellus facilisis lectus finibus ligula dignissim, id pulvinar lectus feugiat. Nullam egestas commodo nisi posuere aliquet. Morbi sit amet tortor sagittis, rutrum dui nec, dapibus sapien. Sed posuere tortor tortor, interdum auctor magna varius vitae. Vestibulum id sagittis augue. Curabitur fermentum arcu sem, eu condimentum quam rutrum non. Phasellus rutrum nibh quis lectus rhoncus pretium. Curabitur dictum interdum elit. Vestibulum maximus sodales imperdiet. Mauris auctor nec purus sed venenatis. In in urna purus. - -Duis placerat molestie suscipit. Morbi a elit id purus efficitur consequat. Nunc ac commodo turpis. Etiam sit amet lacus a ipsum tempus venenatis sed vel nibh. Duis elementum aliquam mi sed tristique. Morbi ligula tortor, semper ac est vel, lobortis maximus erat. Curabitur ipsum felis, laoreet vel condimentum eget, ullamcorper sit amet mauris. Nulla facilisi. Nam at purus sed mi egestas placerat vitae vel magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse at dignissim diam. Phasellus consectetur eget neque vel viverra. Donec sollicitudin mattis dolor vel malesuada. Vivamus vehicula leo neque, vitae fermentum leo posuere et. Praesent dui est, finibus sit amet tristique quis, pharetra vel nibh. - -Duis nulla leo, accumsan eu odio eget, sagittis semper orci. Quisque ullamcorper ligula quam, commodo porttitor mauris ullamcorper eu. Cras varius sagittis felis in aliquam. Duis sodales risus ac justo vehicula, nec mattis diam lacinia. Cras eget lectus ipsum. Ut commodo, enim vitae malesuada hendrerit, ex dolor egestas lectus, sit amet hendrerit metus diam nec est. Vestibulum tortor metus, lobortis sit amet ante eget, tempor molestie lacus. In molestie et urna et semper. Mauris mollis, sem non hendrerit condimentum, sapien nisi cursus est, non suscipit quam justo non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam enim est, porta ac feugiat vitae, rutrum in lorem. Duis vehicula tortor ut posuere maximus. - -Nullam vestibulum non tellus sed commodo. Quisque mattis elit sit amet sapien sollicitudin, ut condimentum nisl congue. Aenean sagittis massa vel elit faucibus fermentum. Donec tincidunt nisi nec nisl sodales pellentesque. Mauris congue congue ligula ut suscipit. Vivamus velit tortor, tempor et gravida eget, fermentum sit amet ante. Nullam fringilla, lorem at ultrices cursus, urna neque ornare dolor, eu lacinia orci enim sed nibh. Ut a ullamcorper lectus, id mattis purus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean maximus sollicitudin posuere. Nunc at augue lacus. Aenean efficitur leo sit amet lacinia efficitur. - -Quisque venenatis quam mi, in pharetra odio vulputate eu. In vel nisl pulvinar, pulvinar ligula ut, sodales risus. Sed efficitur lectus at vestibulum tincidunt. Vestibulum eu ullamcorper elit. Fusce vestibulum magna enim, et tempor lacus posuere vitae. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer leo elit, luctus nec mattis sit amet, sollicitudin in turpis. - -Proin convallis venenatis leo, vitae tristique erat iaculis nec. Nulla facilisi. Duis porttitor, sapien et bibendum vulputate, sem libero sodales lacus, non malesuada felis erat ut libero. Nam non felis semper, finibus est a, mattis mauris. Praesent nec eros quam. Nulla hendrerit, augue consectetur eleifend ultricies, purus mi condimentum nulla, eget dapibus est nunc sed libero. Nullam elementum dui erat, vitae luctus libero sollicitudin et. Nulla odio magna, placerat in augue eu, dapibus imperdiet odio. Suspendisse imperdiet metus sit amet rhoncus dapibus. Cras at enim et urna vehicula cursus eu a mauris. Integer magna ante, eleifend ac placerat vitae, porta at nisi. Cras eget malesuada orci. Curabitur nunc est, vulputate id viverra et, dignissim sed odio. Curabitur non mattis sem. Sed bibendum, turpis vitae vehicula faucibus, nunc quam ultricies lectus, vitae viverra felis turpis at libero. - -Nullam ut egestas ligula. Proin hendrerit justo a lectus commodo venenatis. Nulla facilisi. Ut cursus lorem quis est bibendum condimentum. Aenean in tristique odio. Fusce tempor hendrerit ipsum. Curabitur mollis felis justo, quis dapibus erat auctor vel. Sed augue lectus, finibus ut urna quis, ullamcorper vestibulum dui. Etiam molestie aliquam tempor. Integer mattis sollicitudin erat, et tristique elit varius vel. Mauris a ex justo. - -Nam eros est, imperdiet non volutpat rutrum, pellentesque accumsan ligula. Duis sit amet turpis metus. Aenean in rhoncus metus, ac fringilla ex. Suspendisse condimentum egestas purus, ut pharetra odio vulputate vel. Duis tincidunt massa a placerat ultrices. Mauris ultricies nibh sit amet condimentum malesuada. Duis tincidunt id ipsum sed congue. - -Praesent eu ex augue. Nullam in porta ligula. In tincidunt accumsan arcu, in pellentesque magna tristique in. Mauris eleifend libero ac nisl viverra faucibus. Nam sollicitudin dolor in commodo hendrerit. Cras at orci metus. Ut quis laoreet orci. Vivamus ultrices leo pellentesque tempor aliquet. Maecenas ut eros vitae purus placerat vestibulum. Etiam vitae gravida dolor, quis rhoncus diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. - -Suspendisse fringilla lacinia sagittis. Integer tincidunt consectetur tristique. Morbi non orci convallis, congue sapien quis, vulputate nunc. Donec a libero vel magna elementum facilisis non quis mi. Mauris posuere tellus non ipsum ultrices elementum. Vivamus massa velit, facilisis quis placerat aliquet, aliquet nec leo. Praesent a maximus sem. Sed neque elit, feugiat vel quam non, molestie sagittis nunc. Etiam luctus nunc ac mauris scelerisque, nec rhoncus lacus convallis. Nunc pharetra, nunc ac pulvinar aliquam, ex ipsum euismod augue, nec porttitor lacus turpis vitae neque. Fusce bibendum odio id tortor faucibus pellentesque. Sed ac porta nibh, eu gravida erat. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam quis ullamcorper felis. Nulla mattis sagittis ante ac tincidunt. Integer ac felis efficitur, viverra libero et, facilisis ligula. Suspendisse a metus a massa rhoncus posuere. Phasellus suscipit ligula ut lacus facilisis, ac pellentesque ex tempor. Quisque consectetur massa mi, ac molestie libero dictum quis. Proin porttitor ligula quis erat tincidunt venenatis. Proin congue nunc sed elit gravida, nec consectetur lectus sodales. Etiam tincidunt convallis ipsum at vestibulum. Quisque maximus enim et mauris porttitor, et molestie magna tristique. Morbi vitae metus elit. Maecenas sed volutpat turpis. Aliquam vitae dolor vestibulum, elementum purus eget, dapibus nibh. Nullam egestas dui ac rutrum semper. - -Etiam hendrerit est metus, et condimentum metus aliquam ac. Pellentesque id neque id ipsum rhoncus vulputate. Aliquam erat nisl, posuere sit amet ligula ac, fermentum blandit felis. Vivamus fermentum mi risus, non lacinia purus viverra id. Aenean ac sapien consequat, finibus mauris nec, porta sem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed quis consectetur ex, dignissim bibendum nulla. Phasellus ac libero at quam vehicula euismod non eu leo. Phasellus a sapien augue. - -Maecenas ligula dui, bibendum vitae mauris et, auctor laoreet felis. Duis non libero a mi semper mattis. Quisque consequat luctus massa, quis tristique eros auctor feugiat. Maecenas sodales euismod neque vitae facilisis. Nullam laoreet imperdiet velit at pellentesque. Etiam massa odio, facilisis a consequat vitae, placerat vel magna. Nunc sagittis eros nec urna fringilla, pulvinar vestibulum nibh scelerisque. Sed magna metus, cursus eu consequat et, pharetra a est. Suspendisse elementum neque a dui malesuada lacinia. Donec sed ipsum volutpat, cursus urna id, ullamcorper arcu. Maecenas laoreet nisl eget velit egestas sollicitudin. Etiam nisl turpis, mollis id dignissim vitae, tristique vehicula ante. Maecenas eget placerat est, at rutrum augue. Vivamus faucibus lacinia ullamcorper. Sed pulvinar urna sodales ante sodales, at gravida leo dictum. - -Morbi maximus, quam a lobortis bibendum, enim felis varius elit, ac vehicula elit nisl ut lacus. Quisque ut arcu augue. Praesent id turpis quam. Sed sed arcu eros. Maecenas at cursus lorem, ac eleifend nisi. Fusce mattis felis at commodo pharetra. Praesent ac commodo ipsum. Quisque finibus et eros vitae tincidunt. In hac habitasse platea dictumst. Praesent purus ipsum, luctus lobortis ornare quis, auctor eget justo. Nam vel enim sollicitudin, faucibus tortor eu, sagittis eros. Ut nec consectetur erat. Donec ultricies malesuada ligula, a hendrerit sapien volutpat in. Maecenas sed enim vitae sapien pulvinar faucibus. - -Proin semper nunc nibh, non consequat neque ullamcorper vel. Maecenas lobortis sagittis blandit. Aenean et arcu ultricies turpis malesuada malesuada. Ut quam ex, laoreet ut blandit cursus, feugiat vitae dolor. Etiam ex lacus, scelerisque vel erat vel, efficitur tincidunt magna. Morbi tristique lacinia dolor, in egestas magna ultrices vitae. Integer ultrices leo ac tempus venenatis. Praesent ac porta tortor. Vivamus ornare blandit tristique. Nulla rutrum finibus pellentesque. In non dui elementum, fermentum ipsum vel, varius magna. Pellentesque euismod tortor risus, ac pellentesque nisl faucibus eget. - -Vivamus eu enim purus. Cras ultrices rutrum egestas. Sed mollis erat nibh, at posuere nisl luctus nec. Nunc vulputate, sapien id auctor molestie, nisi diam tristique ante, non convallis tellus nibh at orci. Morbi a posuere purus, in ullamcorper ligula. Etiam elementum sit amet dui imperdiet iaculis. Proin vitae tincidunt ipsum, sit amet placerat lectus. Curabitur commodo sapien quam, et accumsan lectus fringilla non. Nullam eget accumsan enim, ac pharetra mauris. Sed quis tristique velit, vitae commodo nisi. Duis turpis dui, maximus ut risus at, finibus consequat nunc. Maecenas sed est accumsan, aliquet diam in, facilisis risus. Curabitur vehicula rutrum auctor. Nam iaculis risus pulvinar maximus viverra. Nulla vel augue et ex sagittis blandit. - -Ut sem nulla, porta ac ante ac, posuere laoreet eros. Donec sodales posuere justo a auctor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras mollis at orci hendrerit porta. Nullam sodales tortor tortor, non lacinia diam finibus id. Duis libero orci, suscipit ac odio et, dictum consequat ipsum. Pellentesque eu ligula sagittis, volutpat eros at, lacinia lorem. Cras euismod tellus in iaculis tempor. Quisque accumsan, magna a congue venenatis, ante ipsum aliquam lectus, at egestas enim nunc at justo. Quisque sem purus, viverra ut tristique ut, maximus id enim. Etiam quis placerat sem. In sollicitudin, lacus eu rutrum mollis, nulla eros luctus elit, vel dapibus urna purus nec urna. Phasellus egestas massa quam, ac molestie erat hendrerit a. Praesent ultrices neque ut turpis molestie auctor. Etiam molestie placerat purus, et euismod erat aliquam in. Morbi id suscipit justo. - -Proin est ante, consequat at varius a, mattis quis felis. Sed accumsan nibh sit amet ipsum elementum posuere. Vestibulum bibendum id diam sit amet gravida. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi nec dolor vel ipsum dignissim hendrerit vel non ipsum. Praesent facilisis orci quis elit auctor lobortis. Phasellus cursus risus lectus, vel lobortis libero dapibus in. Quisque tristique tempus leo a pulvinar. Pellentesque a magna tincidunt, pellentesque massa nec, laoreet orci. Morbi congue ornare dolor quis commodo. Phasellus massa nisi, tincidunt at eros dictum, hendrerit lobortis urna. Maecenas porta, magna id mattis molestie, nibh tellus lobortis sem, eget tincidunt ipsum quam eu turpis. - -Ut gravida orci risus, vel rutrum mauris vehicula id. Etiam bibendum, neque a placerat condimentum, ex orci imperdiet lectus, quis dapibus arcu lacus eget lectus. Sed consequat non mi sit amet venenatis. Fusce vestibulum erat libero, eget hendrerit risus vulputate sollicitudin. Integer sed eleifend felis. Donec commodo, sem eu mattis placerat, urna odio aliquam tellus, et laoreet justo tellus eget erat. Fusce sed suscipit tortor. Nam hendrerit nibh ac nunc auctor lacinia. Pellentesque placerat condimentum ipsum, eget semper tortor hendrerit vel. Nullam non urna eu lacus pellentesque congue ut id eros. - -Nunc finibus leo in rhoncus tristique. Sed eu ipsum nec nisl egestas faucibus eget a felis. Pellentesque vitae nisi in nulla accumsan fermentum. Sed venenatis feugiat eleifend. Fusce porttitor varius placerat. Aliquam aliquet lacus sit amet mattis mollis. Sed vel nulla quis dolor suscipit vehicula ac viverra lorem. Duis viverra ipsum eget nulla ullamcorper fermentum. Mauris tincidunt arcu quis quam fringilla ornare. Donec et iaculis tortor. Nam ultricies libero vel ipsum aliquet efficitur. Morbi eget dolor aliquam, tempus sapien eget, viverra ante. Donec varius mollis ex, sed efficitur purus euismod interdum. Quisque vel sapien non neque tincidunt semper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. - -Suspendisse sit amet purus leo. Fusce lectus lorem, aliquam ac nulla eget, imperdiet ornare eros. Nullam sem augue, varius in nisi non, sollicitudin pellentesque ante. Etiam eu odio condimentum, tempor libero et, egestas arcu. Cras pellentesque eleifend aliquet. Pellentesque non blandit ligula. Ut congue viverra rhoncus. Phasellus mattis mi ac eros placerat, eu feugiat tellus ultrices. Aenean mollis laoreet libero eu imperdiet. Cras sed pulvinar mi, ac vehicula ligula. Vestibulum sit amet ex massa. In a egestas eros. - -Mauris pretium ipsum risus, venenatis cursus ante imperdiet id. Praesent eu turpis nec risus feugiat maximus ullamcorper ac lectus. Integer placerat at mi vel dapibus. Vestibulum fermentum turpis sit amet turpis viverra, id aliquet diam suscipit. Nam nec ex sed ante ullamcorper pharetra quis sit amet risus. Sed ac faucibus velit, id feugiat nibh. Nullam eget ipsum ex. Vivamus tincidunt non nunc non faucibus. Quisque bibendum viverra facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at nisi hendrerit quam suscipit egestas. Curabitur laoreet maximus ultricies. Duis ut tellus ac augue molestie dictum. - -Suspendisse rhoncus iaculis erat, ut ullamcorper est tristique eget. Donec auctor nec risus at gravida. Vivamus volutpat vulputate tellus, vel ultricies eros suscipit eget. Ut pulvinar id mi eu tempus. Morbi malesuada augue in dui varius, nec blandit neque vehicula. Donec ornare nec nisl in mollis. Morbi enim nisi, rhoncus nec est id, dapibus tempus urna. Ut id elit a felis vestibulum consectetur. Duis lectus quam, pharetra sit amet diam sed, posuere vestibulum erat. Fusce vitae maximus massa. Nullam id metus tempus, iaculis risus eu, lobortis urna. Quisque in congue urna. Pellentesque placerat neque in augue dapibus, non varius ex malesuada. Curabitur ut eleifend libero. Fusce vitae ligula luctus, fermentum enim vitae, ultrices erat. - -Sed viverra augue turpis, scelerisque egestas sapien mattis eu. Duis laoreet magna at ex pharetra dapibus. Praesent eget odio vel quam venenatis dictum. Nulla in sollicitudin dolor. Mauris lobortis nec eros vel rhoncus. Vestibulum porta viverra venenatis. Curabitur vel scelerisque quam, a egestas velit. Praesent volutpat tincidunt magna at laoreet. - -Cras nec lorem odio. Pellentesque quis dui urna. Praesent at tellus ac lectus scelerisque placerat nec eu risus. Vestibulum sit amet mattis ligula. Vivamus sed nisi at leo elementum accumsan at sit amet arcu. Aenean mattis tellus nec leo gravida, eget hendrerit nisl faucibus. Mauris pellentesque luctus condimentum. Maecenas pretium sapien nunc, eget commodo dolor maximus id. Mauris vestibulum accumsan massa a dictum. Phasellus interdum quam ligula, ut maximus diam blandit aliquam. Nunc vitae ex eu erat condimentum consectetur. Maecenas interdum condimentum volutpat. - -Donec et enim a libero rutrum laoreet. Praesent a condimentum sem, at tincidunt quam. In vel molestie risus. Sed urna dui, molestie vitae mollis laoreet, tempor quis lectus. Praesent vitae auctor est, et aliquet nunc. Curabitur vulputate blandit nulla, at gravida metus. Maecenas gravida dui eu iaculis tristique. Pellentesque posuere turpis nec auctor eleifend. Suspendisse bibendum diam eu tellus lobortis, et laoreet quam congue. In hac habitasse platea dictumst. Morbi dictum neque velit, eget rutrum eros ultrices sit amet. - -Phasellus fermentum risus pharetra consectetur bibendum. Donec magna tortor, lacinia vitae nibh quis, aliquet pretium lorem. Donec turpis nisi, pretium eu enim volutpat, mattis malesuada augue. Nullam vel tellus iaculis, sollicitudin elit eget, tincidunt lacus. Fusce elementum elementum felis et iaculis. Suspendisse porta eros nec neque malesuada, in malesuada ante sollicitudin. Vivamus bibendum viverra molestie. - -Integer feugiat, erat nec convallis aliquam, velit felis congue erat, molestie eleifend tellus erat in tellus. Nunc et justo purus. Donec egestas fermentum dui non feugiat. Quisque in sapien sagittis, gravida quam id, iaculis lectus. Cras sagittis rhoncus bibendum. Fusce quis metus in velit scelerisque tincidunt at non ipsum. Vivamus efficitur ante eu odio vulputate, vitae ultricies risus vehicula. Proin eget odio eu sem tincidunt feugiat vel id lorem. - -Vestibulum sit amet nulla dignissim, euismod mi in, fermentum tortor. Donec ut aliquet libero, lacinia accumsan velit. Donec et nulla quam. Nullam laoreet odio nec nunc imperdiet, a congue eros venenatis. Quisque nec tellus sit amet neque interdum posuere. Duis quis mi gravida, tincidunt diam convallis, ultricies augue. Mauris consequat risus non porttitor congue. Ut in ligula consequat, viverra nunc a, eleifend enim. Duis ligula urna, imperdiet nec facilisis et, ornare eu ex. Proin lobortis lectus a lobortis porttitor. Nulla leo metus, egestas eu libero sed, pretium faucibus felis. Vestibulum non sem tortor. Nam cursus est leo. Vivamus luctus enim odio, non interdum sem dapibus a. Aenean accumsan consequat lectus in imperdiet. - -Donec vehicula laoreet ipsum in posuere. Quisque vel quam imperdiet, sollicitudin nisi quis, suscipit velit. Morbi id sodales mauris. Curabitur tellus arcu, feugiat sed dui sit amet, sodales sagittis libero. Aenean vel suscipit metus, non placerat leo. Vestibulum quis nulla elit. Proin scelerisque non ante ut commodo. Interdum et malesuada fames ac ante ipsum primis in faucibus. - -Sed non urna dolor. Suspendisse convallis mi porta pulvinar ultrices. Suspendisse quam ipsum, hendrerit non scelerisque molestie, interdum dictum nunc. Morbi condimentum condimentum turpis eu luctus. Pellentesque sagittis sollicitudin odio, sed ultricies felis ornare sit amet. Sed ultrices ex leo, a tincidunt nisl gravida sed. Nullam ornare accumsan porta. Praesent consectetur id est nec sollicitudin. - -In hac habitasse platea dictumst. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sed ultrices nibh. Duis accumsan suscipit eros, a dictum odio tempus sit amet. Aenean imperdiet erat ac lacus finibus, scelerisque cursus massa imperdiet. Mauris molestie risus ut lacinia posuere. Nulla et sodales purus. Maecenas orci erat, placerat in tristique quis, placerat in mi. - -Donec sollicitudin pellentesque odio in feugiat. Morbi eu dolor ut mauris congue sollicitudin. Aliquam erat volutpat. Nulla id varius dui. Curabitur finibus urna ante, consectetur interdum nisi volutpat a. Quisque quis mi tristique, consequat tellus eget, rutrum sapien. Vivamus vitae tellus vulputate, rutrum ex eu, vulputate sem. Suspendisse viverra lorem tellus, vel interdum orci gravida quis. Ut laoreet arcu at mi ullamcorper finibus. Duis porta sagittis vestibulum. Sed commodo nisl vitae urna sollicitudin, nec lacinia est sodales. Curabitur imperdiet sodales dui sed iaculis. Sed ac tellus maximus, eleifend quam sit amet, feugiat elit. Aenean viverra, dui at mattis varius, est odio vestibulum sapien, sit amet mollis libero massa nec velit. Etiam quis sodales justo. - -Ut ultricies, sem eget sodales feugiat, nunc arcu congue elit, ac tempor justo massa nec purus. Maecenas enim nunc, pharetra eget dictum sit amet, tempus pellentesque velit. Suspendisse venenatis ligula in nulla mattis, et imperdiet ex tincidunt. Etiam vulputate, tellus et ultrices suscipit, enim velit laoreet massa, vitae congue odio enim ac urna. Morbi quam lorem, iaculis ac varius sagittis, euismod quis dolor. In ut dui eu purus feugiat consectetur. Vestibulum cursus velit quis lacus pellentesque iaculis. Cras in risus sed mauris porta rutrum. Nulla facilisi. Nullam eu bibendum est, non pellentesque lectus. Sed imperdiet feugiat lorem, quis convallis ante auctor in. Maecenas justo magna, scelerisque sit amet tellus eget, varius elementum risus. Duis placerat et quam sed varius. - -Duis nec nibh vitae nibh dignissim mollis quis sed felis. Curabitur vitae quam placerat, venenatis purus ut, euismod nisl. Curabitur porttitor nibh eu pulvinar ullamcorper. Suspendisse posuere nec ipsum ac dapibus. Cras convallis consectetur urna. Phasellus a nibh in dolor lacinia posuere id eget augue. In eu pharetra lorem, vitae cursus lacus. Aliquam tincidunt nibh lectus. Aenean facilisis ultricies posuere. Sed ut placerat orci. Curabitur scelerisque gravida blandit. Maecenas placerat ligula eget suscipit fringilla. Mauris a tortor justo. Aliquam hendrerit semper mollis. Phasellus et tincidunt libero. Etiam vel quam libero. - -Quisque aliquet tempor ex. Ut ante sem, vehicula at enim vel, gravida porta elit. Etiam vitae lacus a neque lobortis consectetur. Mauris sed interdum odio. Mauris elementum ex blandit tempor cursus. Integer in enim in leo viverra elementum. Fusce consectetur metus et sem rutrum, mattis euismod diam semper. Nunc sed ipsum vel urna consequat vehicula. Donec cursus pretium lorem, vestibulum pretium felis commodo sit amet. Nam blandit felis enim, eget gravida ex faucibus a. In nec neque massa. Etiam laoreet posuere ipsum. Praesent volutpat nunc dolor, ac vulputate magna facilisis non. Aenean congue turpis vel lectus sollicitudin tristique. Sed nec consequat purus, non vehicula quam. Etiam ultricies, est ac dictum tincidunt, turpis turpis pretium massa, a vulputate libero justo at nibh. - -Aliquam erat volutpat. Cras ultrices augue ac sollicitudin lobortis. Curabitur et aliquet purus. Duis feugiat semper facilisis. Phasellus lobortis cursus velit, a sollicitudin tortor. Nam feugiat sapien non dapibus condimentum. Morbi at mi bibendum, commodo quam at, laoreet enim. Integer eu ultrices enim. Sed vestibulum eu urna ut dictum. Curabitur at mattis leo, sed cursus massa. Aliquam porttitor, felis quis fermentum porttitor, justo velit feugiat nulla, eget condimentum sem dui ut sapien. - -In fringilla elit eu orci aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut eget fringilla tellus. Curabitur fermentum, mi et condimentum suscipit, elit neque bibendum dui, et hendrerit nunc metus id ipsum. Morbi placerat mi in hendrerit congue. Ut feugiat mauris eget scelerisque viverra. Vivamus sit amet erat dictum, sagittis lectus nec, pulvinar lorem. Sed non enim ac dui sollicitudin aliquet. Quisque ut lacus dolor. Fusce hendrerit malesuada euismod. Nulla faucibus vel mauris eu mollis. Mauris est diam, fringilla ac arcu feugiat, efficitur volutpat turpis. Aliquam venenatis cursus massa sed porttitor. Ut ac finibus enim, in tincidunt sapien. - -Nunc faucibus semper turpis a lacinia. Phasellus gravida, libero vel pulvinar ornare, ex sem tincidunt lectus, sit amet convallis augue risus at tortor. Quisque sit amet ipsum id nulla posuere vestibulum. Pellentesque scelerisque mauris vel leo viverra sodales. Nulla viverra aliquam ex, ut rutrum enim fermentum venenatis. Aenean eget dapibus ex, eget faucibus metus. Vestibulum volutpat leo in diam semper, eget porta magna suscipit. Sed sit amet nulla blandit, aliquam dolor ac, gravida velit. Sed vel velit viverra, maximus est id, convallis justo. - -Curabitur nulla ante, vulputate at libero vel, ullamcorper rutrum nibh. Pellentesque porttitor eu mauris id mattis. Duis vulputate augue elit, eget interdum justo pretium vel. Maecenas eu vulputate arcu, eget posuere purus. Suspendisse viverra a velit dictum eleifend. Suspendisse vitae dapibus diam. Donec vehicula justo in ante interdum, eu luctus diam placerat. Vivamus convallis ipsum eu orci suscipit, sed fermentum enim euismod. Maecenas faucibus elit vitae ex ornare tristique. Donec vestibulum nec elit sit amet porttitor. Aenean tempor lectus eget tortor hendrerit luctus. Nullam interdum vitae lectus vel feugiat. Cras in risus non magna consectetur lobortis. Sed faucibus enim quis gravida convallis. - -Phasellus eget massa sit amet libero ultrices suscipit. Vivamus at risus sapien. Nam mollis nunc eget velit dictum maximus. Sed pellentesque, nunc ac fringilla lacinia, quam enim mattis ex, sed euismod tortor metus eu neque. Ut mattis nisl ut lectus rhoncus, sodales bibendum eros porta. Nulla porttitor enim nec diam sagittis, eget porta velit efficitur. Vestibulum ultricies eros neque. Phasellus rutrum suscipit enim, in interdum ante gravida vitae. Sed in sagittis diam, non commodo velit. - -Morbi hendrerit odio orci, nec tincidunt odio rhoncus nec. Mauris neque velit, vehicula a lorem at, suscipit tristique dui. Sed finibus, nisl in mattis convallis, turpis neque sodales lacus, eu porta enim magna non diam. Nam commodo sodales risus consectetur malesuada. In eget elementum justo. Phasellus sit amet massa imperdiet, dapibus nunc sit amet, suscipit orci. Fusce condimentum laoreet feugiat. Ut ut viverra ante. Praesent bibendum interdum commodo. Nulla mollis nisi a est ornare volutpat. Sed at ligula eu nisi dapibus tempus. Proin cursus vestibulum justo, nec efficitur justo dignissim vel. Nunc quis maximus eros. - -Cras viverra, diam a tristique mattis, libero felis vulputate tellus, a ornare felis leo a dui. Nulla ante nulla, finibus ut tellus ut, blandit pharetra nibh. Proin eleifend fermentum ex, eget auctor libero vulputate in. Nullam ultricies, mauris placerat pretium placerat, leo urna lobortis leo, vel placerat arcu libero sed mauris. Aliquam mauris ligula, ornare at urna at, eleifend gravida ligula. Vestibulum consectetur ut nulla non scelerisque. Donec ornare, sem nec elementum aliquam, urna nulla bibendum metus, eu euismod dui ligula ac est. Fusce laoreet erat eu ex lobortis, quis bibendum ligula interdum. Sed vel mi erat. Vivamus id lacus ac enim mattis tempor. Nunc ultricies pellentesque enim sed euismod. Fusce tincidunt convallis elit quis aliquam. Mauris nulla ipsum, sollicitudin quis diam ac, feugiat volutpat tellus. In nibh nibh, vulputate quis tincidunt quis, pulvinar eget magna. Pellentesque quis finibus dolor. Suspendisse viverra vitae lectus non eleifend. - -Nunc ut orci et sapien maximus semper. Nulla dignissim sem urna, ac varius lectus ultricies id. Quisque aliquet pulvinar pretium. In ultricies molestie tellus vehicula porta. Nam enim lorem, aliquam eget ex et, hendrerit volutpat quam. Maecenas diam lacus, pellentesque eget tempus ac, pharetra eu elit. Donec vel eros a sem facilisis vulputate. Nullam ac nisi vulputate, laoreet nisl ac, eleifend sem. Nullam mi massa, rhoncus sed pharetra interdum, tincidunt eget nunc. Aliquam viverra mattis posuere. Mauris et dui sed nisl sollicitudin fermentum quis ut arcu. Nam placerat eget orci at tincidunt. Curabitur vel turpis metus. Phasellus nibh nulla, fermentum scelerisque sem vel, gravida tincidunt velit. Pellentesque vel quam tempor, finibus massa pellentesque, condimentum dui. - -Donec at mattis neque. Etiam velit diam, consequat auctor mauris id, hendrerit faucibus metus. Maecenas ullamcorper eros a est sodales, ac consectetur odio scelerisque. Donec leo metus, imperdiet at pellentesque vel, feugiat id erat. Suspendisse at magna enim. Vestibulum placerat sodales lorem id sollicitudin. Aenean at euismod ligula, eget mollis diam. Phasellus pulvinar, orci nec pretium condimentum, est erat facilisis purus, quis feugiat augue elit aliquam nulla. Aenean vitae tortor id risus congue tincidunt. Sed dolor enim, mattis a ullamcorper id, volutpat ac leo. - -Proin vehicula feugiat augue, id feugiat quam sodales quis. Donec et ultricies massa, a lacinia nulla. Duis aliquam augue ornare euismod viverra. Ut lectus risus, rutrum sit amet efficitur a, luctus nec nisl. Cras volutpat ullamcorper congue. Sed vitae odio metus. Phasellus aliquet euismod varius. - -Nullam sem ex, malesuada ut magna ut, pretium mollis arcu. Nam porttitor eros cursus mi lacinia faucibus. Suspendisse aliquet eleifend iaculis. Maecenas sit amet viverra tortor. Nunc a mollis risus. Etiam tempus dolor in tortor malesuada mattis. Ut tincidunt venenatis est sit amet dignissim. Vestibulum massa enim, tristique sed scelerisque eu, fringilla ac velit. Donec efficitur quis urna sit amet malesuada. Vestibulum consequat ac ligula in dapibus. Maecenas massa massa, molestie non posuere nec, elementum ut magna. In nisi erat, mollis non venenatis eu, faucibus in justo. Morbi gravida non ex non egestas. Pellentesque finibus laoreet diam, eu commodo augue congue vitae. - -Aenean sem mi, ullamcorper dapibus lobortis vitae, interdum tincidunt tortor. Vivamus eget vulputate libero. Ut bibendum posuere lectus, vel tincidunt tortor aliquet at. Phasellus malesuada orci et bibendum accumsan. Aliquam quis libero vel leo mollis porta. Sed sagittis leo ac lacus dictum, ac malesuada elit finibus. Suspendisse pharetra luctus commodo. Vivamus ultricies a odio non interdum. Vivamus scelerisque tincidunt turpis quis tempor. Pellentesque tortor ligula, varius non nunc eu, blandit sollicitudin neque. Nunc imperdiet, diam et tristique luctus, ipsum ex condimentum nunc, sit amet aliquam justo velit sed libero. Duis vel suscipit ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed tincidunt neque vel massa ultricies, id dictum leo consequat. Curabitur lobortis ultricies tellus, eget mattis nisl aliquam sit amet. - -Proin at suscipit justo. Vivamus ut vestibulum nisl. Pellentesque enim odio, pharetra non magna sed, efficitur auctor magna. Praesent tincidunt ante quis ante hendrerit viverra. Pellentesque vel ipsum id magna vulputate efficitur. Sed nec neque accumsan, pulvinar sapien quis, euismod mauris. Donec condimentum laoreet sapien quis gravida. Quisque sed mattis purus. Vestibulum placerat vel neque maximus scelerisque. - -Vestibulum mattis quam quis efficitur elementum. Duis dictum dolor ac scelerisque commodo. Fusce sollicitudin nisi sit amet dictum placerat. Suspendisse euismod pharetra eleifend. In eros nisl, porttitor sed mauris at, consectetur aliquet mauris. Donec euismod viverra neque sed fermentum. Phasellus libero magna, accumsan ut ultricies vitae, dignissim eget metus. Donec tellus turpis, interdum eget maximus nec, hendrerit eget massa. Curabitur auctor ligula in iaculis auctor. In ultrices quam suscipit cursus finibus. Aenean id mi at dolor interdum iaculis vitae ut lorem. Nullam sed nibh fringilla, lacinia odio nec, placerat erat. In dui libero, viverra ac viverra ac, pellentesque sit amet turpis. - -Nulla in enim ex. Sed feugiat est et consectetur venenatis. Cras varius facilisis dui vel convallis. Vestibulum et elit eget tellus feugiat pellentesque. In ut ante eu purus aliquet posuere. Nulla nec ornare sem, sed luctus lorem. Nam varius iaculis odio, eget faucibus nisl ullamcorper in. Sed eget cursus felis, nec efficitur nisi. - -Vivamus commodo et sem quis pulvinar. Pellentesque libero ante, venenatis vitae ligula sit amet, ornare sollicitudin nulla. Mauris eget tellus hendrerit, pulvinar metus quis, tempor nisi. Proin magna ex, laoreet sed tortor quis, varius fermentum enim. Integer eu dolor dictum, vulputate tortor et, aliquet ligula. Vestibulum vitae justo id mauris luctus sollicitudin. Suspendisse eget auctor neque, sodales egestas lorem. Vestibulum lacinia egestas metus vitae euismod. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus ex tellus, volutpat nec pulvinar sit amet, condimentum vitae dui. Curabitur vel felis sodales, lacinia nunc iaculis, ullamcorper augue. Pellentesque consequat dolor quis eros efficitur malesuada. Nulla ut malesuada lectus. - -Morbi et tristique ante. Aliquam erat volutpat. Vivamus vitae dui nec turpis pellentesque fermentum. Quisque eget velit massa. Pellentesque tristique aliquam nisl, eu sollicitudin justo venenatis sed. Duis eleifend sem eros, ut aliquam libero porttitor id. Sed non nunc consequat, rhoncus diam eu, commodo erat. Praesent fermentum in lectus id blandit. Donec quis ipsum at justo volutpat finibus. Nulla blandit justo nulla, at mollis lacus consequat eget. Aenean sollicitudin quis eros ut ullamcorper. - -Pellentesque venenatis nulla ut mi aliquet feugiat. Cras semper vel magna nec pharetra. Integer mattis felis et sapien commodo imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis quis luctus felis. Vestibulum justo nibh, aliquam non lectus vitae, molestie placerat justo. Donec lorem nibh, gravida sit amet hendrerit ac, maximus id ipsum. Nunc ac libero sodales risus eleifend sagittis. Phasellus est massa, lobortis elementum ex sed, scelerisque consectetur neque. Nunc faucibus neque id lorem malesuada, eget convallis ex mattis. - -Sed turpis tortor, fermentum non turpis id, posuere varius nibh. Donec iaculis lorem dui. Etiam eros ante, sodales eget venenatis at, consectetur eget risus. Curabitur non aliquam ante, a pretium justo. Maecenas tempor nisl tortor, vitae dictum nisi ultrices eu. Duis eget dui ultrices, porttitor lacus sed, lobortis purus. Quisque mattis elit nec neque sagittis, sed commodo leo blandit. Mauris sodales interdum eleifend. Vestibulum condimentum consectetur augue, id luctus diam convallis et. - -Nunc suscipit risus in justo accumsan, a placerat magna tincidunt. Proin a nisl ipsum. Sed libero dui, tristique in augue quis, auctor tristique risus. Sed porttitor ex augue, eu porta augue molestie a. Duis rhoncus purus libero, eu tempus turpis condimentum at. Sed mollis nisi id lectus placerat tincidunt. Maecenas non scelerisque elit, quis rutrum orci. Donec in tellus pharetra urna ornare lobortis. Phasellus id risus at nisi varius rutrum eu ut turpis. - -Duis dictum justo quis nisl porta, eget tincidunt magna suscipit. Sed velit massa, ullamcorper eu sodales ac, pretium a massa. Duis et rutrum tortor. Nulla accumsan hendrerit sapien, cursus volutpat eros egestas eget. Donec sollicitudin at ante quis sollicitudin. Aenean blandit feugiat diam, id feugiat eros faucibus eget. Donec viverra dolor vel justo scelerisque dignissim. Nulla semper sem nunc, rhoncus semper tellus ultricies sed. Duis in ornare diam. Donec vehicula feugiat varius. Maecenas ut suscipit est. Vivamus sem sem, finibus at dolor sit amet, euismod dapibus ligula. Vestibulum fringilla odio dapibus, congue massa eget, congue sem. Donec feugiat magna eget tortor lacinia scelerisque non et ipsum. - -Suspendisse potenti. Nunc convallis sollicitudin ex eget venenatis. Sed iaculis nibh ex, vel ornare ligula congue dignissim. Quisque sollicitudin dolor ac dui vestibulum, sit amet molestie nisi aliquet. Donec at risus felis. Aenean sollicitudin metus a feugiat porta. Aenean a tortor ut dolor cursus sagittis. Vivamus consectetur porttitor nunc in facilisis. Proin sit amet mi vel lectus consectetur ultrices. - -Sed cursus lectus vitae nunc tristique, nec commodo turpis dapibus. Pellentesque luctus ex id facilisis ornare. Morbi quis placerat dolor. Donec in lectus in arcu mattis porttitor ac sit amet metus. Cras congue mauris non risus sodales, vitae feugiat ipsum bibendum. Nulla venenatis urna sed libero elementum, a cursus lorem commodo. Mauris faucibus lobortis eros nec commodo. - -Nullam suscipit ligula ullamcorper lorem commodo blandit. Nulla porta nibh quis pulvinar placerat. Vivamus eu arcu justo. Vestibulum imperdiet est ut fermentum porttitor. Pellentesque consectetur libero in sapien efficitur scelerisque. Curabitur ac erat sit amet odio aliquet dignissim. Pellentesque mi sem, rhoncus et luctus at, porttitor rutrum lectus. Vestibulum sollicitudin sollicitudin suscipit. Aenean efficitur dolor non ultrices imperdiet. Donec vel sem ex. - -Sed convallis mauris aliquam rutrum cursus. Ut tempor porttitor sodales. Etiam eu risus ac augue gravida egestas et eu dolor. Proin id magna ex. Suspendisse quis lectus quis lorem ultricies tempus. Donec porttitor velit vitae tincidunt faucibus. Aliquam vitae semper nisi. Morbi ultrices, leo non pretium dapibus, dui libero pellentesque ex, vel placerat enim ante vitae dui. Nunc varius, sem sit amet sagittis lobortis, lectus odio scelerisque mauris, ut vestibulum orci magna quis neque. Sed id congue justo. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris congue nisi est, malesuada mollis elit tincidunt sed. Curabitur sed ex sit amet felis tristique elementum vitae vel nibh. - -Etiam mollis pretium lobortis. Mauris augue lacus, efficitur at lacus sed, mollis tincidunt lectus. Aliquam erat volutpat. Donec at euismod elit, et mattis felis. Sed id lobortis urna. Morbi imperdiet vestibulum leo, sed maximus leo blandit eu. Aliquam semper lorem neque, nec euismod turpis mattis mollis. Quisque lobortis urna ultrices odio pretium, ac venenatis orci faucibus. Suspendisse bibendum odio ligula, sed lobortis massa pharetra nec. Donec turpis justo, iaculis at dictum ac, finibus eu libero. Maecenas quis porttitor mi, sit amet aliquet neque. - -Vivamus auctor vulputate ante, at egestas lorem. Donec eu risus in nulla mollis ultricies at et urna. Duis accumsan porta egestas. Ut vel euismod augue. Fusce convallis nulla ante, nec fringilla velit aliquet at. Nam malesuada dapibus ligula, a aliquam nibh scelerisque ac. Praesent malesuada neque et pellentesque interdum. Curabitur volutpat at turpis vitae tristique. Vivamus porttitor semper congue. Quisque suscipit lacus mi, rhoncus ultrices tortor auctor quis. Maecenas neque neque, molestie ac facilisis eget, luctus ac lorem. In ut odio ut lacus suscipit pulvinar vitae sed elit. Nulla imperdiet, sem quis euismod sagittis, dui erat luctus dolor, faucibus faucibus erat sem eget nunc. Nam accumsan placerat malesuada. Maecenas convallis finibus pulvinar. - -Cras at placerat tortor. Morbi facilisis auctor felis sit amet molestie. Donec sodales sed lorem vitae suscipit. Etiam fermentum pharetra ipsum, nec luctus orci gravida eu. Pellentesque gravida, est non condimentum tempus, mauris ligula molestie est, in congue dolor nisl vel sapien. Duis congue tempor augue, id rutrum eros porta dapibus. Etiam rutrum eget est eget vestibulum. Aenean mollis arcu vel consequat varius. Praesent at condimentum felis. Duis nec interdum nisl. Donec commodo lorem sed sapien scelerisque malesuada non eu urna. In blandit non ipsum at porta. Nam lobortis leo vitae dui auctor, non feugiat quam bibendum. Donec auctor lectus sagittis laoreet maximus. Maecenas rhoncus laoreet porttitor. Vestibulum porttitor augue ut lectus hendrerit, eget posuere mi gravida. - -Sed mattis ex in erat pulvinar, eu imperdiet magna dapibus. Etiam nisi nibh, tempus non tellus sit amet, mattis tempor odio. Quisque nec lorem feugiat, lobortis odio et, commodo nunc. Maecenas semper purus nisi, nec vehicula nibh eleifend vitae. Nulla fermentum a lectus at maximus. Phasellus finibus metus non euismod ultrices. Etiam a pulvinar ante. Quisque convallis nec metus sit amet facilisis. Praesent laoreet massa et sollicitudin laoreet. Vestibulum in mauris aliquet, convallis mi ut, elementum purus. Nulla purus nulla, sodales at hendrerit quis, tempus sed lectus. - -Nam ut laoreet neque, ut maximus nibh. Maecenas quis justo pellentesque, sollicitudin elit at, venenatis velit. Aenean nunc velit, vehicula scelerisque odio at, consectetur laoreet purus. Duis dui purus, malesuada quis ipsum sit amet, tempor interdum libero. Curabitur porta scelerisque sapien, vitae cursus diam condimentum eu. Phasellus sed orci quam. Nullam vitae dui quis purus tincidunt vestibulum. Curabitur quis nulla porta, cursus arcu non, auctor enim. Etiam sollicitudin ex id sem vehicula mollis. Morbi viverra laoreet tincidunt. Praesent ut semper dui. Nam sit amet pretium neque. Mauris vitae luctus diam, in lacinia purus. Maecenas ut placerat justo, ut porta felis. Integer eu mauris ante. - -Aenean porttitor tellus diam, tempor consequat metus efficitur id. Suspendisse ut felis at erat tempor dictum at nec sapien. Sed vestibulum interdum felis, ac mattis mauris porta in. Nunc et condimentum massa. Sed cursus dictum justo et luctus. Integer convallis enim nisl, a rutrum lectus ultricies in. Donec dapibus lacus at nulla dapibus, id sollicitudin velit hendrerit. Fusce a magna at orci mollis rutrum ac a dolor. Aliquam erat volutpat. Morbi varius porta nunc, sit amet sodales ex hendrerit commodo. Donec tincidunt tortor sapien, vitae egestas sapien vehicula eget. - -Suspendisse potenti. Donec pulvinar felis nec leo malesuada interdum. Integer posuere placerat maximus. Donec nibh ipsum, tincidunt vitae luctus vitae, bibendum at leo. Sed cursus nisl ut ex faucibus aliquet sed nec eros. Curabitur molestie posuere felis. Integer faucibus velit eget consequat iaculis. Mauris sed vulputate odio. Phasellus maximus, elit a pharetra egestas, lorem magna semper tellus, vestibulum semper diam felis at sapien. Suspendisse facilisis, nisl sit amet euismod vehicula, libero nulla vehicula dolor, quis fermentum nibh elit sit amet diam. - -Morbi lorem enim, euismod eu varius ut, scelerisque quis odio. Nam tempus vitae eros id molestie. Nunc pretium in nulla eget accumsan. Quisque mattis est ut semper aliquet. Maecenas eget diam elementum, fermentum ipsum a, euismod sapien. Duis quam ligula, cursus et velit nec, ullamcorper tincidunt magna. Donec vulputate nisl est, et ullamcorper urna tempor sit amet. - -Proin lacinia dui non turpis congue pretium. Morbi posuere metus vel purus imperdiet interdum. Morbi venenatis vel eros non ultricies. Nulla vel semper elit. Ut quis purus tincidunt, auctor justo ut, faucibus turpis. Proin quis mattis erat, at faucibus ligula. Mauris in mauris enim. Donec facilisis enim at est feugiat hendrerit. Nam vel nisi lorem. Fusce ultricies convallis diam, in feugiat tortor luctus quis. Donec tempor, leo vitae volutpat aliquam, magna elit feugiat leo, quis placerat sapien felis eget arcu. Donec ornare fermentum eleifend. Integer a est orci. - -Proin rhoncus egestas leo. Nulla ultricies porta elit quis ornare. Nunc fermentum interdum vehicula. In in ligula lorem. Donec nec arcu sit amet orci lobortis iaculis. Mauris at mollis erat, sit amet mollis tortor. Mauris laoreet justo ullamcorper porttitor auctor. Aenean sit amet aliquam lectus, id fermentum eros. Praesent urna sem, vehicula ac fermentum id, dapibus ut purus. Vestibulum vitae tempus nunc. Donec at nunc ornare metus volutpat porta at eget magna. Donec varius aliquet metus, eu lobortis risus aliquam sed. Ut dapibus fermentum velit, ac tincidunt libero faucibus at. - -In in purus auctor, feugiat massa quis, facilisis nisi. Donec dolor purus, gravida eget dolor ac, porttitor imperdiet urna. Donec faucibus placerat erat, a sagittis ante finibus ac. Sed venenatis dignissim elit, in iaculis felis posuere faucibus. Praesent sed viverra dolor. Mauris sed nulla consectetur nunc laoreet molestie in ut metus. Proin ac ex sit amet magna vulputate hendrerit ac condimentum urna. Proin ligula metus, gravida et sollicitudin facilisis, iaculis ut odio. Cras tincidunt urna et augue varius, ut facilisis urna consequat. Aenean vehicula finibus quam. Ut iaculis eu diam ac mollis. Nam mi lorem, tristique eget varius at, sodales at urna. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin vitae dictum erat, et auctor ipsum. Nullam nunc nunc, sollicitudin quis magna a, vestibulum fermentum mauris. Praesent at erat dolor. Proin laoreet tristique nulla vel efficitur. Nam sed ultrices nibh, id rutrum nunc. Curabitur eleifend a erat sit amet sollicitudin. Nullam metus quam, laoreet vitae dapibus id, placerat sed leo. Aliquam erat volutpat. Donec turpis nisl, cursus eu ex sit amet, lacinia pellentesque nisl. Sed id ipsum massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec interdum scelerisque lorem eu mattis. - -Vivamus ac tristique massa, nec facilisis nisl. Nam ipsum neque, tincidunt vel urna in, cursus imperdiet enim. Nam pellentesque egestas tempus. Morbi facilisis imperdiet libero vitae fringilla. Nam lacinia ligula at sapien facilisis malesuada. Nullam accumsan pulvinar sem, et cursus libero porta sit amet. Curabitur vulputate erat elit, ut pulvinar erat maximus vel. - -Cras aliquet metus ut purus sagittis, vel venenatis ante consectetur. Pellentesque nulla lacus, viverra viverra mattis non, placerat vitae nibh. Donec enim turpis, accumsan sit amet tincidunt eu, imperdiet non metus. Morbi ipsum eros, tincidunt vel est ac, tristique porttitor nibh. Praesent ut ullamcorper mauris. Sed laoreet sit amet diam congue venenatis. Integer porta purus nec orci sagittis posuere. - -Donec vehicula mauris eget lacus mollis venenatis et sed nibh. Nam sodales ligula ipsum, scelerisque lacinia ligula sagittis in. Nam sit amet ipsum at erat malesuada congue. Aenean ut sollicitudin sapien. Etiam at tempor odio. Mauris vitae purus ut magna suscipit consequat. Vivamus quis sapien neque. Nulla vulputate sem sit amet massa pellentesque, eleifend tristique ligula egestas. Suspendisse tincidunt gravida mi, in pulvinar lectus egestas non. Aenean imperdiet ex sit amet nunc sollicitudin porta. Integer justo odio, ultricies at interdum in, rhoncus vitae sem. Sed porttitor arcu quis purus aliquet hendrerit. Praesent tempor tortor at dolor dictum pulvinar. Nulla aliquet nunc non ligula scelerisque accumsan. Donec nulla justo, congue vitae massa in, faucibus hendrerit magna. Donec non egestas purus. - -€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯àáâãäåæçèéêëìíîï Vivamus iaculis, lacus efficitur faucibus porta, dui nulla facilisis ligula, ut sodales odio nunc id sapien. Cras viverra auctor ipsum, dapibus mattis neque dictum sed. Sed convallis fermentum molestie. Nulla facilisi turpis duis. \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_gbk.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_gbk.txt deleted file mode 100644 index 2e1de224145..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_gbk.txt +++ /dev/null @@ -1,283 +0,0 @@ -Öйúabc Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vulputate, ipsum quis interdum fermentum, lorem sem fermentum eros, vitae auctor neque lacus in nisi. Suspendisse potenti. Maecenas et scelerisque elit, in tincidunt quam. Sed eu tincidunt quam. Nullam justo ex, imperdiet a imperdiet et, fermentum sit amet eros. Aenean quis tempus sem. Pellentesque accumsan magna mi, ut mollis velit sagittis id. Etiam quis ipsum orci. Fusce purus ante, accumsan a lobortis at, venenatis eu nisl. Praesent ornare sed ante placerat accumsan. Suspendisse tempus dignissim fermentum. Nunc a leo ac lacus sodales iaculis eu vitae mi. In feugiat ante at massa finibus cursus. Suspendisse posuere fringilla ornare. Mauris elementum ac quam id convallis. Vestibulum non elit quis urna volutpat aliquam a eu lacus. - -Aliquam vestibulum imperdiet neque, suscipit aliquam elit ultrices bibendum. Suspendisse ultrices pulvinar cursus. Morbi risus nisi, cursus consequat rutrum vitae, molestie sed dui. Fusce posuere, augue quis dignissim aliquam, nisi ipsum porttitor ante, quis fringilla nisl turpis ac nisi. Nulla varius enim eget lorem vehicula gravida. Donec finibus malesuada leo nec semper. Proin ac enim eros. Vivamus non tincidunt nisi, vel tristique lorem. - -Nunc consequat ex id eros dignissim, id rutrum risus laoreet. Sed euismod non erat eu ultricies. Etiam vehicula gravida lacus ut porta. Vestibulum eu eros quis nunc aliquet luctus. Cras quis semper ligula. Nullam gravida vehicula quam sed porta. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In porta cursus vulputate. Quisque porta a nisi eget cursus. Aliquam risus leo, luctus ac magna in, efficitur cursus magna. In condimentum non mi id semper. Donec interdum ante eget commodo maximus. - -Vivamus sit amet vestibulum lectus. Fusce tincidunt mi sapien, dictum sollicitudin diam vulputate in. Integer fringilla consequat mollis. Cras aliquet consequat felis eget feugiat. Nunc tempor cursus arcu, vitae ornare nunc varius et. Vestibulum et tortor vel ante viverra porttitor. Nam at tortor ullamcorper, facilisis augue quis, tristique erat. Aenean ut euismod nibh. Quisque eu tincidunt est, nec euismod eros. - -Proin vehicula nibh non viverra egestas. Phasellus sem dolor, ultricies ac sagittis tristique, lacinia a purus. Vestibulum in ante eros. Pellentesque lacus nulla, tristique vitae interdum vel, malesuada ac diam. Aenean bibendum posuere turpis in accumsan. Ut est nulla, ullamcorper quis turpis at, viverra sagittis mauris. Sed in interdum purus. Praesent scelerisque nibh eget sem euismod, ut imperdiet mi venenatis. Vivamus pulvinar orci sed dapibus auctor. Nulla facilisi. Vestibulum tincidunt erat nec porttitor egestas. Mauris quis risus ante. Nulla facilisi. - -Aliquam ullamcorper ornare lobortis. Phasellus quis sem et ipsum mollis malesuada sed in ex. Ut aliquam ex eget metus finibus maximus. Proin suscipit mauris eu nibh lacinia, quis feugiat dui dapibus. Nam sed libero est. Aenean vulputate orci sit amet diam faucibus, eu sagittis sapien volutpat. Nam imperdiet felis turpis, at pretium odio pulvinar in. Sed vestibulum id eros nec ultricies. Sed quis aliquam tortor, vitae ullamcorper tellus. Donec egestas laoreet eros, id suscipit est rutrum nec. Sed auctor nulla eget metus aliquam, ut condimentum enim elementum. - -Aliquam suscipit non turpis sit amet bibendum. Fusce velit ligula, euismod et maximus at, luctus sed neque. Quisque pretium, nisl at ullamcorper finibus, lectus leo mattis sapien, vel euismod mauris diam ullamcorper ex. Nulla ut risus finibus, lacinia ligula at, auctor erat. Mauris consectetur sagittis ligula vel dapibus. Nullam libero libero, lobortis aliquam libero vel, venenatis ultricies leo. Duis porttitor, nibh congue fermentum posuere, erat libero pulvinar tortor, a pellentesque nunc ipsum vel sem. Nullam volutpat, eros sit amet facilisis consectetur, ipsum est vehicula massa, non vestibulum neque elit in mauris. Nunc hendrerit ipsum non enim bibendum, vitae rhoncus mi egestas. Etiam ullamcorper massa vel nisl sagittis, nec bibendum arcu malesuada. Aenean aliquet turpis justo, a consectetur arcu mollis convallis. Etiam tellus ipsum, ultricies vitae lorem et, ornare facilisis orci. Praesent fringilla justo urna, vel mollis neque pulvinar vestibulum. - -Donec non iaculis erat. Aliquam et mi sed nunc pulvinar ultricies in ut ipsum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent feugiat lacus ac dignissim semper. Phasellus vitae quam nisi. Morbi vel diam ultricies risus lobortis ornare. Fusce maximus et ligula quis iaculis. Sed congue ex eget felis convallis, sit amet hendrerit elit tempor. Donec vehicula blandit ante eget commodo. Vestibulum eleifend diam at feugiat euismod. Etiam magna tellus, dignissim eget fermentum vel, vestibulum vitae mauris. Nam accumsan et erat id sagittis. Donec lacinia, odio ut ornare ultricies, dolor velit accumsan tortor, non finibus erat tellus quis ligula. Nunc quis metus in leo volutpat ornare vulputate eu nisl. - -Donec quis viverra ex. Nullam id feugiat mauris, eu fringilla nulla. Vestibulum id maximus elit. Cras elementum elit sed felis lobortis, eget sagittis nisi hendrerit. Vivamus vitae elit neque. Donec vulputate lacus ut libero ultrices accumsan. Vivamus accumsan nulla orci, in dignissim est laoreet sagittis. Proin at commodo velit. Curabitur in velit felis. Aliquam erat volutpat. Sed consequat, nulla et cursus sodales, nisi lacus mattis risus, quis eleifend erat ex nec turpis. Sed suscipit ultrices lorem in hendrerit. - -Morbi vitae lacus nec libero ornare tempus eu et diam. Suspendisse magna ipsum, fermentum vel odio quis, molestie aliquam urna. Fusce mollis turpis a eros accumsan porttitor. Pellentesque rhoncus dolor sit amet magna rutrum, et dapibus justo tempor. Sed purus nisi, maximus vitae fringilla eu, molestie nec urna. Fusce malesuada finibus pretium. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec sed aliquet eros. Pellentesque luctus diam ante, eget euismod nisl aliquet eu. Sed accumsan elit purus, tempor varius ligula tempus nec. Curabitur ornare leo suscipit suscipit fermentum. Morbi eget nulla est. Maecenas faucibus interdum tristique. - -Etiam ut elit eros. Nulla pharetra suscipit molestie. Nulla facilisis bibendum nisl non molestie. Curabitur turpis lectus, facilisis vel diam non, vulputate ultrices mauris. Aenean placerat aliquam convallis. Suspendisse sed scelerisque tellus. Vivamus lacinia neque eget risus cursus suscipit. Proin consequat dolor vel neque tempor, eu aliquam sem scelerisque. Duis non eros a purus malesuada pharetra non et nulla. Suspendisse potenti. Mauris libero eros, finibus vel nulla id, sagittis dapibus ante. Proin iaculis sed nunc et cursus. - -Quisque accumsan lorem sit amet lorem aliquet euismod. Curabitur fermentum rutrum posuere. Etiam ultricies, sem id pellentesque suscipit, urna magna lacinia eros, quis efficitur risus nisl at lacus. Nulla quis lacus tortor. Mauris placerat ex in dolor tincidunt, vel aliquet nisi pretium. Cras iaculis risus vitae pellentesque aliquet. Quisque a enim imperdiet, ullamcorper arcu vitae, rutrum risus. Nullam consectetur libero at felis fringilla, nec congue nibh dignissim. Nam et lobortis felis, eu pellentesque ligula. Aenean facilisis, ligula non imperdiet maximus, massa orci gravida sapien, at sagittis lacus nisl in lacus. Nulla quis mauris luctus, scelerisque felis consequat, tempus risus. Fusce auctor nisl non nulla luctus molestie. Maecenas sapien nisl, auctor non dolor et, iaculis scelerisque lorem. Suspendisse egestas enim aliquet, accumsan mauris nec, posuere quam. Nulla iaculis dui dui, sit amet vestibulum erat ultricies ac. - -Cras eget dolor erat. Proin at nisl ut leo consectetur ultricies vel ut arcu. Nulla in felis malesuada, ullamcorper tortor et, convallis massa. Nunc urna justo, ornare in nibh vitae, hendrerit condimentum libero. Etiam vitae libero in purus venenatis fringilla. Nullam velit nulla, consequat ut turpis non, egestas hendrerit nibh. Duis tortor turpis, interdum non ante ac, cursus accumsan lectus. Cras pharetra bibendum augue quis dictum. Sed euismod vestibulum justo. Proin porta lobortis purus. Duis venenatis diam tortor, sit amet condimentum eros rhoncus a. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc at magna nec diam lobortis efficitur sit amet ut lacus. Nulla quis orci tortor. Pellentesque tempus velit a odio finibus porta. - -Proin feugiat mauris a tellus scelerisque convallis. Maecenas libero magna, blandit nec ultrices id, congue vel mi. Aliquam lacinia, quam vel condimentum convallis, tortor turpis aliquam odio, sed blandit libero lacus et eros. In eleifend iaculis magna ac finibus. Praesent auctor facilisis tellus in congue. Sed molestie lobortis dictum. Nam quis dignissim augue, vel euismod lorem. Curabitur posuere dapibus luctus. Donec ultricies dictum lectus, quis blandit arcu commodo ac. Aenean tincidunt ligula in nunc imperdiet dignissim. Curabitur egestas sollicitudin sapien ut semper. Aenean nec dignissim lacus. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec aliquam dictum vehicula. Donec tortor est, volutpat non nisi nec, varius gravida ex. Nunc vel tristique nunc, vitae mattis nisi. Nunc nec luctus ex, vitae tincidunt lectus. In hac habitasse platea dictumst. Curabitur lobortis ex eget tincidunt tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut a vehicula mi. - -Fusce eu libero finibus, interdum nulla a, placerat neque. Cras bibendum tempor libero nec feugiat. Cras ut sodales eros. Proin viverra, massa sit amet viverra egestas, neque nisl porta ex, sit amet hendrerit libero ligula vel urna. Mauris suscipit lacus id justo rhoncus suscipit. Etiam vel libero tellus. Maecenas non diam molestie, condimentum tellus a, bibendum enim. Mauris aliquet imperdiet tellus, eget sagittis dolor. Sed blandit in neque et luctus. Cras elementum sagittis nunc, vel mollis lorem euismod et. Donec posuere at lacus eget suscipit. - -Nulla nunc mi, pretium non massa vel, tempor semper magna. Nunc a leo pulvinar, tincidunt nunc at, dignissim mi. Aliquam erat volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut viverra nulla a nisl finibus, at hendrerit ligula ullamcorper. Donec a lorem semper, tempor magna et, lobortis libero. Mauris id sapien leo. Donec dignissim, quam vitae porttitor dignissim, quam justo mattis dui, vel consequat odio elit quis orci. Etiam nec pretium neque, sit amet pretium orci. Duis ac tortor venenatis, feugiat purus non, feugiat nunc. Proin scelerisque nisl in turpis aliquam vulputate. - -Praesent sed est semper, fringilla lorem vitae, tincidunt nibh. Cras eros metus, auctor at mauris sit amet, sodales semper orci. Nunc a ornare ex. Curabitur bibendum arcu congue urna vulputate egestas. Vestibulum finibus id risus et accumsan. Aenean ut volutpat tellus. Aenean tincidunt malesuada urna sit amet vestibulum. Mauris vel tellus dictum, varius lacus quis, dictum arcu. - -Aenean quis metus eu erat feugiat cursus vel at ligula. Proin dapibus sodales urna, id euismod lectus tempus id. Pellentesque ex ligula, convallis et erat vel, vulputate condimentum nisl. Pellentesque pharetra nulla quis massa eleifend hendrerit. Praesent sed massa ipsum. Maecenas vehicula dolor massa, id sodales urna faucibus et. Mauris ac quam non massa tincidunt feugiat et at lacus. Fusce libero massa, vulputate vel scelerisque non, mollis in leo. Ut sit amet ultricies odio. Suspendisse in sapien viverra, facilisis purus ut, pretium libero. - -Vivamus tristique pharetra molestie. Nam a volutpat purus. Praesent consequat gravida nisi, ac blandit nisi suscipit ut. Quisque posuere, ligula a ultrices laoreet, ligula nunc vulputate libero, ut rutrum erat odio tincidunt justo. Sed vitae leo at leo fringilla bibendum. Vestibulum ut augue nec dolor auctor accumsan. Praesent laoreet id eros pulvinar commodo. Suspendisse potenti. Ut pharetra, mauris vitae blandit fringilla, odio ante tincidunt lorem, sit amet tempor metus diam ut turpis. - -Praesent quis egestas arcu. Nullam at porta arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi vulputate ligula malesuada ligula luctus, vulputate tempus erat bibendum. Nunc ullamcorper non lectus at euismod. Etiam nibh felis, tincidunt a metus vel, pellentesque rhoncus neque. Etiam at diam in erat luctus interdum. Nunc vel ipsum pulvinar, sollicitudin lacus ac, tempus urna. Etiam vel lacinia sapien. Pellentesque sagittis velit vel mi efficitur iaculis. Integer euismod sit amet urna in sagittis. Cras eleifend ut nibh in facilisis. Donec et lacus vitae nunc placerat sodales. Nulla sed hendrerit ligula, at dapibus sapien. - -Praesent at iaculis ex. Curabitur est purus, cursus a faucibus quis, dictum id velit. Donec dignissim fringilla viverra. Nunc mauris felis, laoreet sit amet sagittis at, vestibulum in libero. Maecenas quis orci turpis. Quisque ut nibh vitae magna mollis consequat id at mauris. Aliquam eu odio eget nulla bibendum sodales. Quisque vel orci eleifend nisi pretium lacinia. Suspendisse eget risus eget mi volutpat molestie eget quis lacus. Duis nisi libero, tincidunt nec nulla id, faucibus cursus felis. - -Donec tempor eget risus pellentesque molestie. Phasellus porta neque vel arcu egestas, nec blandit velit fringilla. Nullam porta faucibus justo vitae laoreet. Pellentesque viverra id nunc eu varius. Nulla pulvinar lobortis iaculis. Etiam vestibulum odio nec velit tristique, a tristique nisi mattis. In sed fringilla orci, vitae efficitur odio. Quisque dui odio, ornare eget velit at, lacinia consequat libero. Quisque lectus nulla, aliquet eu leo in, porta rutrum diam. Donec nec mattis neque. Nam rutrum, odio ac eleifend bibendum, dolor arcu rutrum neque, eget porta elit tellus a lacus. Sed massa metus, sollicitudin et sapien eu, finibus tempus orci. Proin et sapien sit amet erat molestie interdum. In quis rutrum velit, faucibus ultrices tellus. - -Sed sagittis sed justo eget tincidunt. Maecenas ut leo sagittis, feugiat magna et, viverra velit. Maecenas ex arcu, feugiat at consequat vitae, auctor eu massa. Integer egestas, enim vitae maximus convallis, est lectus pretium mauris, ac posuere lectus nisl quis quam. Aliquam tempus laoreet mi, vitae dapibus dolor varius dapibus. Suspendisse potenti. Donec sit amet purus nec libero dapibus tristique. Pellentesque viverra bibendum ligula. Donec sed felis et ex lobortis laoreet. Phasellus a fringilla libero, vitae malesuada nulla. Pellentesque blandit mattis lacus, et blandit tortor laoreet consequat. Suspendisse libero nunc, viverra sed fermentum in, accumsan egestas arcu. Proin in placerat elit. Sed interdum imperdiet malesuada. Suspendisse aliquet quis mauris eget sollicitudin. - -Vivamus accumsan tellus non erat volutpat, quis dictum dolor feugiat. Praesent rutrum nunc ac est mollis cursus. Fusce semper volutpat dui ut egestas. Curabitur sit amet posuere massa. Cras tincidunt nulla et mi mollis imperdiet. Suspendisse scelerisque ex id sodales vulputate. In nunc augue, pharetra in placerat eu, mattis id tellus. Vivamus cursus efficitur vehicula. Nulla aliquet vehicula aliquet. - -Sed cursus tellus sed porta pulvinar. Sed vitae nisi neque. Nullam aliquet, lorem et efficitur scelerisque, arcu diam aliquam felis, sed pulvinar lorem odio et turpis. Praesent convallis pulvinar turpis eu iaculis. Aliquam nec gravida mi. Curabitur eu nibh tempor, blandit justo in, ultrices felis. Fusce placerat metus non mi sagittis rutrum. Morbi sed dui fringilla, sagittis mauris eget, imperdiet nunc. Phasellus hendrerit sem elit, id hendrerit libero auctor sit amet. Integer sodales elit sit amet consequat cursus. - -Nam semper est eget nunc mollis, in pellentesque lectus fringilla. In finibus vel diam id semper. Nunc mattis quis erat eu consectetur. In hac habitasse platea dictumst. Nullam et ipsum vestibulum ex pulvinar ultricies sit amet id velit. Aenean suscipit mi tortor, a lobortis magna viverra non. Nulla condimentum aliquet ante et ullamcorper. Pellentesque porttitor arcu a posuere tempus. Aenean lacus quam, imperdiet eu justo vitae, pretium efficitur ex. Duis id purus id magna rhoncus ultrices id eu risus. Nunc dignissim et libero id dictum. - -Quisque a tincidunt neque. Phasellus commodo mi sit amet tempor fringilla. Ut rhoncus, neque non porttitor elementum, libero nulla egestas augue, sed fringilla sapien felis ac velit. Phasellus viverra rhoncus mollis. Nam ullamcorper leo vel erat laoreet luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus semper a metus a cursus. Nulla sed orci egestas, efficitur purus ac, malesuada tellus. Aenean rutrum velit at tellus fermentum mollis. Aliquam eleifend euismod metus. - -In hac habitasse platea dictumst. Vestibulum volutpat neque vitae porttitor laoreet. Nam at tellus consequat, sodales quam in, pulvinar arcu. Maecenas varius convallis diam, ac lobortis tellus pellentesque quis. Maecenas eget augue massa. Nullam volutpat nibh ac justo rhoncus, ut iaculis tellus rutrum. Fusce efficitur efficitur libero quis condimentum. Curabitur congue neque non tincidunt tristique. Fusce eget tempor ex, at pellentesque odio. Praesent luctus dictum vestibulum. Etiam non orci nunc. Vivamus vitae laoreet purus, a lobortis velit. Curabitur tincidunt purus ac lectus elementum pellentesque. Quisque sed tincidunt est. - -Sed vel ultrices massa, vitae ultricies justo. Cras finibus mauris nec lacus tempus dignissim. Cras faucibus maximus velit, eget faucibus orci luctus vehicula. Nulla massa nunc, porta ac consequat eget, rhoncus non tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce sed maximus metus, vel imperdiet ipsum. Ut scelerisque lectus at blandit porttitor. Ut vulputate nunc pharetra, aliquet sapien ac, sollicitudin sapien. Aenean eget ante lorem. Nam accumsan venenatis tellus id dignissim. - -Curabitur fringilla, magna non maximus dapibus, nulla sapien vestibulum lectus, sit amet semper dolor neque vitae nisl. Nunc ultrices vehicula augue sed iaculis. Maecenas nec diam mollis, suscipit orci et, vestibulum ante. Pellentesque eu nisl tortor. Nunc eleifend, lacus quis volutpat volutpat, nisi mi molestie sem, quis mollis ipsum libero a tellus. Ut viverra dolor mattis convallis interdum. Sed tempus nisl at nunc scelerisque aliquet. Quisque tempor tempor lorem id feugiat. Nullam blandit lectus velit, vitae porta lacus tincidunt a. Vivamus sit amet arcu ultrices, tincidunt mi quis, viverra quam. Aenean fringilla libero elementum lorem semper, quis pulvinar eros gravida. Nullam sodales blandit mauris, sed fermentum velit fermentum sit amet. Donec malesuada mauris in augue sodales vulputate. Vestibulum gravida turpis id elit rhoncus dignissim. Integer non congue lorem, eu viverra orci. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec at dolor magna. Aliquam consectetur erat augue, id iaculis velit pharetra ac. Integer rutrum venenatis dignissim. Integer non sodales elit. Curabitur ut magna ut nibh feugiat aliquam ac ut risus. Morbi nibh quam, aliquam id placerat nec, vestibulum eget velit. Suspendisse at dignissim quam. Vivamus aliquet sem sed nisl volutpat, ut cursus orci ultrices. Aliquam ultrices lacinia enim, vitae aliquet neque. - -Quisque scelerisque finibus diam in mattis. Cras cursus auctor velit. Aliquam sem leo, fermentum et maximus et, molestie a libero. Aenean justo elit, rutrum a ornare id, egestas eget enim. Aenean auctor tristique erat. Curabitur condimentum libero lacus, nec consequat orci vestibulum sed. Fusce elit ligula, blandit vitae sapien vitae, dictum ultrices risus. Nam laoreet suscipit sapien, at interdum velit faucibus sit amet. Duis quis metus egestas lectus elementum posuere non nec libero. Aliquam a dolor bibendum, facilisis nunc a, maximus diam. Vestibulum suscipit tristique magna, non dignissim turpis sodales sed. Nunc ornare, velit ac facilisis fringilla, dolor mi consectetur lorem, vitae finibus erat justo suscipit urna. Maecenas sit amet eros erat. Nunc non arcu ornare, suscipit lorem eget, sodales mauris. Aliquam tincidunt, quam nec mollis lacinia, nisi orci fermentum libero, consequat eleifend lectus quam et sapien. Vestibulum a quam urna. - -Cras arcu leo, euismod ac ullamcorper at, faucibus sed massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus porttitor velit in enim interdum, non commodo metus ornare. Morbi vel lorem quis nisl luctus tristique quis vitae nisl. Suspendisse condimentum tortor enim, nec eleifend ipsum euismod et. Sed gravida quam ut tristique lacinia. Mauris eu interdum ipsum, ac ultrices odio. Nullam auctor tellus a risus porttitor vehicula. Nulla blandit euismod dictum. In pharetra, enim iaculis pulvinar interdum, dui nunc placerat nunc, sit amet pretium lectus nulla vitae quam. Phasellus quis enim sollicitudin, varius nulla id, ornare purus. Donec quam lacus, vestibulum quis nunc ac, mollis dictum nisi. Cras ut mollis elit. Maecenas ultrices ligula at risus faucibus scelerisque. Etiam vitae porttitor purus. Curabitur blandit lectus urna, ut hendrerit tortor feugiat ut. - -Phasellus fringilla, sapien pellentesque commodo pharetra, ante libero aliquam tellus, ut consectetur augue libero a sapien. Maecenas blandit luctus nisl eget aliquet. Maecenas vitae porta dolor, faucibus laoreet sapien. Suspendisse lobortis, ipsum sed vehicula aliquam, elit purus scelerisque dui, rutrum consectetur diam odio et lorem. In nec lacinia metus. Donec viverra libero est, vel bibendum erat condimentum quis. Donec feugiat purus leo. In laoreet vitae felis a porttitor. Mauris ullamcorper, lacus id condimentum suscipit, neque magna pellentesque arcu, eget cursus neque tellus id metus. Curabitur volutpat ac orci vel ultricies. - -Sed ut finibus erat. Sed diam purus, varius non tincidunt quis, ultrices sit amet ipsum. Donec et egestas nulla. Suspendisse placerat nisi at dui laoreet iaculis. Aliquam aliquet leo at augue faucibus molestie. Nullam lacus augue, hendrerit sed nisi eu, faucibus porta est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam ut leo aliquet sem fermentum rutrum quis ac justo. Integer placerat aliquam nisl ut sagittis. Proin erat orci, lobortis et sem eget, eleifend fringilla augue. Mauris varius laoreet arcu, sed tincidunt felis. Pellentesque venenatis lorem odio, id pulvinar velit molestie feugiat. Donec mattis lacus sed eleifend pulvinar. - -Sed condimentum ex in tincidunt hendrerit. Etiam eget risus lacinia, euismod nibh eu, pellentesque quam. Proin elit eros, convallis id mauris ac, bibendum ultrices lectus. Morbi venenatis, purus id fermentum consequat, nunc libero tincidunt ligula, non dictum ligula orci nec quam. Nulla nec ultrices lorem. Aenean maximus augue vel dictum pharetra. Etiam turpis urna, pellentesque quis malesuada eu, molestie faucibus felis. - -Vestibulum pharetra augue ut quam blandit congue in nec risus. Proin eu nibh eu dui eleifend porta vitae id lectus. Proin lacus nibh, lobortis sed ligula vitae, interdum lobortis erat. Suspendisse potenti. In sollicitudin quis sapien ut aliquet. Mauris ac nulla arcu. Fusce tristique justo quis lectus mollis, eu volutpat lectus finibus. Vivamus venenatis facilisis ex ut vestibulum. - -Etiam varius lobortis purus, in hendrerit elit tristique at. In tempus, augue vestibulum fermentum gravida, ligula tellus vulputate arcu, eu molestie ex sapien at purus. Vestibulum nec egestas metus. Duis pulvinar quam nec consequat interdum. Aenean non dapibus lacus. Aliquam sit amet aliquet nulla. Sed venenatis volutpat purus nec convallis. Phasellus aliquet semper sodales. Cras risus sapien, condimentum auctor urna a, pulvinar ornare nisl. Sed tincidunt felis elit, ut elementum est bibendum ac. Morbi interdum justo vel dui faucibus condimentum. - -Sed convallis eu sem at tincidunt. Nullam at auctor est, et ullamcorper ipsum. Pellentesque eget ante ante. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer euismod, sapien sed dapibus ornare, nibh enim maximus lacus, lacinia placerat urna quam quis felis. Morbi accumsan id nisl ut condimentum. Donec bibendum nisi est, sed volutpat lorem rhoncus in. Vestibulum ac lacinia nunc, eget volutpat magna. Integer aliquam pharetra ipsum, id placerat nunc volutpat quis. Etiam urna diam, rhoncus sit amet varius vel, euismod vel sem. Nullam vel molestie urna. Vivamus ornare erat at venenatis euismod. Suspendisse potenti. Fusce diam justo, tincidunt vel sem at, commodo faucibus nisl. Duis gravida efficitur diam, vel sagittis erat pulvinar ut. - -Quisque vel pharetra felis. Duis efficitur tortor dolor, vitae porttitor erat fermentum sed. Sed eu mi purus. Etiam dignissim tortor eu tempus molestie. Aenean pretium erat enim, in hendrerit ante hendrerit at. Sed ut risus vel nunc venenatis ultricies quis in lacus. Pellentesque vitae purus euismod, placerat risus non, ullamcorper augue. Quisque varius quam ligula, nec aliquet ex faucibus vitae. Quisque rhoncus sit amet leo tincidunt mattis. Cras id mauris eget purus pretium gravida sit amet eu augue. Aliquam dapibus odio augue, id lacinia velit pulvinar eu. - -Mauris fringilla, tellus nec pharetra iaculis, neque nisi ultrices massa, et tincidunt sem dui sed mi. Curabitur erat lorem, venenatis quis tempus lacinia, tempus sit amet nunc. Aliquam at neque ac metus commodo dictum quis vitae justo. Phasellus eget lacus tempus, blandit lorem vel, rutrum est. Aenean pharetra sem ut augue lobortis dignissim. Sed rhoncus at nulla id ultrices. Cras id condimentum felis. In suscipit luctus vulputate. Donec tincidunt lacus nec enim tincidunt sollicitudin ut quis enim. Nam at libero urna. Praesent sit amet massa vitae massa ullamcorper vehicula. - -Nullam bibendum augue ut turpis condimentum bibendum. Proin sit amet urna hendrerit, sodales tortor a, lobortis lectus. Integer sagittis velit turpis, et tincidunt nisi commodo eget. Duis tincidunt elit finibus accumsan cursus. Aenean dignissim scelerisque felis vel lacinia. Nunc lacinia maximus luctus. In hac habitasse platea dictumst. Vestibulum eget urna et enim tempor tempor. Nam feugiat, felis vel vestibulum tempus, orci justo viverra diam, id dapibus lorem justo in ligula. - -Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In ac pellentesque sem. Vestibulum lacinia magna dui, eu lacinia augue placerat et. Maecenas pulvinar congue est. Pellentesque commodo dui non pulvinar scelerisque. Etiam interdum est posuere sem bibendum, ac commodo magna dictum. Cras ipsum turpis, rhoncus nec posuere vitae, laoreet a arcu. Integer ac massa sit amet enim placerat lacinia sed ultrices arcu. Suspendisse sem nibh, luctus sit amet volutpat in, pellentesque eu metus. Ut gravida neque eget mi accumsan tempus. Nam sit amet aliquet nibh. - -Pellentesque a purus cursus nulla hendrerit congue quis et odio. Aenean hendrerit, leo ullamcorper sagittis hendrerit, erat dui molestie quam, sed condimentum lacus risus sed tellus. Morbi a dapibus lectus, ut feugiat ex. Phasellus pretium quam et sapien mollis, vel iaculis dui dignissim. Sed ullamcorper est turpis, a viverra lorem consectetur in. Aenean aliquet nibh non cursus rutrum. Suspendisse at tristique urna, id lobortis urna. In hac habitasse platea dictumst. Phasellus libero velit, rutrum sed tellus nec, dapibus tincidunt ligula. Quisque vel dui venenatis, consequat nisl ut, lacinia ipsum. Phasellus vitae magna pellentesque, lobortis est id, faucibus quam. Nam eleifend faucibus dui vel pellentesque. - -Etiam ut est non lacus tincidunt interdum. Maecenas sed massa urna. Quisque ut nibh tortor. Pellentesque felis ipsum, tempor finibus ipsum et, euismod pretium metus. Donec sit amet est ipsum. Quisque rhoncus justo non finibus elementum. Nulla nec lectus ac tortor placerat fringilla. Phasellus ac ultrices nunc, eu efficitur nisl. Nulla rhoncus nunc vitae ante dictum tincidunt. Nunc ultrices, massa sit amet malesuada dignissim, lectus lacus consequat sapien, non eleifend metus sem in eros. Phasellus mauris ante, dictum sit amet suscipit ac, rhoncus eget nisi. Phasellus at orci mollis, imperdiet neque eget, faucibus nulla. In at purus massa. Pellentesque quis rutrum lectus. - -Integer eu faucibus turpis, sit amet mollis massa. Vestibulum id nulla commodo, rutrum ipsum sed, semper ante. Phasellus condimentum orci nec nibh convallis, ac maximus orci ullamcorper. Maecenas vitae sollicitudin mi. Integer et finibus lectus, et condimentum ligula. Donec elementum tristique quam vitae dapibus. Morbi euismod ipsum in tristique ullamcorper. - -Duis fermentum non enim eu auctor. Quisque lacinia nibh vehicula nibh posuere, eu volutpat turpis facilisis. Ut ac faucibus nulla. Sed eleifend quis ex et pellentesque. Vestibulum sollicitudin in libero id fringilla. Phasellus dignissim purus consequat, condimentum dui sit amet, condimentum ante. Pellentesque ac consectetur massa, quis sagittis est. Nulla maximus tristique risus accumsan convallis. Curabitur imperdiet ac lacus a ultrices. Nulla facilisi. Sed quis quam quis lectus placerat lobortis vel sed turpis. In mollis dui id neque iaculis, ut aliquet tellus malesuada. Proin at luctus odio, vel blandit sapien. Praesent dignissim tortor vehicula libero fringilla, nec ultrices erat suscipit. Maecenas scelerisque purus in dapibus fermentum. - -Curabitur magna odio, mattis in tortor ut, porttitor congue est. Vestibulum mollis lacinia elementum. Fusce maximus erat vitae nunc rutrum lobortis. Integer ligula eros, auctor vel elit non, posuere luctus lacus. Maecenas quis auctor massa. Ut ipsum lacus, efficitur posuere euismod et, hendrerit efficitur est. Phasellus fringilla, quam id tincidunt pretium, nunc dui sollicitudin orci, eu dignissim nisi metus ut magna. Integer lobortis interdum dolor, non bibendum purus posuere et. Donec non lectus aliquet, pretium dolor eu, cursus massa. Sed ut dui sapien. In sed vestibulum massa. Pellentesque blandit, dui non sodales vehicula, orci metus mollis nunc, non pharetra ex tellus ac est. Mauris sagittis metus et fermentum pretium. Nulla facilisi. Quisque quis ante ut nulla placerat mattis ut quis nisi. - -Sed quis nulla ligula. Quisque dignissim ligula urna, sed aliquam purus semper at. Suspendisse potenti. Nunc massa lectus, pharetra vehicula arcu bibendum, imperdiet sodales ipsum. Nam ac sapien diam. Mauris iaculis fringilla mattis. Pellentesque tempus eros sit amet justo volutpat mollis. Phasellus ac turpis ipsum. Morbi vel ante elit. Aenean posuere quam consequat velit varius suscipit. Donec tempor quam ut nibh cursus efficitur. - -Morbi molestie dolor nec sem egestas suscipit. Etiam placerat pharetra lectus, et ullamcorper risus tristique in. Sed faucibus ullamcorper lectus eget fringilla. Maecenas malesuada hendrerit congue. Sed eget neque a erat placerat tincidunt. Aliquam vitae dignissim turpis. Fusce at placerat magna, a laoreet lectus. Maecenas a purus nec diam gravida fringilla. Nam malesuada euismod ante non vehicula. In faucibus bibendum leo, faucibus posuere nisl pretium quis. Fusce finibus bibendum finibus. Vestibulum eu justo maximus, hendrerit diam nec, dignissim sapien. Aenean dolor lacus, malesuada quis vestibulum ac, venenatis ac ipsum. Cras a est id nunc finibus facilisis. Cras lacinia neque et interdum vehicula. Suspendisse vulputate tellus elit, eget tempor dui finibus vel. - -Cras sed pretium odio. Proin hendrerit elementum felis in tincidunt. Nam sed turpis vel justo molestie accumsan condimentum eu nunc. Praesent lobortis euismod rhoncus. Nulla vitae euismod nibh, quis mattis mi. Fusce ultrices placerat porttitor. Duis sem ipsum, pellentesque sit amet odio a, molestie vulputate mauris. - -Duis blandit mollis ligula, sit amet mattis ligula finibus sit amet. Nunc a leo molestie, placerat diam et, vestibulum leo. Suspendisse facilisis neque purus, nec pellentesque ligula fermentum nec. Aenean malesuada mauris lorem, eu blandit arcu pulvinar quis. Duis laoreet urna lacus, non maximus arcu rutrum ultricies. Nulla augue dolor, suscipit eu mollis eu, aliquam condimentum diam. Ut semper orci luctus, pharetra turpis at, euismod mi. Nulla leo diam, finibus sit amet purus sed, maximus dictum lorem. Integer eu mi id turpis laoreet rhoncus. - -Integer a mauris tincidunt, finibus orci ut, pretium mauris. Nulla molestie nunc mi, id finibus lorem elementum sed. Proin quis laoreet ante. Integer nulla augue, commodo id molestie quis, rutrum ut turpis. Suspendisse et tortor turpis. Sed ut pharetra massa. Pellentesque elementum blandit sem, ut elementum tellus egestas a. Fusce eu purus nibh. - -Cras dignissim ligula scelerisque magna faucibus ullamcorper. Proin at condimentum risus, auctor malesuada quam. Nullam interdum interdum egestas. Nulla aliquam nisi vitae felis mollis dictum. Suspendisse dapibus consectetur tortor. Ut ut nisi non sem bibendum tincidunt. Vivamus suscipit leo quis gravida dignissim. - -Aliquam interdum, leo id vehicula mollis, eros eros rhoncus diam, non mollis ligula mi eu mauris. Sed ultrices vel velit sollicitudin tincidunt. Nunc auctor metus at ligula gravida elementum. Praesent interdum eu elit et mollis. Duis egestas quam sit amet velit dignissim consequat. Aliquam ac turpis nec nunc convallis sagittis. Fusce blandit, erat ac fringilla consectetur, dolor eros sodales leo, vel aliquet risus nisl et diam. Aliquam luctus felis vitae est eleifend euismod facilisis et lacus. Sed leo tellus, auctor eu arcu in, volutpat sagittis nisl. Pellentesque nisl ligula, placerat vel ullamcorper at, vulputate ac odio. Morbi ac faucibus orci, et tempus nulla. Proin rhoncus rutrum dolor, in venenatis mauris. Suspendisse a fermentum augue, non semper mi. Nunc eget pretium neque. Phasellus augue erat, feugiat ac aliquam congue, rutrum non sapien. Pellentesque ac diam gravida, consectetur felis at, ornare neque. - -Nullam interdum mattis sapien quis porttitor. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus aliquet rutrum ipsum id euismod. Maecenas consectetur massa et mi porta viverra. Nunc quam nibh, dignissim vitae maximus et, ullamcorper nec lorem. Nunc vitae justo dapibus, luctus lacus vitae, pretium elit. Maecenas et efficitur leo. Curabitur mauris lectus, placerat quis vehicula vitae, auctor ut urna. Quisque rhoncus pharetra luctus. In hac habitasse platea dictumst. Integer sit amet metus nec eros malesuada aliquam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi hendrerit mi ac leo aliquam, sit amet ultricies libero commodo. Mauris dapibus purus metus, sit amet viverra nibh imperdiet et. Nullam porta nulla tellus, quis vehicula diam imperdiet non. Vivamus enim massa, bibendum in fermentum in, ultrices at ex. - -Suspendisse fermentum id nibh eget accumsan. Duis dapibus bibendum erat ut sollicitudin. Aliquam nec felis risus. Pellentesque rhoncus ligula id sem maximus mollis sed nec massa. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ipsum ipsum, sodales sed enim id, convallis faucibus eros. Donec ultricies dictum tincidunt. Cras vitae nibh arcu. Pellentesque cursus, sapien nec consequat fermentum, ipsum ante suscipit dui, imperdiet hendrerit est nisl eu massa. Quisque vitae sem ligula. Aenean iaculis metus ut mauris interdum laoreet. Vivamus sed gravida dolor. - -Morbi nulla metus, porttitor sed eros sit amet, efficitur efficitur est. In vel nisl urna. Ut aliquet tellus at congue convallis. Phasellus imperdiet lobortis sollicitudin. Integer sodales, sem eu ultricies pharetra, erat erat porttitor odio, eget dapibus libero ipsum eget velit. Phasellus gravida nulla nisl, eu pharetra mi auctor vel. Sed blandit pharetra velit, ut egestas libero placerat non. Aliquam a interdum quam. Proin at tortor nec dui sollicitudin tempus sed vestibulum elit. Nunc non sollicitudin velit. - -Aenean consequat diam velit, sed rutrum tortor faucibus dictum. Quisque at semper augue. Duis ut est eget mi ornare bibendum id et ligula. Phasellus consequat tortor non leo pulvinar posuere. Proin vestibulum eleifend felis, in hendrerit tortor sollicitudin eu. Phasellus hendrerit, lacus vel laoreet interdum, dui tortor consequat justo, commodo ultricies arcu felis vitae enim. Vivamus eu sapien at leo suscipit rutrum eu at justo. Aenean et dolor a libero ullamcorper posuere. Integer laoreet placerat nisi in vulputate. Mauris laoreet eget risus sed cursus. Donec scelerisque neque a libero eleifend hendrerit. Nulla varius condimentum nunc sit amet fermentum. Aliquam lorem ex, varius nec mollis ut, ultrices in neque. Morbi sit amet porta leo. Integer iaculis fermentum lacus in vestibulum. - -Ut gravida, tellus ut maximus ultrices, erat est venenatis nisl, vitae pretium massa ex ac magna. Sed non purus eget ligula aliquet volutpat non quis arcu. Nam aliquam tincidunt risus, sit amet fringilla sapien vulputate ut. Mauris luctus suscipit pellentesque. Nunc porttitor dapibus ex quis tempus. Ut ullamcorper metus a eros vulputate, vitae viverra lectus convallis. Mauris semper imperdiet augue quis tincidunt. Integer porta pretium magna, sed cursus sem scelerisque sollicitudin. Nam efficitur, nibh pretium eleifend vestibulum, purus diam posuere sem, in egestas mauris augue sit amet urna. - -Vestibulum tincidunt euismod massa in congue. Duis interdum metus non laoreet fringilla. Donec at ligula congue, tincidunt nunc non, scelerisque nunc. Donec bibendum magna non est scelerisque feugiat at nec neque. Ut orci tortor, tempus eget massa non, dignissim faucibus dolor. Nam odio risus, accumsan pretium neque eget, accumsan dignissim dui. In ut neque auctor, scelerisque tellus sed, ullamcorper nisi. Suspendisse varius cursus quam at hendrerit. Vivamus elit libero, sagittis vitae sem ac, vulputate iaculis ligula. - -Sed lobortis laoreet purus sit amet rutrum. Pellentesque feugiat non leo vel lacinia. Quisque feugiat nisl a orci bibendum vestibulum. In et sollicitudin urna. Morbi a arcu ac metus faucibus tempus. Nam eu imperdiet sapien, suscipit mattis tortor. Aenean blandit ipsum nisi, a eleifend ligula euismod at. Integer tincidunt pharetra felis, mollis placerat mauris hendrerit at. Curabitur convallis, est sit amet luctus volutpat, massa lacus cursus augue, sed eleifend magna quam et risus. Aliquam lobortis tincidunt metus vitae porttitor. Suspendisse potenti. Aenean ullamcorper, neque id commodo luctus, nulla nunc lobortis quam, id dapibus neque dui nec mauris. Etiam quis lorem quis elit commodo ornare. Ut pharetra purus ultricies enim ultrices efficitur. Proin vehicula tincidunt molestie. Mauris et placerat sem. - -Aliquam erat volutpat. Suspendisse velit turpis, posuere ac lacus eu, lacinia laoreet velit. Sed interdum felis neque, id blandit sem malesuada sit amet. Ut sagittis justo erat, efficitur semper orci tempor sed. Donec enim massa, posuere varius lectus egestas, pellentesque posuere mi. Cras tincidunt ut libero sed mattis. Suspendisse quis magna et tellus posuere interdum vel at purus. Pellentesque fringilla tristique neque, id aliquet tellus ultricies non. Duis ut tellus vel odio lobortis vulputate. - -Integer at magna ac erat convallis vestibulum. Sed lobortis porttitor mauris. Fusce varius lorem et volutpat pulvinar. Aenean ac vulputate lectus, vitae consequat velit. Suspendisse ex dui, varius ut risus ut, dictum scelerisque sem. Vivamus urna orci, volutpat ut convallis ac, venenatis vitae urna. In hac habitasse platea dictumst. Etiam eu purus arcu. Aenean vulputate leo urna, vel tristique dui sagittis euismod. Suspendisse non tellus efficitur ante rhoncus volutpat at et sapien. - -Sed dapibus accumsan porttitor. Phasellus facilisis lectus finibus ligula dignissim, id pulvinar lectus feugiat. Nullam egestas commodo nisi posuere aliquet. Morbi sit amet tortor sagittis, rutrum dui nec, dapibus sapien. Sed posuere tortor tortor, interdum auctor magna varius vitae. Vestibulum id sagittis augue. Curabitur fermentum arcu sem, eu condimentum quam rutrum non. Phasellus rutrum nibh quis lectus rhoncus pretium. Curabitur dictum interdum elit. Vestibulum maximus sodales imperdiet. Mauris auctor nec purus sed venenatis. In in urna purus. - -Duis placerat molestie suscipit. Morbi a elit id purus efficitur consequat. Nunc ac commodo turpis. Etiam sit amet lacus a ipsum tempus venenatis sed vel nibh. Duis elementum aliquam mi sed tristique. Morbi ligula tortor, semper ac est vel, lobortis maximus erat. Curabitur ipsum felis, laoreet vel condimentum eget, ullamcorper sit amet mauris. Nulla facilisi. Nam at purus sed mi egestas placerat vitae vel magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse at dignissim diam. Phasellus consectetur eget neque vel viverra. Donec sollicitudin mattis dolor vel malesuada. Vivamus vehicula leo neque, vitae fermentum leo posuere et. Praesent dui est, finibus sit amet tristique quis, pharetra vel nibh. - -Duis nulla leo, accumsan eu odio eget, sagittis semper orci. Quisque ullamcorper ligula quam, commodo porttitor mauris ullamcorper eu. Cras varius sagittis felis in aliquam. Duis sodales risus ac justo vehicula, nec mattis diam lacinia. Cras eget lectus ipsum. Ut commodo, enim vitae malesuada hendrerit, ex dolor egestas lectus, sit amet hendrerit metus diam nec est. Vestibulum tortor metus, lobortis sit amet ante eget, tempor molestie lacus. In molestie et urna et semper. Mauris mollis, sem non hendrerit condimentum, sapien nisi cursus est, non suscipit quam justo non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam enim est, porta ac feugiat vitae, rutrum in lorem. Duis vehicula tortor ut posuere maximus. - -Nullam vestibulum non tellus sed commodo. Quisque mattis elit sit amet sapien sollicitudin, ut condimentum nisl congue. Aenean sagittis massa vel elit faucibus fermentum. Donec tincidunt nisi nec nisl sodales pellentesque. Mauris congue congue ligula ut suscipit. Vivamus velit tortor, tempor et gravida eget, fermentum sit amet ante. Nullam fringilla, lorem at ultrices cursus, urna neque ornare dolor, eu lacinia orci enim sed nibh. Ut a ullamcorper lectus, id mattis purus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean maximus sollicitudin posuere. Nunc at augue lacus. Aenean efficitur leo sit amet lacinia efficitur. - -Quisque venenatis quam mi, in pharetra odio vulputate eu. In vel nisl pulvinar, pulvinar ligula ut, sodales risus. Sed efficitur lectus at vestibulum tincidunt. Vestibulum eu ullamcorper elit. Fusce vestibulum magna enim, et tempor lacus posuere vitae. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer leo elit, luctus nec mattis sit amet, sollicitudin in turpis. - -Proin convallis venenatis leo, vitae tristique erat iaculis nec. Nulla facilisi. Duis porttitor, sapien et bibendum vulputate, sem libero sodales lacus, non malesuada felis erat ut libero. Nam non felis semper, finibus est a, mattis mauris. Praesent nec eros quam. Nulla hendrerit, augue consectetur eleifend ultricies, purus mi condimentum nulla, eget dapibus est nunc sed libero. Nullam elementum dui erat, vitae luctus libero sollicitudin et. Nulla odio magna, placerat in augue eu, dapibus imperdiet odio. Suspendisse imperdiet metus sit amet rhoncus dapibus. Cras at enim et urna vehicula cursus eu a mauris. Integer magna ante, eleifend ac placerat vitae, porta at nisi. Cras eget malesuada orci. Curabitur nunc est, vulputate id viverra et, dignissim sed odio. Curabitur non mattis sem. Sed bibendum, turpis vitae vehicula faucibus, nunc quam ultricies lectus, vitae viverra felis turpis at libero. - -Nullam ut egestas ligula. Proin hendrerit justo a lectus commodo venenatis. Nulla facilisi. Ut cursus lorem quis est bibendum condimentum. Aenean in tristique odio. Fusce tempor hendrerit ipsum. Curabitur mollis felis justo, quis dapibus erat auctor vel. Sed augue lectus, finibus ut urna quis, ullamcorper vestibulum dui. Etiam molestie aliquam tempor. Integer mattis sollicitudin erat, et tristique elit varius vel. Mauris a ex justo. - -Nam eros est, imperdiet non volutpat rutrum, pellentesque accumsan ligula. Duis sit amet turpis metus. Aenean in rhoncus metus, ac fringilla ex. Suspendisse condimentum egestas purus, ut pharetra odio vulputate vel. Duis tincidunt massa a placerat ultrices. Mauris ultricies nibh sit amet condimentum malesuada. Duis tincidunt id ipsum sed congue. - -Praesent eu ex augue. Nullam in porta ligula. In tincidunt accumsan arcu, in pellentesque magna tristique in. Mauris eleifend libero ac nisl viverra faucibus. Nam sollicitudin dolor in commodo hendrerit. Cras at orci metus. Ut quis laoreet orci. Vivamus ultrices leo pellentesque tempor aliquet. Maecenas ut eros vitae purus placerat vestibulum. Etiam vitae gravida dolor, quis rhoncus diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. - -Suspendisse fringilla lacinia sagittis. Integer tincidunt consectetur tristique. Morbi non orci convallis, congue sapien quis, vulputate nunc. Donec a libero vel magna elementum facilisis non quis mi. Mauris posuere tellus non ipsum ultrices elementum. Vivamus massa velit, facilisis quis placerat aliquet, aliquet nec leo. Praesent a maximus sem. Sed neque elit, feugiat vel quam non, molestie sagittis nunc. Etiam luctus nunc ac mauris scelerisque, nec rhoncus lacus convallis. Nunc pharetra, nunc ac pulvinar aliquam, ex ipsum euismod augue, nec porttitor lacus turpis vitae neque. Fusce bibendum odio id tortor faucibus pellentesque. Sed ac porta nibh, eu gravida erat. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam quis ullamcorper felis. Nulla mattis sagittis ante ac tincidunt. Integer ac felis efficitur, viverra libero et, facilisis ligula. Suspendisse a metus a massa rhoncus posuere. Phasellus suscipit ligula ut lacus facilisis, ac pellentesque ex tempor. Quisque consectetur massa mi, ac molestie libero dictum quis. Proin porttitor ligula quis erat tincidunt venenatis. Proin congue nunc sed elit gravida, nec consectetur lectus sodales. Etiam tincidunt convallis ipsum at vestibulum. Quisque maximus enim et mauris porttitor, et molestie magna tristique. Morbi vitae metus elit. Maecenas sed volutpat turpis. Aliquam vitae dolor vestibulum, elementum purus eget, dapibus nibh. Nullam egestas dui ac rutrum semper. - -Etiam hendrerit est metus, et condimentum metus aliquam ac. Pellentesque id neque id ipsum rhoncus vulputate. Aliquam erat nisl, posuere sit amet ligula ac, fermentum blandit felis. Vivamus fermentum mi risus, non lacinia purus viverra id. Aenean ac sapien consequat, finibus mauris nec, porta sem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed quis consectetur ex, dignissim bibendum nulla. Phasellus ac libero at quam vehicula euismod non eu leo. Phasellus a sapien augue. - -Maecenas ligula dui, bibendum vitae mauris et, auctor laoreet felis. Duis non libero a mi semper mattis. Quisque consequat luctus massa, quis tristique eros auctor feugiat. Maecenas sodales euismod neque vitae facilisis. Nullam laoreet imperdiet velit at pellentesque. Etiam massa odio, facilisis a consequat vitae, placerat vel magna. Nunc sagittis eros nec urna fringilla, pulvinar vestibulum nibh scelerisque. Sed magna metus, cursus eu consequat et, pharetra a est. Suspendisse elementum neque a dui malesuada lacinia. Donec sed ipsum volutpat, cursus urna id, ullamcorper arcu. Maecenas laoreet nisl eget velit egestas sollicitudin. Etiam nisl turpis, mollis id dignissim vitae, tristique vehicula ante. Maecenas eget placerat est, at rutrum augue. Vivamus faucibus lacinia ullamcorper. Sed pulvinar urna sodales ante sodales, at gravida leo dictum. - -Morbi maximus, quam a lobortis bibendum, enim felis varius elit, ac vehicula elit nisl ut lacus. Quisque ut arcu augue. Praesent id turpis quam. Sed sed arcu eros. Maecenas at cursus lorem, ac eleifend nisi. Fusce mattis felis at commodo pharetra. Praesent ac commodo ipsum. Quisque finibus et eros vitae tincidunt. In hac habitasse platea dictumst. Praesent purus ipsum, luctus lobortis ornare quis, auctor eget justo. Nam vel enim sollicitudin, faucibus tortor eu, sagittis eros. Ut nec consectetur erat. Donec ultricies malesuada ligula, a hendrerit sapien volutpat in. Maecenas sed enim vitae sapien pulvinar faucibus. - -Proin semper nunc nibh, non consequat neque ullamcorper vel. Maecenas lobortis sagittis blandit. Aenean et arcu ultricies turpis malesuada malesuada. Ut quam ex, laoreet ut blandit cursus, feugiat vitae dolor. Etiam ex lacus, scelerisque vel erat vel, efficitur tincidunt magna. Morbi tristique lacinia dolor, in egestas magna ultrices vitae. Integer ultrices leo ac tempus venenatis. Praesent ac porta tortor. Vivamus ornare blandit tristique. Nulla rutrum finibus pellentesque. In non dui elementum, fermentum ipsum vel, varius magna. Pellentesque euismod tortor risus, ac pellentesque nisl faucibus eget. - -Vivamus eu enim purus. Cras ultrices rutrum egestas. Sed mollis erat nibh, at posuere nisl luctus nec. Nunc vulputate, sapien id auctor molestie, nisi diam tristique ante, non convallis tellus nibh at orci. Morbi a posuere purus, in ullamcorper ligula. Etiam elementum sit amet dui imperdiet iaculis. Proin vitae tincidunt ipsum, sit amet placerat lectus. Curabitur commodo sapien quam, et accumsan lectus fringilla non. Nullam eget accumsan enim, ac pharetra mauris. Sed quis tristique velit, vitae commodo nisi. Duis turpis dui, maximus ut risus at, finibus consequat nunc. Maecenas sed est accumsan, aliquet diam in, facilisis risus. Curabitur vehicula rutrum auctor. Nam iaculis risus pulvinar maximus viverra. Nulla vel augue et ex sagittis blandit. - -Ut sem nulla, porta ac ante ac, posuere laoreet eros. Donec sodales posuere justo a auctor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras mollis at orci hendrerit porta. Nullam sodales tortor tortor, non lacinia diam finibus id. Duis libero orci, suscipit ac odio et, dictum consequat ipsum. Pellentesque eu ligula sagittis, volutpat eros at, lacinia lorem. Cras euismod tellus in iaculis tempor. Quisque accumsan, magna a congue venenatis, ante ipsum aliquam lectus, at egestas enim nunc at justo. Quisque sem purus, viverra ut tristique ut, maximus id enim. Etiam quis placerat sem. In sollicitudin, lacus eu rutrum mollis, nulla eros luctus elit, vel dapibus urna purus nec urna. Phasellus egestas massa quam, ac molestie erat hendrerit a. Praesent ultrices neque ut turpis molestie auctor. Etiam molestie placerat purus, et euismod erat aliquam in. Morbi id suscipit justo. - -Proin est ante, consequat at varius a, mattis quis felis. Sed accumsan nibh sit amet ipsum elementum posuere. Vestibulum bibendum id diam sit amet gravida. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi nec dolor vel ipsum dignissim hendrerit vel non ipsum. Praesent facilisis orci quis elit auctor lobortis. Phasellus cursus risus lectus, vel lobortis libero dapibus in. Quisque tristique tempus leo a pulvinar. Pellentesque a magna tincidunt, pellentesque massa nec, laoreet orci. Morbi congue ornare dolor quis commodo. Phasellus massa nisi, tincidunt at eros dictum, hendrerit lobortis urna. Maecenas porta, magna id mattis molestie, nibh tellus lobortis sem, eget tincidunt ipsum quam eu turpis. - -Ut gravida orci risus, vel rutrum mauris vehicula id. Etiam bibendum, neque a placerat condimentum, ex orci imperdiet lectus, quis dapibus arcu lacus eget lectus. Sed consequat non mi sit amet venenatis. Fusce vestibulum erat libero, eget hendrerit risus vulputate sollicitudin. Integer sed eleifend felis. Donec commodo, sem eu mattis placerat, urna odio aliquam tellus, et laoreet justo tellus eget erat. Fusce sed suscipit tortor. Nam hendrerit nibh ac nunc auctor lacinia. Pellentesque placerat condimentum ipsum, eget semper tortor hendrerit vel. Nullam non urna eu lacus pellentesque congue ut id eros. - -Nunc finibus leo in rhoncus tristique. Sed eu ipsum nec nisl egestas faucibus eget a felis. Pellentesque vitae nisi in nulla accumsan fermentum. Sed venenatis feugiat eleifend. Fusce porttitor varius placerat. Aliquam aliquet lacus sit amet mattis mollis. Sed vel nulla quis dolor suscipit vehicula ac viverra lorem. Duis viverra ipsum eget nulla ullamcorper fermentum. Mauris tincidunt arcu quis quam fringilla ornare. Donec et iaculis tortor. Nam ultricies libero vel ipsum aliquet efficitur. Morbi eget dolor aliquam, tempus sapien eget, viverra ante. Donec varius mollis ex, sed efficitur purus euismod interdum. Quisque vel sapien non neque tincidunt semper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. - -Suspendisse sit amet purus leo. Fusce lectus lorem, aliquam ac nulla eget, imperdiet ornare eros. Nullam sem augue, varius in nisi non, sollicitudin pellentesque ante. Etiam eu odio condimentum, tempor libero et, egestas arcu. Cras pellentesque eleifend aliquet. Pellentesque non blandit ligula. Ut congue viverra rhoncus. Phasellus mattis mi ac eros placerat, eu feugiat tellus ultrices. Aenean mollis laoreet libero eu imperdiet. Cras sed pulvinar mi, ac vehicula ligula. Vestibulum sit amet ex massa. In a egestas eros. - -Mauris pretium ipsum risus, venenatis cursus ante imperdiet id. Praesent eu turpis nec risus feugiat maximus ullamcorper ac lectus. Integer placerat at mi vel dapibus. Vestibulum fermentum turpis sit amet turpis viverra, id aliquet diam suscipit. Nam nec ex sed ante ullamcorper pharetra quis sit amet risus. Sed ac faucibus velit, id feugiat nibh. Nullam eget ipsum ex. Vivamus tincidunt non nunc non faucibus. Quisque bibendum viverra facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at nisi hendrerit quam suscipit egestas. Curabitur laoreet maximus ultricies. Duis ut tellus ac augue molestie dictum. - -Suspendisse rhoncus iaculis erat, ut ullamcorper est tristique eget. Donec auctor nec risus at gravida. Vivamus volutpat vulputate tellus, vel ultricies eros suscipit eget. Ut pulvinar id mi eu tempus. Morbi malesuada augue in dui varius, nec blandit neque vehicula. Donec ornare nec nisl in mollis. Morbi enim nisi, rhoncus nec est id, dapibus tempus urna. Ut id elit a felis vestibulum consectetur. Duis lectus quam, pharetra sit amet diam sed, posuere vestibulum erat. Fusce vitae maximus massa. Nullam id metus tempus, iaculis risus eu, lobortis urna. Quisque in congue urna. Pellentesque placerat neque in augue dapibus, non varius ex malesuada. Curabitur ut eleifend libero. Fusce vitae ligula luctus, fermentum enim vitae, ultrices erat. - -Sed viverra augue turpis, scelerisque egestas sapien mattis eu. Duis laoreet magna at ex pharetra dapibus. Praesent eget odio vel quam venenatis dictum. Nulla in sollicitudin dolor. Mauris lobortis nec eros vel rhoncus. Vestibulum porta viverra venenatis. Curabitur vel scelerisque quam, a egestas velit. Praesent volutpat tincidunt magna at laoreet. - -Cras nec lorem odio. Pellentesque quis dui urna. Praesent at tellus ac lectus scelerisque placerat nec eu risus. Vestibulum sit amet mattis ligula. Vivamus sed nisi at leo elementum accumsan at sit amet arcu. Aenean mattis tellus nec leo gravida, eget hendrerit nisl faucibus. Mauris pellentesque luctus condimentum. Maecenas pretium sapien nunc, eget commodo dolor maximus id. Mauris vestibulum accumsan massa a dictum. Phasellus interdum quam ligula, ut maximus diam blandit aliquam. Nunc vitae ex eu erat condimentum consectetur. Maecenas interdum condimentum volutpat. - -Donec et enim a libero rutrum laoreet. Praesent a condimentum sem, at tincidunt quam. In vel molestie risus. Sed urna dui, molestie vitae mollis laoreet, tempor quis lectus. Praesent vitae auctor est, et aliquet nunc. Curabitur vulputate blandit nulla, at gravida metus. Maecenas gravida dui eu iaculis tristique. Pellentesque posuere turpis nec auctor eleifend. Suspendisse bibendum diam eu tellus lobortis, et laoreet quam congue. In hac habitasse platea dictumst. Morbi dictum neque velit, eget rutrum eros ultrices sit amet. - -Phasellus fermentum risus pharetra consectetur bibendum. Donec magna tortor, lacinia vitae nibh quis, aliquet pretium lorem. Donec turpis nisi, pretium eu enim volutpat, mattis malesuada augue. Nullam vel tellus iaculis, sollicitudin elit eget, tincidunt lacus. Fusce elementum elementum felis et iaculis. Suspendisse porta eros nec neque malesuada, in malesuada ante sollicitudin. Vivamus bibendum viverra molestie. - -Integer feugiat, erat nec convallis aliquam, velit felis congue erat, molestie eleifend tellus erat in tellus. Nunc et justo purus. Donec egestas fermentum dui non feugiat. Quisque in sapien sagittis, gravida quam id, iaculis lectus. Cras sagittis rhoncus bibendum. Fusce quis metus in velit scelerisque tincidunt at non ipsum. Vivamus efficitur ante eu odio vulputate, vitae ultricies risus vehicula. Proin eget odio eu sem tincidunt feugiat vel id lorem. - -Vestibulum sit amet nulla dignissim, euismod mi in, fermentum tortor. Donec ut aliquet libero, lacinia accumsan velit. Donec et nulla quam. Nullam laoreet odio nec nunc imperdiet, a congue eros venenatis. Quisque nec tellus sit amet neque interdum posuere. Duis quis mi gravida, tincidunt diam convallis, ultricies augue. Mauris consequat risus non porttitor congue. Ut in ligula consequat, viverra nunc a, eleifend enim. Duis ligula urna, imperdiet nec facilisis et, ornare eu ex. Proin lobortis lectus a lobortis porttitor. Nulla leo metus, egestas eu libero sed, pretium faucibus felis. Vestibulum non sem tortor. Nam cursus est leo. Vivamus luctus enim odio, non interdum sem dapibus a. Aenean accumsan consequat lectus in imperdiet. - -Donec vehicula laoreet ipsum in posuere. Quisque vel quam imperdiet, sollicitudin nisi quis, suscipit velit. Morbi id sodales mauris. Curabitur tellus arcu, feugiat sed dui sit amet, sodales sagittis libero. Aenean vel suscipit metus, non placerat leo. Vestibulum quis nulla elit. Proin scelerisque non ante ut commodo. Interdum et malesuada fames ac ante ipsum primis in faucibus. - -Sed non urna dolor. Suspendisse convallis mi porta pulvinar ultrices. Suspendisse quam ipsum, hendrerit non scelerisque molestie, interdum dictum nunc. Morbi condimentum condimentum turpis eu luctus. Pellentesque sagittis sollicitudin odio, sed ultricies felis ornare sit amet. Sed ultrices ex leo, a tincidunt nisl gravida sed. Nullam ornare accumsan porta. Praesent consectetur id est nec sollicitudin. - -In hac habitasse platea dictumst. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sed ultrices nibh. Duis accumsan suscipit eros, a dictum odio tempus sit amet. Aenean imperdiet erat ac lacus finibus, scelerisque cursus massa imperdiet. Mauris molestie risus ut lacinia posuere. Nulla et sodales purus. Maecenas orci erat, placerat in tristique quis, placerat in mi. - -Donec sollicitudin pellentesque odio in feugiat. Morbi eu dolor ut mauris congue sollicitudin. Aliquam erat volutpat. Nulla id varius dui. Curabitur finibus urna ante, consectetur interdum nisi volutpat a. Quisque quis mi tristique, consequat tellus eget, rutrum sapien. Vivamus vitae tellus vulputate, rutrum ex eu, vulputate sem. Suspendisse viverra lorem tellus, vel interdum orci gravida quis. Ut laoreet arcu at mi ullamcorper finibus. Duis porta sagittis vestibulum. Sed commodo nisl vitae urna sollicitudin, nec lacinia est sodales. Curabitur imperdiet sodales dui sed iaculis. Sed ac tellus maximus, eleifend quam sit amet, feugiat elit. Aenean viverra, dui at mattis varius, est odio vestibulum sapien, sit amet mollis libero massa nec velit. Etiam quis sodales justo. - -Ut ultricies, sem eget sodales feugiat, nunc arcu congue elit, ac tempor justo massa nec purus. Maecenas enim nunc, pharetra eget dictum sit amet, tempus pellentesque velit. Suspendisse venenatis ligula in nulla mattis, et imperdiet ex tincidunt. Etiam vulputate, tellus et ultrices suscipit, enim velit laoreet massa, vitae congue odio enim ac urna. Morbi quam lorem, iaculis ac varius sagittis, euismod quis dolor. In ut dui eu purus feugiat consectetur. Vestibulum cursus velit quis lacus pellentesque iaculis. Cras in risus sed mauris porta rutrum. Nulla facilisi. Nullam eu bibendum est, non pellentesque lectus. Sed imperdiet feugiat lorem, quis convallis ante auctor in. Maecenas justo magna, scelerisque sit amet tellus eget, varius elementum risus. Duis placerat et quam sed varius. - -Duis nec nibh vitae nibh dignissim mollis quis sed felis. Curabitur vitae quam placerat, venenatis purus ut, euismod nisl. Curabitur porttitor nibh eu pulvinar ullamcorper. Suspendisse posuere nec ipsum ac dapibus. Cras convallis consectetur urna. Phasellus a nibh in dolor lacinia posuere id eget augue. In eu pharetra lorem, vitae cursus lacus. Aliquam tincidunt nibh lectus. Aenean facilisis ultricies posuere. Sed ut placerat orci. Curabitur scelerisque gravida blandit. Maecenas placerat ligula eget suscipit fringilla. Mauris a tortor justo. Aliquam hendrerit semper mollis. Phasellus et tincidunt libero. Etiam vel quam libero. - -Quisque aliquet tempor ex. Ut ante sem, vehicula at enim vel, gravida porta elit. Etiam vitae lacus a neque lobortis consectetur. Mauris sed interdum odio. Mauris elementum ex blandit tempor cursus. Integer in enim in leo viverra elementum. Fusce consectetur metus et sem rutrum, mattis euismod diam semper. Nunc sed ipsum vel urna consequat vehicula. Donec cursus pretium lorem, vestibulum pretium felis commodo sit amet. Nam blandit felis enim, eget gravida ex faucibus a. In nec neque massa. Etiam laoreet posuere ipsum. Praesent volutpat nunc dolor, ac vulputate magna facilisis non. Aenean congue turpis vel lectus sollicitudin tristique. Sed nec consequat purus, non vehicula quam. Etiam ultricies, est ac dictum tincidunt, turpis turpis pretium massa, a vulputate libero justo at nibh. - -Aliquam erat volutpat. Cras ultrices augue ac sollicitudin lobortis. Curabitur et aliquet purus. Duis feugiat semper facilisis. Phasellus lobortis cursus velit, a sollicitudin tortor. Nam feugiat sapien non dapibus condimentum. Morbi at mi bibendum, commodo quam at, laoreet enim. Integer eu ultrices enim. Sed vestibulum eu urna ut dictum. Curabitur at mattis leo, sed cursus massa. Aliquam porttitor, felis quis fermentum porttitor, justo velit feugiat nulla, eget condimentum sem dui ut sapien. - -In fringilla elit eu orci aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut eget fringilla tellus. Curabitur fermentum, mi et condimentum suscipit, elit neque bibendum dui, et hendrerit nunc metus id ipsum. Morbi placerat mi in hendrerit congue. Ut feugiat mauris eget scelerisque viverra. Vivamus sit amet erat dictum, sagittis lectus nec, pulvinar lorem. Sed non enim ac dui sollicitudin aliquet. Quisque ut lacus dolor. Fusce hendrerit malesuada euismod. Nulla faucibus vel mauris eu mollis. Mauris est diam, fringilla ac arcu feugiat, efficitur volutpat turpis. Aliquam venenatis cursus massa sed porttitor. Ut ac finibus enim, in tincidunt sapien. - -Nunc faucibus semper turpis a lacinia. Phasellus gravida, libero vel pulvinar ornare, ex sem tincidunt lectus, sit amet convallis augue risus at tortor. Quisque sit amet ipsum id nulla posuere vestibulum. Pellentesque scelerisque mauris vel leo viverra sodales. Nulla viverra aliquam ex, ut rutrum enim fermentum venenatis. Aenean eget dapibus ex, eget faucibus metus. Vestibulum volutpat leo in diam semper, eget porta magna suscipit. Sed sit amet nulla blandit, aliquam dolor ac, gravida velit. Sed vel velit viverra, maximus est id, convallis justo. - -Curabitur nulla ante, vulputate at libero vel, ullamcorper rutrum nibh. Pellentesque porttitor eu mauris id mattis. Duis vulputate augue elit, eget interdum justo pretium vel. Maecenas eu vulputate arcu, eget posuere purus. Suspendisse viverra a velit dictum eleifend. Suspendisse vitae dapibus diam. Donec vehicula justo in ante interdum, eu luctus diam placerat. Vivamus convallis ipsum eu orci suscipit, sed fermentum enim euismod. Maecenas faucibus elit vitae ex ornare tristique. Donec vestibulum nec elit sit amet porttitor. Aenean tempor lectus eget tortor hendrerit luctus. Nullam interdum vitae lectus vel feugiat. Cras in risus non magna consectetur lobortis. Sed faucibus enim quis gravida convallis. - -Phasellus eget massa sit amet libero ultrices suscipit. Vivamus at risus sapien. Nam mollis nunc eget velit dictum maximus. Sed pellentesque, nunc ac fringilla lacinia, quam enim mattis ex, sed euismod tortor metus eu neque. Ut mattis nisl ut lectus rhoncus, sodales bibendum eros porta. Nulla porttitor enim nec diam sagittis, eget porta velit efficitur. Vestibulum ultricies eros neque. Phasellus rutrum suscipit enim, in interdum ante gravida vitae. Sed in sagittis diam, non commodo velit. - -Morbi hendrerit odio orci, nec tincidunt odio rhoncus nec. Mauris neque velit, vehicula a lorem at, suscipit tristique dui. Sed finibus, nisl in mattis convallis, turpis neque sodales lacus, eu porta enim magna non diam. Nam commodo sodales risus consectetur malesuada. In eget elementum justo. Phasellus sit amet massa imperdiet, dapibus nunc sit amet, suscipit orci. Fusce condimentum laoreet feugiat. Ut ut viverra ante. Praesent bibendum interdum commodo. Nulla mollis nisi a est ornare volutpat. Sed at ligula eu nisi dapibus tempus. Proin cursus vestibulum justo, nec efficitur justo dignissim vel. Nunc quis maximus eros. - -Cras viverra, diam a tristique mattis, libero felis vulputate tellus, a ornare felis leo a dui. Nulla ante nulla, finibus ut tellus ut, blandit pharetra nibh. Proin eleifend fermentum ex, eget auctor libero vulputate in. Nullam ultricies, mauris placerat pretium placerat, leo urna lobortis leo, vel placerat arcu libero sed mauris. Aliquam mauris ligula, ornare at urna at, eleifend gravida ligula. Vestibulum consectetur ut nulla non scelerisque. Donec ornare, sem nec elementum aliquam, urna nulla bibendum metus, eu euismod dui ligula ac est. Fusce laoreet erat eu ex lobortis, quis bibendum ligula interdum. Sed vel mi erat. Vivamus id lacus ac enim mattis tempor. Nunc ultricies pellentesque enim sed euismod. Fusce tincidunt convallis elit quis aliquam. Mauris nulla ipsum, sollicitudin quis diam ac, feugiat volutpat tellus. In nibh nibh, vulputate quis tincidunt quis, pulvinar eget magna. Pellentesque quis finibus dolor. Suspendisse viverra vitae lectus non eleifend. - -Nunc ut orci et sapien maximus semper. Nulla dignissim sem urna, ac varius lectus ultricies id. Quisque aliquet pulvinar pretium. In ultricies molestie tellus vehicula porta. Nam enim lorem, aliquam eget ex et, hendrerit volutpat quam. Maecenas diam lacus, pellentesque eget tempus ac, pharetra eu elit. Donec vel eros a sem facilisis vulputate. Nullam ac nisi vulputate, laoreet nisl ac, eleifend sem. Nullam mi massa, rhoncus sed pharetra interdum, tincidunt eget nunc. Aliquam viverra mattis posuere. Mauris et dui sed nisl sollicitudin fermentum quis ut arcu. Nam placerat eget orci at tincidunt. Curabitur vel turpis metus. Phasellus nibh nulla, fermentum scelerisque sem vel, gravida tincidunt velit. Pellentesque vel quam tempor, finibus massa pellentesque, condimentum dui. - -Donec at mattis neque. Etiam velit diam, consequat auctor mauris id, hendrerit faucibus metus. Maecenas ullamcorper eros a est sodales, ac consectetur odio scelerisque. Donec leo metus, imperdiet at pellentesque vel, feugiat id erat. Suspendisse at magna enim. Vestibulum placerat sodales lorem id sollicitudin. Aenean at euismod ligula, eget mollis diam. Phasellus pulvinar, orci nec pretium condimentum, est erat facilisis purus, quis feugiat augue elit aliquam nulla. Aenean vitae tortor id risus congue tincidunt. Sed dolor enim, mattis a ullamcorper id, volutpat ac leo. - -Proin vehicula feugiat augue, id feugiat quam sodales quis. Donec et ultricies massa, a lacinia nulla. Duis aliquam augue ornare euismod viverra. Ut lectus risus, rutrum sit amet efficitur a, luctus nec nisl. Cras volutpat ullamcorper congue. Sed vitae odio metus. Phasellus aliquet euismod varius. - -Nullam sem ex, malesuada ut magna ut, pretium mollis arcu. Nam porttitor eros cursus mi lacinia faucibus. Suspendisse aliquet eleifend iaculis. Maecenas sit amet viverra tortor. Nunc a mollis risus. Etiam tempus dolor in tortor malesuada mattis. Ut tincidunt venenatis est sit amet dignissim. Vestibulum massa enim, tristique sed scelerisque eu, fringilla ac velit. Donec efficitur quis urna sit amet malesuada. Vestibulum consequat ac ligula in dapibus. Maecenas massa massa, molestie non posuere nec, elementum ut magna. In nisi erat, mollis non venenatis eu, faucibus in justo. Morbi gravida non ex non egestas. Pellentesque finibus laoreet diam, eu commodo augue congue vitae. - -Aenean sem mi, ullamcorper dapibus lobortis vitae, interdum tincidunt tortor. Vivamus eget vulputate libero. Ut bibendum posuere lectus, vel tincidunt tortor aliquet at. Phasellus malesuada orci et bibendum accumsan. Aliquam quis libero vel leo mollis porta. Sed sagittis leo ac lacus dictum, ac malesuada elit finibus. Suspendisse pharetra luctus commodo. Vivamus ultricies a odio non interdum. Vivamus scelerisque tincidunt turpis quis tempor. Pellentesque tortor ligula, varius non nunc eu, blandit sollicitudin neque. Nunc imperdiet, diam et tristique luctus, ipsum ex condimentum nunc, sit amet aliquam justo velit sed libero. Duis vel suscipit ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed tincidunt neque vel massa ultricies, id dictum leo consequat. Curabitur lobortis ultricies tellus, eget mattis nisl aliquam sit amet. - -Proin at suscipit justo. Vivamus ut vestibulum nisl. Pellentesque enim odio, pharetra non magna sed, efficitur auctor magna. Praesent tincidunt ante quis ante hendrerit viverra. Pellentesque vel ipsum id magna vulputate efficitur. Sed nec neque accumsan, pulvinar sapien quis, euismod mauris. Donec condimentum laoreet sapien quis gravida. Quisque sed mattis purus. Vestibulum placerat vel neque maximus scelerisque. - -Vestibulum mattis quam quis efficitur elementum. Duis dictum dolor ac scelerisque commodo. Fusce sollicitudin nisi sit amet dictum placerat. Suspendisse euismod pharetra eleifend. In eros nisl, porttitor sed mauris at, consectetur aliquet mauris. Donec euismod viverra neque sed fermentum. Phasellus libero magna, accumsan ut ultricies vitae, dignissim eget metus. Donec tellus turpis, interdum eget maximus nec, hendrerit eget massa. Curabitur auctor ligula in iaculis auctor. In ultrices quam suscipit cursus finibus. Aenean id mi at dolor interdum iaculis vitae ut lorem. Nullam sed nibh fringilla, lacinia odio nec, placerat erat. In dui libero, viverra ac viverra ac, pellentesque sit amet turpis. - -Nulla in enim ex. Sed feugiat est et consectetur venenatis. Cras varius facilisis dui vel convallis. Vestibulum et elit eget tellus feugiat pellentesque. In ut ante eu purus aliquet posuere. Nulla nec ornare sem, sed luctus lorem. Nam varius iaculis odio, eget faucibus nisl ullamcorper in. Sed eget cursus felis, nec efficitur nisi. - -Vivamus commodo et sem quis pulvinar. Pellentesque libero ante, venenatis vitae ligula sit amet, ornare sollicitudin nulla. Mauris eget tellus hendrerit, pulvinar metus quis, tempor nisi. Proin magna ex, laoreet sed tortor quis, varius fermentum enim. Integer eu dolor dictum, vulputate tortor et, aliquet ligula. Vestibulum vitae justo id mauris luctus sollicitudin. Suspendisse eget auctor neque, sodales egestas lorem. Vestibulum lacinia egestas metus vitae euismod. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus ex tellus, volutpat nec pulvinar sit amet, condimentum vitae dui. Curabitur vel felis sodales, lacinia nunc iaculis, ullamcorper augue. Pellentesque consequat dolor quis eros efficitur malesuada. Nulla ut malesuada lectus. - -Morbi et tristique ante. Aliquam erat volutpat. Vivamus vitae dui nec turpis pellentesque fermentum. Quisque eget velit massa. Pellentesque tristique aliquam nisl, eu sollicitudin justo venenatis sed. Duis eleifend sem eros, ut aliquam libero porttitor id. Sed non nunc consequat, rhoncus diam eu, commodo erat. Praesent fermentum in lectus id blandit. Donec quis ipsum at justo volutpat finibus. Nulla blandit justo nulla, at mollis lacus consequat eget. Aenean sollicitudin quis eros ut ullamcorper. - -Pellentesque venenatis nulla ut mi aliquet feugiat. Cras semper vel magna nec pharetra. Integer mattis felis et sapien commodo imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis quis luctus felis. Vestibulum justo nibh, aliquam non lectus vitae, molestie placerat justo. Donec lorem nibh, gravida sit amet hendrerit ac, maximus id ipsum. Nunc ac libero sodales risus eleifend sagittis. Phasellus est massa, lobortis elementum ex sed, scelerisque consectetur neque. Nunc faucibus neque id lorem malesuada, eget convallis ex mattis. - -Sed turpis tortor, fermentum non turpis id, posuere varius nibh. Donec iaculis lorem dui. Etiam eros ante, sodales eget venenatis at, consectetur eget risus. Curabitur non aliquam ante, a pretium justo. Maecenas tempor nisl tortor, vitae dictum nisi ultrices eu. Duis eget dui ultrices, porttitor lacus sed, lobortis purus. Quisque mattis elit nec neque sagittis, sed commodo leo blandit. Mauris sodales interdum eleifend. Vestibulum condimentum consectetur augue, id luctus diam convallis et. - -Nunc suscipit risus in justo accumsan, a placerat magna tincidunt. Proin a nisl ipsum. Sed libero dui, tristique in augue quis, auctor tristique risus. Sed porttitor ex augue, eu porta augue molestie a. Duis rhoncus purus libero, eu tempus turpis condimentum at. Sed mollis nisi id lectus placerat tincidunt. Maecenas non scelerisque elit, quis rutrum orci. Donec in tellus pharetra urna ornare lobortis. Phasellus id risus at nisi varius rutrum eu ut turpis. - -Duis dictum justo quis nisl porta, eget tincidunt magna suscipit. Sed velit massa, ullamcorper eu sodales ac, pretium a massa. Duis et rutrum tortor. Nulla accumsan hendrerit sapien, cursus volutpat eros egestas eget. Donec sollicitudin at ante quis sollicitudin. Aenean blandit feugiat diam, id feugiat eros faucibus eget. Donec viverra dolor vel justo scelerisque dignissim. Nulla semper sem nunc, rhoncus semper tellus ultricies sed. Duis in ornare diam. Donec vehicula feugiat varius. Maecenas ut suscipit est. Vivamus sem sem, finibus at dolor sit amet, euismod dapibus ligula. Vestibulum fringilla odio dapibus, congue massa eget, congue sem. Donec feugiat magna eget tortor lacinia scelerisque non et ipsum. - -Suspendisse potenti. Nunc convallis sollicitudin ex eget venenatis. Sed iaculis nibh ex, vel ornare ligula congue dignissim. Quisque sollicitudin dolor ac dui vestibulum, sit amet molestie nisi aliquet. Donec at risus felis. Aenean sollicitudin metus a feugiat porta. Aenean a tortor ut dolor cursus sagittis. Vivamus consectetur porttitor nunc in facilisis. Proin sit amet mi vel lectus consectetur ultrices. - -Sed cursus lectus vitae nunc tristique, nec commodo turpis dapibus. Pellentesque luctus ex id facilisis ornare. Morbi quis placerat dolor. Donec in lectus in arcu mattis porttitor ac sit amet metus. Cras congue mauris non risus sodales, vitae feugiat ipsum bibendum. Nulla venenatis urna sed libero elementum, a cursus lorem commodo. Mauris faucibus lobortis eros nec commodo. - -Nullam suscipit ligula ullamcorper lorem commodo blandit. Nulla porta nibh quis pulvinar placerat. Vivamus eu arcu justo. Vestibulum imperdiet est ut fermentum porttitor. Pellentesque consectetur libero in sapien efficitur scelerisque. Curabitur ac erat sit amet odio aliquet dignissim. Pellentesque mi sem, rhoncus et luctus at, porttitor rutrum lectus. Vestibulum sollicitudin sollicitudin suscipit. Aenean efficitur dolor non ultrices imperdiet. Donec vel sem ex. - -Sed convallis mauris aliquam rutrum cursus. Ut tempor porttitor sodales. Etiam eu risus ac augue gravida egestas et eu dolor. Proin id magna ex. Suspendisse quis lectus quis lorem ultricies tempus. Donec porttitor velit vitae tincidunt faucibus. Aliquam vitae semper nisi. Morbi ultrices, leo non pretium dapibus, dui libero pellentesque ex, vel placerat enim ante vitae dui. Nunc varius, sem sit amet sagittis lobortis, lectus odio scelerisque mauris, ut vestibulum orci magna quis neque. Sed id congue justo. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris congue nisi est, malesuada mollis elit tincidunt sed. Curabitur sed ex sit amet felis tristique elementum vitae vel nibh. - -Etiam mollis pretium lobortis. Mauris augue lacus, efficitur at lacus sed, mollis tincidunt lectus. Aliquam erat volutpat. Donec at euismod elit, et mattis felis. Sed id lobortis urna. Morbi imperdiet vestibulum leo, sed maximus leo blandit eu. Aliquam semper lorem neque, nec euismod turpis mattis mollis. Quisque lobortis urna ultrices odio pretium, ac venenatis orci faucibus. Suspendisse bibendum odio ligula, sed lobortis massa pharetra nec. Donec turpis justo, iaculis at dictum ac, finibus eu libero. Maecenas quis porttitor mi, sit amet aliquet neque. - -Vivamus auctor vulputate ante, at egestas lorem. Donec eu risus in nulla mollis ultricies at et urna. Duis accumsan porta egestas. Ut vel euismod augue. Fusce convallis nulla ante, nec fringilla velit aliquet at. Nam malesuada dapibus ligula, a aliquam nibh scelerisque ac. Praesent malesuada neque et pellentesque interdum. Curabitur volutpat at turpis vitae tristique. Vivamus porttitor semper congue. Quisque suscipit lacus mi, rhoncus ultrices tortor auctor quis. Maecenas neque neque, molestie ac facilisis eget, luctus ac lorem. In ut odio ut lacus suscipit pulvinar vitae sed elit. Nulla imperdiet, sem quis euismod sagittis, dui erat luctus dolor, faucibus faucibus erat sem eget nunc. Nam accumsan placerat malesuada. Maecenas convallis finibus pulvinar. - -Cras at placerat tortor. Morbi facilisis auctor felis sit amet molestie. Donec sodales sed lorem vitae suscipit. Etiam fermentum pharetra ipsum, nec luctus orci gravida eu. Pellentesque gravida, est non condimentum tempus, mauris ligula molestie est, in congue dolor nisl vel sapien. Duis congue tempor augue, id rutrum eros porta dapibus. Etiam rutrum eget est eget vestibulum. Aenean mollis arcu vel consequat varius. Praesent at condimentum felis. Duis nec interdum nisl. Donec commodo lorem sed sapien scelerisque malesuada non eu urna. In blandit non ipsum at porta. Nam lobortis leo vitae dui auctor, non feugiat quam bibendum. Donec auctor lectus sagittis laoreet maximus. Maecenas rhoncus laoreet porttitor. Vestibulum porttitor augue ut lectus hendrerit, eget posuere mi gravida. - -Sed mattis ex in erat pulvinar, eu imperdiet magna dapibus. Etiam nisi nibh, tempus non tellus sit amet, mattis tempor odio. Quisque nec lorem feugiat, lobortis odio et, commodo nunc. Maecenas semper purus nisi, nec vehicula nibh eleifend vitae. Nulla fermentum a lectus at maximus. Phasellus finibus metus non euismod ultrices. Etiam a pulvinar ante. Quisque convallis nec metus sit amet facilisis. Praesent laoreet massa et sollicitudin laoreet. Vestibulum in mauris aliquet, convallis mi ut, elementum purus. Nulla purus nulla, sodales at hendrerit quis, tempus sed lectus. - -Nam ut laoreet neque, ut maximus nibh. Maecenas quis justo pellentesque, sollicitudin elit at, venenatis velit. Aenean nunc velit, vehicula scelerisque odio at, consectetur laoreet purus. Duis dui purus, malesuada quis ipsum sit amet, tempor interdum libero. Curabitur porta scelerisque sapien, vitae cursus diam condimentum eu. Phasellus sed orci quam. Nullam vitae dui quis purus tincidunt vestibulum. Curabitur quis nulla porta, cursus arcu non, auctor enim. Etiam sollicitudin ex id sem vehicula mollis. Morbi viverra laoreet tincidunt. Praesent ut semper dui. Nam sit amet pretium neque. Mauris vitae luctus diam, in lacinia purus. Maecenas ut placerat justo, ut porta felis. Integer eu mauris ante. - -Aenean porttitor tellus diam, tempor consequat metus efficitur id. Suspendisse ut felis at erat tempor dictum at nec sapien. Sed vestibulum interdum felis, ac mattis mauris porta in. Nunc et condimentum massa. Sed cursus dictum justo et luctus. Integer convallis enim nisl, a rutrum lectus ultricies in. Donec dapibus lacus at nulla dapibus, id sollicitudin velit hendrerit. Fusce a magna at orci mollis rutrum ac a dolor. Aliquam erat volutpat. Morbi varius porta nunc, sit amet sodales ex hendrerit commodo. Donec tincidunt tortor sapien, vitae egestas sapien vehicula eget. - -Suspendisse potenti. Donec pulvinar felis nec leo malesuada interdum. Integer posuere placerat maximus. Donec nibh ipsum, tincidunt vitae luctus vitae, bibendum at leo. Sed cursus nisl ut ex faucibus aliquet sed nec eros. Curabitur molestie posuere felis. Integer faucibus velit eget consequat iaculis. Mauris sed vulputate odio. Phasellus maximus, elit a pharetra egestas, lorem magna semper tellus, vestibulum semper diam felis at sapien. Suspendisse facilisis, nisl sit amet euismod vehicula, libero nulla vehicula dolor, quis fermentum nibh elit sit amet diam. - -Morbi lorem enim, euismod eu varius ut, scelerisque quis odio. Nam tempus vitae eros id molestie. Nunc pretium in nulla eget accumsan. Quisque mattis est ut semper aliquet. Maecenas eget diam elementum, fermentum ipsum a, euismod sapien. Duis quam ligula, cursus et velit nec, ullamcorper tincidunt magna. Donec vulputate nisl est, et ullamcorper urna tempor sit amet. - -Proin lacinia dui non turpis congue pretium. Morbi posuere metus vel purus imperdiet interdum. Morbi venenatis vel eros non ultricies. Nulla vel semper elit. Ut quis purus tincidunt, auctor justo ut, faucibus turpis. Proin quis mattis erat, at faucibus ligula. Mauris in mauris enim. Donec facilisis enim at est feugiat hendrerit. Nam vel nisi lorem. Fusce ultricies convallis diam, in feugiat tortor luctus quis. Donec tempor, leo vitae volutpat aliquam, magna elit feugiat leo, quis placerat sapien felis eget arcu. Donec ornare fermentum eleifend. Integer a est orci. - -Proin rhoncus egestas leo. Nulla ultricies porta elit quis ornare. Nunc fermentum interdum vehicula. In in ligula lorem. Donec nec arcu sit amet orci lobortis iaculis. Mauris at mollis erat, sit amet mollis tortor. Mauris laoreet justo ullamcorper porttitor auctor. Aenean sit amet aliquam lectus, id fermentum eros. Praesent urna sem, vehicula ac fermentum id, dapibus ut purus. Vestibulum vitae tempus nunc. Donec at nunc ornare metus volutpat porta at eget magna. Donec varius aliquet metus, eu lobortis risus aliquam sed. Ut dapibus fermentum velit, ac tincidunt libero faucibus at. - -In in purus auctor, feugiat massa quis, facilisis nisi. Donec dolor purus, gravida eget dolor ac, porttitor imperdiet urna. Donec faucibus placerat erat, a sagittis ante finibus ac. Sed venenatis dignissim elit, in iaculis felis posuere faucibus. Praesent sed viverra dolor. Mauris sed nulla consectetur nunc laoreet molestie in ut metus. Proin ac ex sit amet magna vulputate hendrerit ac condimentum urna. Proin ligula metus, gravida et sollicitudin facilisis, iaculis ut odio. Cras tincidunt urna et augue varius, ut facilisis urna consequat. Aenean vehicula finibus quam. Ut iaculis eu diam ac mollis. Nam mi lorem, tristique eget varius at, sodales at urna. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin vitae dictum erat, et auctor ipsum. Nullam nunc nunc, sollicitudin quis magna a, vestibulum fermentum mauris. Praesent at erat dolor. Proin laoreet tristique nulla vel efficitur. Nam sed ultrices nibh, id rutrum nunc. Curabitur eleifend a erat sit amet sollicitudin. Nullam metus quam, laoreet vitae dapibus id, placerat sed leo. Aliquam erat volutpat. Donec turpis nisl, cursus eu ex sit amet, lacinia pellentesque nisl. Sed id ipsum massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec interdum scelerisque lorem eu mattis. - -Vivamus ac tristique massa, nec facilisis nisl. Nam ipsum neque, tincidunt vel urna in, cursus imperdiet enim. Nam pellentesque egestas tempus. Morbi facilisis imperdiet libero vitae fringilla. Nam lacinia ligula at sapien facilisis malesuada. Nullam accumsan pulvinar sem, et cursus libero porta sit amet. Curabitur vulputate erat elit, ut pulvinar erat maximus vel. - -Cras aliquet metus ut purus sagittis, vel venenatis ante consectetur. Pellentesque nulla lacus, viverra viverra mattis non, placerat vitae nibh. Donec enim turpis, accumsan sit amet tincidunt eu, imperdiet non metus. Morbi ipsum eros, tincidunt vel est ac, tristique porttitor nibh. Praesent ut ullamcorper mauris. Sed laoreet sit amet diam congue venenatis. Integer porta purus nec orci sagittis posuere. - -Donec vehicula mauris eget lacus mollis venenatis et sed nibh. Nam sodales ligula ipsum, scelerisque lacinia ligula sagittis in. Nam sit amet ipsum at erat malesuada congue. Aenean ut sollicitudin sapien. Etiam at tempor odio. Mauris vitae purus ut magna suscipit consequat. Vivamus quis sapien neque. Nulla vulputate sem sit amet massa pellentesque, eleifend tristique ligula egestas. Suspendisse tincidunt gravida mi, in pulvinar lectus egestas non. Aenean imperdiet ex sit amet nunc sollicitudin porta. Integer justo odio, ultricies at interdum in, rhoncus vitae sem. Sed porttitor arcu quis purus aliquet hendrerit. Praesent tempor tortor at dolor dictum pulvinar. Nulla aliquet nunc non ligula scelerisque accumsan. Donec nulla justo, congue vitae massa in, faucibus hendrerit magna. Donec non egestas purus. - -Öйúabc Vivamus iaculis, lacus efficitur faucibus porta, dui nulla facilisis ligula, ut sodales odio nunc id sapien. Cras viverra auctor ipsum, dapibus mattis neque dictum sed. Sed convallis fermentum molestie. Nulla facilisi turpis duis. \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_shiftjis.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_shiftjis.txt deleted file mode 100644 index 3e106d9df47..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_shiftjis.txt +++ /dev/null @@ -1,283 +0,0 @@ -’†•¶abc Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vulputate, ipsum quis interdum fermentum, lorem sem fermentum eros, vitae auctor neque lacus in nisi. Suspendisse potenti. Maecenas et scelerisque elit, in tincidunt quam. Sed eu tincidunt quam. Nullam justo ex, imperdiet a imperdiet et, fermentum sit amet eros. Aenean quis tempus sem. Pellentesque accumsan magna mi, ut mollis velit sagittis id. Etiam quis ipsum orci. Fusce purus ante, accumsan a lobortis at, venenatis eu nisl. Praesent ornare sed ante placerat accumsan. Suspendisse tempus dignissim fermentum. Nunc a leo ac lacus sodales iaculis eu vitae mi. In feugiat ante at massa finibus cursus. Suspendisse posuere fringilla ornare. Mauris elementum ac quam id convallis. Vestibulum non elit quis urna volutpat aliquam a eu lacus. - -Aliquam vestibulum imperdiet neque, suscipit aliquam elit ultrices bibendum. Suspendisse ultrices pulvinar cursus. Morbi risus nisi, cursus consequat rutrum vitae, molestie sed dui. Fusce posuere, augue quis dignissim aliquam, nisi ipsum porttitor ante, quis fringilla nisl turpis ac nisi. Nulla varius enim eget lorem vehicula gravida. Donec finibus malesuada leo nec semper. Proin ac enim eros. Vivamus non tincidunt nisi, vel tristique lorem. - -Nunc consequat ex id eros dignissim, id rutrum risus laoreet. Sed euismod non erat eu ultricies. Etiam vehicula gravida lacus ut porta. Vestibulum eu eros quis nunc aliquet luctus. Cras quis semper ligula. Nullam gravida vehicula quam sed porta. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In porta cursus vulputate. Quisque porta a nisi eget cursus. Aliquam risus leo, luctus ac magna in, efficitur cursus magna. In condimentum non mi id semper. Donec interdum ante eget commodo maximus. - -Vivamus sit amet vestibulum lectus. Fusce tincidunt mi sapien, dictum sollicitudin diam vulputate in. Integer fringilla consequat mollis. Cras aliquet consequat felis eget feugiat. Nunc tempor cursus arcu, vitae ornare nunc varius et. Vestibulum et tortor vel ante viverra porttitor. Nam at tortor ullamcorper, facilisis augue quis, tristique erat. Aenean ut euismod nibh. Quisque eu tincidunt est, nec euismod eros. - -Proin vehicula nibh non viverra egestas. Phasellus sem dolor, ultricies ac sagittis tristique, lacinia a purus. Vestibulum in ante eros. Pellentesque lacus nulla, tristique vitae interdum vel, malesuada ac diam. Aenean bibendum posuere turpis in accumsan. Ut est nulla, ullamcorper quis turpis at, viverra sagittis mauris. Sed in interdum purus. Praesent scelerisque nibh eget sem euismod, ut imperdiet mi venenatis. Vivamus pulvinar orci sed dapibus auctor. Nulla facilisi. Vestibulum tincidunt erat nec porttitor egestas. Mauris quis risus ante. Nulla facilisi. - -Aliquam ullamcorper ornare lobortis. Phasellus quis sem et ipsum mollis malesuada sed in ex. Ut aliquam ex eget metus finibus maximus. Proin suscipit mauris eu nibh lacinia, quis feugiat dui dapibus. Nam sed libero est. Aenean vulputate orci sit amet diam faucibus, eu sagittis sapien volutpat. Nam imperdiet felis turpis, at pretium odio pulvinar in. Sed vestibulum id eros nec ultricies. Sed quis aliquam tortor, vitae ullamcorper tellus. Donec egestas laoreet eros, id suscipit est rutrum nec. Sed auctor nulla eget metus aliquam, ut condimentum enim elementum. - -Aliquam suscipit non turpis sit amet bibendum. Fusce velit ligula, euismod et maximus at, luctus sed neque. Quisque pretium, nisl at ullamcorper finibus, lectus leo mattis sapien, vel euismod mauris diam ullamcorper ex. Nulla ut risus finibus, lacinia ligula at, auctor erat. Mauris consectetur sagittis ligula vel dapibus. Nullam libero libero, lobortis aliquam libero vel, venenatis ultricies leo. Duis porttitor, nibh congue fermentum posuere, erat libero pulvinar tortor, a pellentesque nunc ipsum vel sem. Nullam volutpat, eros sit amet facilisis consectetur, ipsum est vehicula massa, non vestibulum neque elit in mauris. Nunc hendrerit ipsum non enim bibendum, vitae rhoncus mi egestas. Etiam ullamcorper massa vel nisl sagittis, nec bibendum arcu malesuada. Aenean aliquet turpis justo, a consectetur arcu mollis convallis. Etiam tellus ipsum, ultricies vitae lorem et, ornare facilisis orci. Praesent fringilla justo urna, vel mollis neque pulvinar vestibulum. - -Donec non iaculis erat. Aliquam et mi sed nunc pulvinar ultricies in ut ipsum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent feugiat lacus ac dignissim semper. Phasellus vitae quam nisi. Morbi vel diam ultricies risus lobortis ornare. Fusce maximus et ligula quis iaculis. Sed congue ex eget felis convallis, sit amet hendrerit elit tempor. Donec vehicula blandit ante eget commodo. Vestibulum eleifend diam at feugiat euismod. Etiam magna tellus, dignissim eget fermentum vel, vestibulum vitae mauris. Nam accumsan et erat id sagittis. Donec lacinia, odio ut ornare ultricies, dolor velit accumsan tortor, non finibus erat tellus quis ligula. Nunc quis metus in leo volutpat ornare vulputate eu nisl. - -Donec quis viverra ex. Nullam id feugiat mauris, eu fringilla nulla. Vestibulum id maximus elit. Cras elementum elit sed felis lobortis, eget sagittis nisi hendrerit. Vivamus vitae elit neque. Donec vulputate lacus ut libero ultrices accumsan. Vivamus accumsan nulla orci, in dignissim est laoreet sagittis. Proin at commodo velit. Curabitur in velit felis. Aliquam erat volutpat. Sed consequat, nulla et cursus sodales, nisi lacus mattis risus, quis eleifend erat ex nec turpis. Sed suscipit ultrices lorem in hendrerit. - -Morbi vitae lacus nec libero ornare tempus eu et diam. Suspendisse magna ipsum, fermentum vel odio quis, molestie aliquam urna. Fusce mollis turpis a eros accumsan porttitor. Pellentesque rhoncus dolor sit amet magna rutrum, et dapibus justo tempor. Sed purus nisi, maximus vitae fringilla eu, molestie nec urna. Fusce malesuada finibus pretium. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec sed aliquet eros. Pellentesque luctus diam ante, eget euismod nisl aliquet eu. Sed accumsan elit purus, tempor varius ligula tempus nec. Curabitur ornare leo suscipit suscipit fermentum. Morbi eget nulla est. Maecenas faucibus interdum tristique. - -Etiam ut elit eros. Nulla pharetra suscipit molestie. Nulla facilisis bibendum nisl non molestie. Curabitur turpis lectus, facilisis vel diam non, vulputate ultrices mauris. Aenean placerat aliquam convallis. Suspendisse sed scelerisque tellus. Vivamus lacinia neque eget risus cursus suscipit. Proin consequat dolor vel neque tempor, eu aliquam sem scelerisque. Duis non eros a purus malesuada pharetra non et nulla. Suspendisse potenti. Mauris libero eros, finibus vel nulla id, sagittis dapibus ante. Proin iaculis sed nunc et cursus. - -Quisque accumsan lorem sit amet lorem aliquet euismod. Curabitur fermentum rutrum posuere. Etiam ultricies, sem id pellentesque suscipit, urna magna lacinia eros, quis efficitur risus nisl at lacus. Nulla quis lacus tortor. Mauris placerat ex in dolor tincidunt, vel aliquet nisi pretium. Cras iaculis risus vitae pellentesque aliquet. Quisque a enim imperdiet, ullamcorper arcu vitae, rutrum risus. Nullam consectetur libero at felis fringilla, nec congue nibh dignissim. Nam et lobortis felis, eu pellentesque ligula. Aenean facilisis, ligula non imperdiet maximus, massa orci gravida sapien, at sagittis lacus nisl in lacus. Nulla quis mauris luctus, scelerisque felis consequat, tempus risus. Fusce auctor nisl non nulla luctus molestie. Maecenas sapien nisl, auctor non dolor et, iaculis scelerisque lorem. Suspendisse egestas enim aliquet, accumsan mauris nec, posuere quam. Nulla iaculis dui dui, sit amet vestibulum erat ultricies ac. - -Cras eget dolor erat. Proin at nisl ut leo consectetur ultricies vel ut arcu. Nulla in felis malesuada, ullamcorper tortor et, convallis massa. Nunc urna justo, ornare in nibh vitae, hendrerit condimentum libero. Etiam vitae libero in purus venenatis fringilla. Nullam velit nulla, consequat ut turpis non, egestas hendrerit nibh. Duis tortor turpis, interdum non ante ac, cursus accumsan lectus. Cras pharetra bibendum augue quis dictum. Sed euismod vestibulum justo. Proin porta lobortis purus. Duis venenatis diam tortor, sit amet condimentum eros rhoncus a. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc at magna nec diam lobortis efficitur sit amet ut lacus. Nulla quis orci tortor. Pellentesque tempus velit a odio finibus porta. - -Proin feugiat mauris a tellus scelerisque convallis. Maecenas libero magna, blandit nec ultrices id, congue vel mi. Aliquam lacinia, quam vel condimentum convallis, tortor turpis aliquam odio, sed blandit libero lacus et eros. In eleifend iaculis magna ac finibus. Praesent auctor facilisis tellus in congue. Sed molestie lobortis dictum. Nam quis dignissim augue, vel euismod lorem. Curabitur posuere dapibus luctus. Donec ultricies dictum lectus, quis blandit arcu commodo ac. Aenean tincidunt ligula in nunc imperdiet dignissim. Curabitur egestas sollicitudin sapien ut semper. Aenean nec dignissim lacus. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec aliquam dictum vehicula. Donec tortor est, volutpat non nisi nec, varius gravida ex. Nunc vel tristique nunc, vitae mattis nisi. Nunc nec luctus ex, vitae tincidunt lectus. In hac habitasse platea dictumst. Curabitur lobortis ex eget tincidunt tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut a vehicula mi. - -Fusce eu libero finibus, interdum nulla a, placerat neque. Cras bibendum tempor libero nec feugiat. Cras ut sodales eros. Proin viverra, massa sit amet viverra egestas, neque nisl porta ex, sit amet hendrerit libero ligula vel urna. Mauris suscipit lacus id justo rhoncus suscipit. Etiam vel libero tellus. Maecenas non diam molestie, condimentum tellus a, bibendum enim. Mauris aliquet imperdiet tellus, eget sagittis dolor. Sed blandit in neque et luctus. Cras elementum sagittis nunc, vel mollis lorem euismod et. Donec posuere at lacus eget suscipit. - -Nulla nunc mi, pretium non massa vel, tempor semper magna. Nunc a leo pulvinar, tincidunt nunc at, dignissim mi. Aliquam erat volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut viverra nulla a nisl finibus, at hendrerit ligula ullamcorper. Donec a lorem semper, tempor magna et, lobortis libero. Mauris id sapien leo. Donec dignissim, quam vitae porttitor dignissim, quam justo mattis dui, vel consequat odio elit quis orci. Etiam nec pretium neque, sit amet pretium orci. Duis ac tortor venenatis, feugiat purus non, feugiat nunc. Proin scelerisque nisl in turpis aliquam vulputate. - -Praesent sed est semper, fringilla lorem vitae, tincidunt nibh. Cras eros metus, auctor at mauris sit amet, sodales semper orci. Nunc a ornare ex. Curabitur bibendum arcu congue urna vulputate egestas. Vestibulum finibus id risus et accumsan. Aenean ut volutpat tellus. Aenean tincidunt malesuada urna sit amet vestibulum. Mauris vel tellus dictum, varius lacus quis, dictum arcu. - -Aenean quis metus eu erat feugiat cursus vel at ligula. Proin dapibus sodales urna, id euismod lectus tempus id. Pellentesque ex ligula, convallis et erat vel, vulputate condimentum nisl. Pellentesque pharetra nulla quis massa eleifend hendrerit. Praesent sed massa ipsum. Maecenas vehicula dolor massa, id sodales urna faucibus et. Mauris ac quam non massa tincidunt feugiat et at lacus. Fusce libero massa, vulputate vel scelerisque non, mollis in leo. Ut sit amet ultricies odio. Suspendisse in sapien viverra, facilisis purus ut, pretium libero. - -Vivamus tristique pharetra molestie. Nam a volutpat purus. Praesent consequat gravida nisi, ac blandit nisi suscipit ut. Quisque posuere, ligula a ultrices laoreet, ligula nunc vulputate libero, ut rutrum erat odio tincidunt justo. Sed vitae leo at leo fringilla bibendum. Vestibulum ut augue nec dolor auctor accumsan. Praesent laoreet id eros pulvinar commodo. Suspendisse potenti. Ut pharetra, mauris vitae blandit fringilla, odio ante tincidunt lorem, sit amet tempor metus diam ut turpis. - -Praesent quis egestas arcu. Nullam at porta arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi vulputate ligula malesuada ligula luctus, vulputate tempus erat bibendum. Nunc ullamcorper non lectus at euismod. Etiam nibh felis, tincidunt a metus vel, pellentesque rhoncus neque. Etiam at diam in erat luctus interdum. Nunc vel ipsum pulvinar, sollicitudin lacus ac, tempus urna. Etiam vel lacinia sapien. Pellentesque sagittis velit vel mi efficitur iaculis. Integer euismod sit amet urna in sagittis. Cras eleifend ut nibh in facilisis. Donec et lacus vitae nunc placerat sodales. Nulla sed hendrerit ligula, at dapibus sapien. - -Praesent at iaculis ex. Curabitur est purus, cursus a faucibus quis, dictum id velit. Donec dignissim fringilla viverra. Nunc mauris felis, laoreet sit amet sagittis at, vestibulum in libero. Maecenas quis orci turpis. Quisque ut nibh vitae magna mollis consequat id at mauris. Aliquam eu odio eget nulla bibendum sodales. Quisque vel orci eleifend nisi pretium lacinia. Suspendisse eget risus eget mi volutpat molestie eget quis lacus. Duis nisi libero, tincidunt nec nulla id, faucibus cursus felis. - -Donec tempor eget risus pellentesque molestie. Phasellus porta neque vel arcu egestas, nec blandit velit fringilla. Nullam porta faucibus justo vitae laoreet. Pellentesque viverra id nunc eu varius. Nulla pulvinar lobortis iaculis. Etiam vestibulum odio nec velit tristique, a tristique nisi mattis. In sed fringilla orci, vitae efficitur odio. Quisque dui odio, ornare eget velit at, lacinia consequat libero. Quisque lectus nulla, aliquet eu leo in, porta rutrum diam. Donec nec mattis neque. Nam rutrum, odio ac eleifend bibendum, dolor arcu rutrum neque, eget porta elit tellus a lacus. Sed massa metus, sollicitudin et sapien eu, finibus tempus orci. Proin et sapien sit amet erat molestie interdum. In quis rutrum velit, faucibus ultrices tellus. - -Sed sagittis sed justo eget tincidunt. Maecenas ut leo sagittis, feugiat magna et, viverra velit. Maecenas ex arcu, feugiat at consequat vitae, auctor eu massa. Integer egestas, enim vitae maximus convallis, est lectus pretium mauris, ac posuere lectus nisl quis quam. Aliquam tempus laoreet mi, vitae dapibus dolor varius dapibus. Suspendisse potenti. Donec sit amet purus nec libero dapibus tristique. Pellentesque viverra bibendum ligula. Donec sed felis et ex lobortis laoreet. Phasellus a fringilla libero, vitae malesuada nulla. Pellentesque blandit mattis lacus, et blandit tortor laoreet consequat. Suspendisse libero nunc, viverra sed fermentum in, accumsan egestas arcu. Proin in placerat elit. Sed interdum imperdiet malesuada. Suspendisse aliquet quis mauris eget sollicitudin. - -Vivamus accumsan tellus non erat volutpat, quis dictum dolor feugiat. Praesent rutrum nunc ac est mollis cursus. Fusce semper volutpat dui ut egestas. Curabitur sit amet posuere massa. Cras tincidunt nulla et mi mollis imperdiet. Suspendisse scelerisque ex id sodales vulputate. In nunc augue, pharetra in placerat eu, mattis id tellus. Vivamus cursus efficitur vehicula. Nulla aliquet vehicula aliquet. - -Sed cursus tellus sed porta pulvinar. Sed vitae nisi neque. Nullam aliquet, lorem et efficitur scelerisque, arcu diam aliquam felis, sed pulvinar lorem odio et turpis. Praesent convallis pulvinar turpis eu iaculis. Aliquam nec gravida mi. Curabitur eu nibh tempor, blandit justo in, ultrices felis. Fusce placerat metus non mi sagittis rutrum. Morbi sed dui fringilla, sagittis mauris eget, imperdiet nunc. Phasellus hendrerit sem elit, id hendrerit libero auctor sit amet. Integer sodales elit sit amet consequat cursus. - -Nam semper est eget nunc mollis, in pellentesque lectus fringilla. In finibus vel diam id semper. Nunc mattis quis erat eu consectetur. In hac habitasse platea dictumst. Nullam et ipsum vestibulum ex pulvinar ultricies sit amet id velit. Aenean suscipit mi tortor, a lobortis magna viverra non. Nulla condimentum aliquet ante et ullamcorper. Pellentesque porttitor arcu a posuere tempus. Aenean lacus quam, imperdiet eu justo vitae, pretium efficitur ex. Duis id purus id magna rhoncus ultrices id eu risus. Nunc dignissim et libero id dictum. - -Quisque a tincidunt neque. Phasellus commodo mi sit amet tempor fringilla. Ut rhoncus, neque non porttitor elementum, libero nulla egestas augue, sed fringilla sapien felis ac velit. Phasellus viverra rhoncus mollis. Nam ullamcorper leo vel erat laoreet luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus semper a metus a cursus. Nulla sed orci egestas, efficitur purus ac, malesuada tellus. Aenean rutrum velit at tellus fermentum mollis. Aliquam eleifend euismod metus. - -In hac habitasse platea dictumst. Vestibulum volutpat neque vitae porttitor laoreet. Nam at tellus consequat, sodales quam in, pulvinar arcu. Maecenas varius convallis diam, ac lobortis tellus pellentesque quis. Maecenas eget augue massa. Nullam volutpat nibh ac justo rhoncus, ut iaculis tellus rutrum. Fusce efficitur efficitur libero quis condimentum. Curabitur congue neque non tincidunt tristique. Fusce eget tempor ex, at pellentesque odio. Praesent luctus dictum vestibulum. Etiam non orci nunc. Vivamus vitae laoreet purus, a lobortis velit. Curabitur tincidunt purus ac lectus elementum pellentesque. Quisque sed tincidunt est. - -Sed vel ultrices massa, vitae ultricies justo. Cras finibus mauris nec lacus tempus dignissim. Cras faucibus maximus velit, eget faucibus orci luctus vehicula. Nulla massa nunc, porta ac consequat eget, rhoncus non tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce sed maximus metus, vel imperdiet ipsum. Ut scelerisque lectus at blandit porttitor. Ut vulputate nunc pharetra, aliquet sapien ac, sollicitudin sapien. Aenean eget ante lorem. Nam accumsan venenatis tellus id dignissim. - -Curabitur fringilla, magna non maximus dapibus, nulla sapien vestibulum lectus, sit amet semper dolor neque vitae nisl. Nunc ultrices vehicula augue sed iaculis. Maecenas nec diam mollis, suscipit orci et, vestibulum ante. Pellentesque eu nisl tortor. Nunc eleifend, lacus quis volutpat volutpat, nisi mi molestie sem, quis mollis ipsum libero a tellus. Ut viverra dolor mattis convallis interdum. Sed tempus nisl at nunc scelerisque aliquet. Quisque tempor tempor lorem id feugiat. Nullam blandit lectus velit, vitae porta lacus tincidunt a. Vivamus sit amet arcu ultrices, tincidunt mi quis, viverra quam. Aenean fringilla libero elementum lorem semper, quis pulvinar eros gravida. Nullam sodales blandit mauris, sed fermentum velit fermentum sit amet. Donec malesuada mauris in augue sodales vulputate. Vestibulum gravida turpis id elit rhoncus dignissim. Integer non congue lorem, eu viverra orci. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec at dolor magna. Aliquam consectetur erat augue, id iaculis velit pharetra ac. Integer rutrum venenatis dignissim. Integer non sodales elit. Curabitur ut magna ut nibh feugiat aliquam ac ut risus. Morbi nibh quam, aliquam id placerat nec, vestibulum eget velit. Suspendisse at dignissim quam. Vivamus aliquet sem sed nisl volutpat, ut cursus orci ultrices. Aliquam ultrices lacinia enim, vitae aliquet neque. - -Quisque scelerisque finibus diam in mattis. Cras cursus auctor velit. Aliquam sem leo, fermentum et maximus et, molestie a libero. Aenean justo elit, rutrum a ornare id, egestas eget enim. Aenean auctor tristique erat. Curabitur condimentum libero lacus, nec consequat orci vestibulum sed. Fusce elit ligula, blandit vitae sapien vitae, dictum ultrices risus. Nam laoreet suscipit sapien, at interdum velit faucibus sit amet. Duis quis metus egestas lectus elementum posuere non nec libero. Aliquam a dolor bibendum, facilisis nunc a, maximus diam. Vestibulum suscipit tristique magna, non dignissim turpis sodales sed. Nunc ornare, velit ac facilisis fringilla, dolor mi consectetur lorem, vitae finibus erat justo suscipit urna. Maecenas sit amet eros erat. Nunc non arcu ornare, suscipit lorem eget, sodales mauris. Aliquam tincidunt, quam nec mollis lacinia, nisi orci fermentum libero, consequat eleifend lectus quam et sapien. Vestibulum a quam urna. - -Cras arcu leo, euismod ac ullamcorper at, faucibus sed massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus porttitor velit in enim interdum, non commodo metus ornare. Morbi vel lorem quis nisl luctus tristique quis vitae nisl. Suspendisse condimentum tortor enim, nec eleifend ipsum euismod et. Sed gravida quam ut tristique lacinia. Mauris eu interdum ipsum, ac ultrices odio. Nullam auctor tellus a risus porttitor vehicula. Nulla blandit euismod dictum. In pharetra, enim iaculis pulvinar interdum, dui nunc placerat nunc, sit amet pretium lectus nulla vitae quam. Phasellus quis enim sollicitudin, varius nulla id, ornare purus. Donec quam lacus, vestibulum quis nunc ac, mollis dictum nisi. Cras ut mollis elit. Maecenas ultrices ligula at risus faucibus scelerisque. Etiam vitae porttitor purus. Curabitur blandit lectus urna, ut hendrerit tortor feugiat ut. - -Phasellus fringilla, sapien pellentesque commodo pharetra, ante libero aliquam tellus, ut consectetur augue libero a sapien. Maecenas blandit luctus nisl eget aliquet. Maecenas vitae porta dolor, faucibus laoreet sapien. Suspendisse lobortis, ipsum sed vehicula aliquam, elit purus scelerisque dui, rutrum consectetur diam odio et lorem. In nec lacinia metus. Donec viverra libero est, vel bibendum erat condimentum quis. Donec feugiat purus leo. In laoreet vitae felis a porttitor. Mauris ullamcorper, lacus id condimentum suscipit, neque magna pellentesque arcu, eget cursus neque tellus id metus. Curabitur volutpat ac orci vel ultricies. - -Sed ut finibus erat. Sed diam purus, varius non tincidunt quis, ultrices sit amet ipsum. Donec et egestas nulla. Suspendisse placerat nisi at dui laoreet iaculis. Aliquam aliquet leo at augue faucibus molestie. Nullam lacus augue, hendrerit sed nisi eu, faucibus porta est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam ut leo aliquet sem fermentum rutrum quis ac justo. Integer placerat aliquam nisl ut sagittis. Proin erat orci, lobortis et sem eget, eleifend fringilla augue. Mauris varius laoreet arcu, sed tincidunt felis. Pellentesque venenatis lorem odio, id pulvinar velit molestie feugiat. Donec mattis lacus sed eleifend pulvinar. - -Sed condimentum ex in tincidunt hendrerit. Etiam eget risus lacinia, euismod nibh eu, pellentesque quam. Proin elit eros, convallis id mauris ac, bibendum ultrices lectus. Morbi venenatis, purus id fermentum consequat, nunc libero tincidunt ligula, non dictum ligula orci nec quam. Nulla nec ultrices lorem. Aenean maximus augue vel dictum pharetra. Etiam turpis urna, pellentesque quis malesuada eu, molestie faucibus felis. - -Vestibulum pharetra augue ut quam blandit congue in nec risus. Proin eu nibh eu dui eleifend porta vitae id lectus. Proin lacus nibh, lobortis sed ligula vitae, interdum lobortis erat. Suspendisse potenti. In sollicitudin quis sapien ut aliquet. Mauris ac nulla arcu. Fusce tristique justo quis lectus mollis, eu volutpat lectus finibus. Vivamus venenatis facilisis ex ut vestibulum. - -Etiam varius lobortis purus, in hendrerit elit tristique at. In tempus, augue vestibulum fermentum gravida, ligula tellus vulputate arcu, eu molestie ex sapien at purus. Vestibulum nec egestas metus. Duis pulvinar quam nec consequat interdum. Aenean non dapibus lacus. Aliquam sit amet aliquet nulla. Sed venenatis volutpat purus nec convallis. Phasellus aliquet semper sodales. Cras risus sapien, condimentum auctor urna a, pulvinar ornare nisl. Sed tincidunt felis elit, ut elementum est bibendum ac. Morbi interdum justo vel dui faucibus condimentum. - -Sed convallis eu sem at tincidunt. Nullam at auctor est, et ullamcorper ipsum. Pellentesque eget ante ante. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer euismod, sapien sed dapibus ornare, nibh enim maximus lacus, lacinia placerat urna quam quis felis. Morbi accumsan id nisl ut condimentum. Donec bibendum nisi est, sed volutpat lorem rhoncus in. Vestibulum ac lacinia nunc, eget volutpat magna. Integer aliquam pharetra ipsum, id placerat nunc volutpat quis. Etiam urna diam, rhoncus sit amet varius vel, euismod vel sem. Nullam vel molestie urna. Vivamus ornare erat at venenatis euismod. Suspendisse potenti. Fusce diam justo, tincidunt vel sem at, commodo faucibus nisl. Duis gravida efficitur diam, vel sagittis erat pulvinar ut. - -Quisque vel pharetra felis. Duis efficitur tortor dolor, vitae porttitor erat fermentum sed. Sed eu mi purus. Etiam dignissim tortor eu tempus molestie. Aenean pretium erat enim, in hendrerit ante hendrerit at. Sed ut risus vel nunc venenatis ultricies quis in lacus. Pellentesque vitae purus euismod, placerat risus non, ullamcorper augue. Quisque varius quam ligula, nec aliquet ex faucibus vitae. Quisque rhoncus sit amet leo tincidunt mattis. Cras id mauris eget purus pretium gravida sit amet eu augue. Aliquam dapibus odio augue, id lacinia velit pulvinar eu. - -Mauris fringilla, tellus nec pharetra iaculis, neque nisi ultrices massa, et tincidunt sem dui sed mi. Curabitur erat lorem, venenatis quis tempus lacinia, tempus sit amet nunc. Aliquam at neque ac metus commodo dictum quis vitae justo. Phasellus eget lacus tempus, blandit lorem vel, rutrum est. Aenean pharetra sem ut augue lobortis dignissim. Sed rhoncus at nulla id ultrices. Cras id condimentum felis. In suscipit luctus vulputate. Donec tincidunt lacus nec enim tincidunt sollicitudin ut quis enim. Nam at libero urna. Praesent sit amet massa vitae massa ullamcorper vehicula. - -Nullam bibendum augue ut turpis condimentum bibendum. Proin sit amet urna hendrerit, sodales tortor a, lobortis lectus. Integer sagittis velit turpis, et tincidunt nisi commodo eget. Duis tincidunt elit finibus accumsan cursus. Aenean dignissim scelerisque felis vel lacinia. Nunc lacinia maximus luctus. In hac habitasse platea dictumst. Vestibulum eget urna et enim tempor tempor. Nam feugiat, felis vel vestibulum tempus, orci justo viverra diam, id dapibus lorem justo in ligula. - -Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In ac pellentesque sem. Vestibulum lacinia magna dui, eu lacinia augue placerat et. Maecenas pulvinar congue est. Pellentesque commodo dui non pulvinar scelerisque. Etiam interdum est posuere sem bibendum, ac commodo magna dictum. Cras ipsum turpis, rhoncus nec posuere vitae, laoreet a arcu. Integer ac massa sit amet enim placerat lacinia sed ultrices arcu. Suspendisse sem nibh, luctus sit amet volutpat in, pellentesque eu metus. Ut gravida neque eget mi accumsan tempus. Nam sit amet aliquet nibh. - -Pellentesque a purus cursus nulla hendrerit congue quis et odio. Aenean hendrerit, leo ullamcorper sagittis hendrerit, erat dui molestie quam, sed condimentum lacus risus sed tellus. Morbi a dapibus lectus, ut feugiat ex. Phasellus pretium quam et sapien mollis, vel iaculis dui dignissim. Sed ullamcorper est turpis, a viverra lorem consectetur in. Aenean aliquet nibh non cursus rutrum. Suspendisse at tristique urna, id lobortis urna. In hac habitasse platea dictumst. Phasellus libero velit, rutrum sed tellus nec, dapibus tincidunt ligula. Quisque vel dui venenatis, consequat nisl ut, lacinia ipsum. Phasellus vitae magna pellentesque, lobortis est id, faucibus quam. Nam eleifend faucibus dui vel pellentesque. - -Etiam ut est non lacus tincidunt interdum. Maecenas sed massa urna. Quisque ut nibh tortor. Pellentesque felis ipsum, tempor finibus ipsum et, euismod pretium metus. Donec sit amet est ipsum. Quisque rhoncus justo non finibus elementum. Nulla nec lectus ac tortor placerat fringilla. Phasellus ac ultrices nunc, eu efficitur nisl. Nulla rhoncus nunc vitae ante dictum tincidunt. Nunc ultrices, massa sit amet malesuada dignissim, lectus lacus consequat sapien, non eleifend metus sem in eros. Phasellus mauris ante, dictum sit amet suscipit ac, rhoncus eget nisi. Phasellus at orci mollis, imperdiet neque eget, faucibus nulla. In at purus massa. Pellentesque quis rutrum lectus. - -Integer eu faucibus turpis, sit amet mollis massa. Vestibulum id nulla commodo, rutrum ipsum sed, semper ante. Phasellus condimentum orci nec nibh convallis, ac maximus orci ullamcorper. Maecenas vitae sollicitudin mi. Integer et finibus lectus, et condimentum ligula. Donec elementum tristique quam vitae dapibus. Morbi euismod ipsum in tristique ullamcorper. - -Duis fermentum non enim eu auctor. Quisque lacinia nibh vehicula nibh posuere, eu volutpat turpis facilisis. Ut ac faucibus nulla. Sed eleifend quis ex et pellentesque. Vestibulum sollicitudin in libero id fringilla. Phasellus dignissim purus consequat, condimentum dui sit amet, condimentum ante. Pellentesque ac consectetur massa, quis sagittis est. Nulla maximus tristique risus accumsan convallis. Curabitur imperdiet ac lacus a ultrices. Nulla facilisi. Sed quis quam quis lectus placerat lobortis vel sed turpis. In mollis dui id neque iaculis, ut aliquet tellus malesuada. Proin at luctus odio, vel blandit sapien. Praesent dignissim tortor vehicula libero fringilla, nec ultrices erat suscipit. Maecenas scelerisque purus in dapibus fermentum. - -Curabitur magna odio, mattis in tortor ut, porttitor congue est. Vestibulum mollis lacinia elementum. Fusce maximus erat vitae nunc rutrum lobortis. Integer ligula eros, auctor vel elit non, posuere luctus lacus. Maecenas quis auctor massa. Ut ipsum lacus, efficitur posuere euismod et, hendrerit efficitur est. Phasellus fringilla, quam id tincidunt pretium, nunc dui sollicitudin orci, eu dignissim nisi metus ut magna. Integer lobortis interdum dolor, non bibendum purus posuere et. Donec non lectus aliquet, pretium dolor eu, cursus massa. Sed ut dui sapien. In sed vestibulum massa. Pellentesque blandit, dui non sodales vehicula, orci metus mollis nunc, non pharetra ex tellus ac est. Mauris sagittis metus et fermentum pretium. Nulla facilisi. Quisque quis ante ut nulla placerat mattis ut quis nisi. - -Sed quis nulla ligula. Quisque dignissim ligula urna, sed aliquam purus semper at. Suspendisse potenti. Nunc massa lectus, pharetra vehicula arcu bibendum, imperdiet sodales ipsum. Nam ac sapien diam. Mauris iaculis fringilla mattis. Pellentesque tempus eros sit amet justo volutpat mollis. Phasellus ac turpis ipsum. Morbi vel ante elit. Aenean posuere quam consequat velit varius suscipit. Donec tempor quam ut nibh cursus efficitur. - -Morbi molestie dolor nec sem egestas suscipit. Etiam placerat pharetra lectus, et ullamcorper risus tristique in. Sed faucibus ullamcorper lectus eget fringilla. Maecenas malesuada hendrerit congue. Sed eget neque a erat placerat tincidunt. Aliquam vitae dignissim turpis. Fusce at placerat magna, a laoreet lectus. Maecenas a purus nec diam gravida fringilla. Nam malesuada euismod ante non vehicula. In faucibus bibendum leo, faucibus posuere nisl pretium quis. Fusce finibus bibendum finibus. Vestibulum eu justo maximus, hendrerit diam nec, dignissim sapien. Aenean dolor lacus, malesuada quis vestibulum ac, venenatis ac ipsum. Cras a est id nunc finibus facilisis. Cras lacinia neque et interdum vehicula. Suspendisse vulputate tellus elit, eget tempor dui finibus vel. - -Cras sed pretium odio. Proin hendrerit elementum felis in tincidunt. Nam sed turpis vel justo molestie accumsan condimentum eu nunc. Praesent lobortis euismod rhoncus. Nulla vitae euismod nibh, quis mattis mi. Fusce ultrices placerat porttitor. Duis sem ipsum, pellentesque sit amet odio a, molestie vulputate mauris. - -Duis blandit mollis ligula, sit amet mattis ligula finibus sit amet. Nunc a leo molestie, placerat diam et, vestibulum leo. Suspendisse facilisis neque purus, nec pellentesque ligula fermentum nec. Aenean malesuada mauris lorem, eu blandit arcu pulvinar quis. Duis laoreet urna lacus, non maximus arcu rutrum ultricies. Nulla augue dolor, suscipit eu mollis eu, aliquam condimentum diam. Ut semper orci luctus, pharetra turpis at, euismod mi. Nulla leo diam, finibus sit amet purus sed, maximus dictum lorem. Integer eu mi id turpis laoreet rhoncus. - -Integer a mauris tincidunt, finibus orci ut, pretium mauris. Nulla molestie nunc mi, id finibus lorem elementum sed. Proin quis laoreet ante. Integer nulla augue, commodo id molestie quis, rutrum ut turpis. Suspendisse et tortor turpis. Sed ut pharetra massa. Pellentesque elementum blandit sem, ut elementum tellus egestas a. Fusce eu purus nibh. - -Cras dignissim ligula scelerisque magna faucibus ullamcorper. Proin at condimentum risus, auctor malesuada quam. Nullam interdum interdum egestas. Nulla aliquam nisi vitae felis mollis dictum. Suspendisse dapibus consectetur tortor. Ut ut nisi non sem bibendum tincidunt. Vivamus suscipit leo quis gravida dignissim. - -Aliquam interdum, leo id vehicula mollis, eros eros rhoncus diam, non mollis ligula mi eu mauris. Sed ultrices vel velit sollicitudin tincidunt. Nunc auctor metus at ligula gravida elementum. Praesent interdum eu elit et mollis. Duis egestas quam sit amet velit dignissim consequat. Aliquam ac turpis nec nunc convallis sagittis. Fusce blandit, erat ac fringilla consectetur, dolor eros sodales leo, vel aliquet risus nisl et diam. Aliquam luctus felis vitae est eleifend euismod facilisis et lacus. Sed leo tellus, auctor eu arcu in, volutpat sagittis nisl. Pellentesque nisl ligula, placerat vel ullamcorper at, vulputate ac odio. Morbi ac faucibus orci, et tempus nulla. Proin rhoncus rutrum dolor, in venenatis mauris. Suspendisse a fermentum augue, non semper mi. Nunc eget pretium neque. Phasellus augue erat, feugiat ac aliquam congue, rutrum non sapien. Pellentesque ac diam gravida, consectetur felis at, ornare neque. - -Nullam interdum mattis sapien quis porttitor. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus aliquet rutrum ipsum id euismod. Maecenas consectetur massa et mi porta viverra. Nunc quam nibh, dignissim vitae maximus et, ullamcorper nec lorem. Nunc vitae justo dapibus, luctus lacus vitae, pretium elit. Maecenas et efficitur leo. Curabitur mauris lectus, placerat quis vehicula vitae, auctor ut urna. Quisque rhoncus pharetra luctus. In hac habitasse platea dictumst. Integer sit amet metus nec eros malesuada aliquam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi hendrerit mi ac leo aliquam, sit amet ultricies libero commodo. Mauris dapibus purus metus, sit amet viverra nibh imperdiet et. Nullam porta nulla tellus, quis vehicula diam imperdiet non. Vivamus enim massa, bibendum in fermentum in, ultrices at ex. - -Suspendisse fermentum id nibh eget accumsan. Duis dapibus bibendum erat ut sollicitudin. Aliquam nec felis risus. Pellentesque rhoncus ligula id sem maximus mollis sed nec massa. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ipsum ipsum, sodales sed enim id, convallis faucibus eros. Donec ultricies dictum tincidunt. Cras vitae nibh arcu. Pellentesque cursus, sapien nec consequat fermentum, ipsum ante suscipit dui, imperdiet hendrerit est nisl eu massa. Quisque vitae sem ligula. Aenean iaculis metus ut mauris interdum laoreet. Vivamus sed gravida dolor. - -Morbi nulla metus, porttitor sed eros sit amet, efficitur efficitur est. In vel nisl urna. Ut aliquet tellus at congue convallis. Phasellus imperdiet lobortis sollicitudin. Integer sodales, sem eu ultricies pharetra, erat erat porttitor odio, eget dapibus libero ipsum eget velit. Phasellus gravida nulla nisl, eu pharetra mi auctor vel. Sed blandit pharetra velit, ut egestas libero placerat non. Aliquam a interdum quam. Proin at tortor nec dui sollicitudin tempus sed vestibulum elit. Nunc non sollicitudin velit. - -Aenean consequat diam velit, sed rutrum tortor faucibus dictum. Quisque at semper augue. Duis ut est eget mi ornare bibendum id et ligula. Phasellus consequat tortor non leo pulvinar posuere. Proin vestibulum eleifend felis, in hendrerit tortor sollicitudin eu. Phasellus hendrerit, lacus vel laoreet interdum, dui tortor consequat justo, commodo ultricies arcu felis vitae enim. Vivamus eu sapien at leo suscipit rutrum eu at justo. Aenean et dolor a libero ullamcorper posuere. Integer laoreet placerat nisi in vulputate. Mauris laoreet eget risus sed cursus. Donec scelerisque neque a libero eleifend hendrerit. Nulla varius condimentum nunc sit amet fermentum. Aliquam lorem ex, varius nec mollis ut, ultrices in neque. Morbi sit amet porta leo. Integer iaculis fermentum lacus in vestibulum. - -Ut gravida, tellus ut maximus ultrices, erat est venenatis nisl, vitae pretium massa ex ac magna. Sed non purus eget ligula aliquet volutpat non quis arcu. Nam aliquam tincidunt risus, sit amet fringilla sapien vulputate ut. Mauris luctus suscipit pellentesque. Nunc porttitor dapibus ex quis tempus. Ut ullamcorper metus a eros vulputate, vitae viverra lectus convallis. Mauris semper imperdiet augue quis tincidunt. Integer porta pretium magna, sed cursus sem scelerisque sollicitudin. Nam efficitur, nibh pretium eleifend vestibulum, purus diam posuere sem, in egestas mauris augue sit amet urna. - -Vestibulum tincidunt euismod massa in congue. Duis interdum metus non laoreet fringilla. Donec at ligula congue, tincidunt nunc non, scelerisque nunc. Donec bibendum magna non est scelerisque feugiat at nec neque. Ut orci tortor, tempus eget massa non, dignissim faucibus dolor. Nam odio risus, accumsan pretium neque eget, accumsan dignissim dui. In ut neque auctor, scelerisque tellus sed, ullamcorper nisi. Suspendisse varius cursus quam at hendrerit. Vivamus elit libero, sagittis vitae sem ac, vulputate iaculis ligula. - -Sed lobortis laoreet purus sit amet rutrum. Pellentesque feugiat non leo vel lacinia. Quisque feugiat nisl a orci bibendum vestibulum. In et sollicitudin urna. Morbi a arcu ac metus faucibus tempus. Nam eu imperdiet sapien, suscipit mattis tortor. Aenean blandit ipsum nisi, a eleifend ligula euismod at. Integer tincidunt pharetra felis, mollis placerat mauris hendrerit at. Curabitur convallis, est sit amet luctus volutpat, massa lacus cursus augue, sed eleifend magna quam et risus. Aliquam lobortis tincidunt metus vitae porttitor. Suspendisse potenti. Aenean ullamcorper, neque id commodo luctus, nulla nunc lobortis quam, id dapibus neque dui nec mauris. Etiam quis lorem quis elit commodo ornare. Ut pharetra purus ultricies enim ultrices efficitur. Proin vehicula tincidunt molestie. Mauris et placerat sem. - -Aliquam erat volutpat. Suspendisse velit turpis, posuere ac lacus eu, lacinia laoreet velit. Sed interdum felis neque, id blandit sem malesuada sit amet. Ut sagittis justo erat, efficitur semper orci tempor sed. Donec enim massa, posuere varius lectus egestas, pellentesque posuere mi. Cras tincidunt ut libero sed mattis. Suspendisse quis magna et tellus posuere interdum vel at purus. Pellentesque fringilla tristique neque, id aliquet tellus ultricies non. Duis ut tellus vel odio lobortis vulputate. - -Integer at magna ac erat convallis vestibulum. Sed lobortis porttitor mauris. Fusce varius lorem et volutpat pulvinar. Aenean ac vulputate lectus, vitae consequat velit. Suspendisse ex dui, varius ut risus ut, dictum scelerisque sem. Vivamus urna orci, volutpat ut convallis ac, venenatis vitae urna. In hac habitasse platea dictumst. Etiam eu purus arcu. Aenean vulputate leo urna, vel tristique dui sagittis euismod. Suspendisse non tellus efficitur ante rhoncus volutpat at et sapien. - -Sed dapibus accumsan porttitor. Phasellus facilisis lectus finibus ligula dignissim, id pulvinar lectus feugiat. Nullam egestas commodo nisi posuere aliquet. Morbi sit amet tortor sagittis, rutrum dui nec, dapibus sapien. Sed posuere tortor tortor, interdum auctor magna varius vitae. Vestibulum id sagittis augue. Curabitur fermentum arcu sem, eu condimentum quam rutrum non. Phasellus rutrum nibh quis lectus rhoncus pretium. Curabitur dictum interdum elit. Vestibulum maximus sodales imperdiet. Mauris auctor nec purus sed venenatis. In in urna purus. - -Duis placerat molestie suscipit. Morbi a elit id purus efficitur consequat. Nunc ac commodo turpis. Etiam sit amet lacus a ipsum tempus venenatis sed vel nibh. Duis elementum aliquam mi sed tristique. Morbi ligula tortor, semper ac est vel, lobortis maximus erat. Curabitur ipsum felis, laoreet vel condimentum eget, ullamcorper sit amet mauris. Nulla facilisi. Nam at purus sed mi egestas placerat vitae vel magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse at dignissim diam. Phasellus consectetur eget neque vel viverra. Donec sollicitudin mattis dolor vel malesuada. Vivamus vehicula leo neque, vitae fermentum leo posuere et. Praesent dui est, finibus sit amet tristique quis, pharetra vel nibh. - -Duis nulla leo, accumsan eu odio eget, sagittis semper orci. Quisque ullamcorper ligula quam, commodo porttitor mauris ullamcorper eu. Cras varius sagittis felis in aliquam. Duis sodales risus ac justo vehicula, nec mattis diam lacinia. Cras eget lectus ipsum. Ut commodo, enim vitae malesuada hendrerit, ex dolor egestas lectus, sit amet hendrerit metus diam nec est. Vestibulum tortor metus, lobortis sit amet ante eget, tempor molestie lacus. In molestie et urna et semper. Mauris mollis, sem non hendrerit condimentum, sapien nisi cursus est, non suscipit quam justo non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam enim est, porta ac feugiat vitae, rutrum in lorem. Duis vehicula tortor ut posuere maximus. - -Nullam vestibulum non tellus sed commodo. Quisque mattis elit sit amet sapien sollicitudin, ut condimentum nisl congue. Aenean sagittis massa vel elit faucibus fermentum. Donec tincidunt nisi nec nisl sodales pellentesque. Mauris congue congue ligula ut suscipit. Vivamus velit tortor, tempor et gravida eget, fermentum sit amet ante. Nullam fringilla, lorem at ultrices cursus, urna neque ornare dolor, eu lacinia orci enim sed nibh. Ut a ullamcorper lectus, id mattis purus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean maximus sollicitudin posuere. Nunc at augue lacus. Aenean efficitur leo sit amet lacinia efficitur. - -Quisque venenatis quam mi, in pharetra odio vulputate eu. In vel nisl pulvinar, pulvinar ligula ut, sodales risus. Sed efficitur lectus at vestibulum tincidunt. Vestibulum eu ullamcorper elit. Fusce vestibulum magna enim, et tempor lacus posuere vitae. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer leo elit, luctus nec mattis sit amet, sollicitudin in turpis. - -Proin convallis venenatis leo, vitae tristique erat iaculis nec. Nulla facilisi. Duis porttitor, sapien et bibendum vulputate, sem libero sodales lacus, non malesuada felis erat ut libero. Nam non felis semper, finibus est a, mattis mauris. Praesent nec eros quam. Nulla hendrerit, augue consectetur eleifend ultricies, purus mi condimentum nulla, eget dapibus est nunc sed libero. Nullam elementum dui erat, vitae luctus libero sollicitudin et. Nulla odio magna, placerat in augue eu, dapibus imperdiet odio. Suspendisse imperdiet metus sit amet rhoncus dapibus. Cras at enim et urna vehicula cursus eu a mauris. Integer magna ante, eleifend ac placerat vitae, porta at nisi. Cras eget malesuada orci. Curabitur nunc est, vulputate id viverra et, dignissim sed odio. Curabitur non mattis sem. Sed bibendum, turpis vitae vehicula faucibus, nunc quam ultricies lectus, vitae viverra felis turpis at libero. - -Nullam ut egestas ligula. Proin hendrerit justo a lectus commodo venenatis. Nulla facilisi. Ut cursus lorem quis est bibendum condimentum. Aenean in tristique odio. Fusce tempor hendrerit ipsum. Curabitur mollis felis justo, quis dapibus erat auctor vel. Sed augue lectus, finibus ut urna quis, ullamcorper vestibulum dui. Etiam molestie aliquam tempor. Integer mattis sollicitudin erat, et tristique elit varius vel. Mauris a ex justo. - -Nam eros est, imperdiet non volutpat rutrum, pellentesque accumsan ligula. Duis sit amet turpis metus. Aenean in rhoncus metus, ac fringilla ex. Suspendisse condimentum egestas purus, ut pharetra odio vulputate vel. Duis tincidunt massa a placerat ultrices. Mauris ultricies nibh sit amet condimentum malesuada. Duis tincidunt id ipsum sed congue. - -Praesent eu ex augue. Nullam in porta ligula. In tincidunt accumsan arcu, in pellentesque magna tristique in. Mauris eleifend libero ac nisl viverra faucibus. Nam sollicitudin dolor in commodo hendrerit. Cras at orci metus. Ut quis laoreet orci. Vivamus ultrices leo pellentesque tempor aliquet. Maecenas ut eros vitae purus placerat vestibulum. Etiam vitae gravida dolor, quis rhoncus diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. - -Suspendisse fringilla lacinia sagittis. Integer tincidunt consectetur tristique. Morbi non orci convallis, congue sapien quis, vulputate nunc. Donec a libero vel magna elementum facilisis non quis mi. Mauris posuere tellus non ipsum ultrices elementum. Vivamus massa velit, facilisis quis placerat aliquet, aliquet nec leo. Praesent a maximus sem. Sed neque elit, feugiat vel quam non, molestie sagittis nunc. Etiam luctus nunc ac mauris scelerisque, nec rhoncus lacus convallis. Nunc pharetra, nunc ac pulvinar aliquam, ex ipsum euismod augue, nec porttitor lacus turpis vitae neque. Fusce bibendum odio id tortor faucibus pellentesque. Sed ac porta nibh, eu gravida erat. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam quis ullamcorper felis. Nulla mattis sagittis ante ac tincidunt. Integer ac felis efficitur, viverra libero et, facilisis ligula. Suspendisse a metus a massa rhoncus posuere. Phasellus suscipit ligula ut lacus facilisis, ac pellentesque ex tempor. Quisque consectetur massa mi, ac molestie libero dictum quis. Proin porttitor ligula quis erat tincidunt venenatis. Proin congue nunc sed elit gravida, nec consectetur lectus sodales. Etiam tincidunt convallis ipsum at vestibulum. Quisque maximus enim et mauris porttitor, et molestie magna tristique. Morbi vitae metus elit. Maecenas sed volutpat turpis. Aliquam vitae dolor vestibulum, elementum purus eget, dapibus nibh. Nullam egestas dui ac rutrum semper. - -Etiam hendrerit est metus, et condimentum metus aliquam ac. Pellentesque id neque id ipsum rhoncus vulputate. Aliquam erat nisl, posuere sit amet ligula ac, fermentum blandit felis. Vivamus fermentum mi risus, non lacinia purus viverra id. Aenean ac sapien consequat, finibus mauris nec, porta sem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed quis consectetur ex, dignissim bibendum nulla. Phasellus ac libero at quam vehicula euismod non eu leo. Phasellus a sapien augue. - -Maecenas ligula dui, bibendum vitae mauris et, auctor laoreet felis. Duis non libero a mi semper mattis. Quisque consequat luctus massa, quis tristique eros auctor feugiat. Maecenas sodales euismod neque vitae facilisis. Nullam laoreet imperdiet velit at pellentesque. Etiam massa odio, facilisis a consequat vitae, placerat vel magna. Nunc sagittis eros nec urna fringilla, pulvinar vestibulum nibh scelerisque. Sed magna metus, cursus eu consequat et, pharetra a est. Suspendisse elementum neque a dui malesuada lacinia. Donec sed ipsum volutpat, cursus urna id, ullamcorper arcu. Maecenas laoreet nisl eget velit egestas sollicitudin. Etiam nisl turpis, mollis id dignissim vitae, tristique vehicula ante. Maecenas eget placerat est, at rutrum augue. Vivamus faucibus lacinia ullamcorper. Sed pulvinar urna sodales ante sodales, at gravida leo dictum. - -Morbi maximus, quam a lobortis bibendum, enim felis varius elit, ac vehicula elit nisl ut lacus. Quisque ut arcu augue. Praesent id turpis quam. Sed sed arcu eros. Maecenas at cursus lorem, ac eleifend nisi. Fusce mattis felis at commodo pharetra. Praesent ac commodo ipsum. Quisque finibus et eros vitae tincidunt. In hac habitasse platea dictumst. Praesent purus ipsum, luctus lobortis ornare quis, auctor eget justo. Nam vel enim sollicitudin, faucibus tortor eu, sagittis eros. Ut nec consectetur erat. Donec ultricies malesuada ligula, a hendrerit sapien volutpat in. Maecenas sed enim vitae sapien pulvinar faucibus. - -Proin semper nunc nibh, non consequat neque ullamcorper vel. Maecenas lobortis sagittis blandit. Aenean et arcu ultricies turpis malesuada malesuada. Ut quam ex, laoreet ut blandit cursus, feugiat vitae dolor. Etiam ex lacus, scelerisque vel erat vel, efficitur tincidunt magna. Morbi tristique lacinia dolor, in egestas magna ultrices vitae. Integer ultrices leo ac tempus venenatis. Praesent ac porta tortor. Vivamus ornare blandit tristique. Nulla rutrum finibus pellentesque. In non dui elementum, fermentum ipsum vel, varius magna. Pellentesque euismod tortor risus, ac pellentesque nisl faucibus eget. - -Vivamus eu enim purus. Cras ultrices rutrum egestas. Sed mollis erat nibh, at posuere nisl luctus nec. Nunc vulputate, sapien id auctor molestie, nisi diam tristique ante, non convallis tellus nibh at orci. Morbi a posuere purus, in ullamcorper ligula. Etiam elementum sit amet dui imperdiet iaculis. Proin vitae tincidunt ipsum, sit amet placerat lectus. Curabitur commodo sapien quam, et accumsan lectus fringilla non. Nullam eget accumsan enim, ac pharetra mauris. Sed quis tristique velit, vitae commodo nisi. Duis turpis dui, maximus ut risus at, finibus consequat nunc. Maecenas sed est accumsan, aliquet diam in, facilisis risus. Curabitur vehicula rutrum auctor. Nam iaculis risus pulvinar maximus viverra. Nulla vel augue et ex sagittis blandit. - -Ut sem nulla, porta ac ante ac, posuere laoreet eros. Donec sodales posuere justo a auctor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras mollis at orci hendrerit porta. Nullam sodales tortor tortor, non lacinia diam finibus id. Duis libero orci, suscipit ac odio et, dictum consequat ipsum. Pellentesque eu ligula sagittis, volutpat eros at, lacinia lorem. Cras euismod tellus in iaculis tempor. Quisque accumsan, magna a congue venenatis, ante ipsum aliquam lectus, at egestas enim nunc at justo. Quisque sem purus, viverra ut tristique ut, maximus id enim. Etiam quis placerat sem. In sollicitudin, lacus eu rutrum mollis, nulla eros luctus elit, vel dapibus urna purus nec urna. Phasellus egestas massa quam, ac molestie erat hendrerit a. Praesent ultrices neque ut turpis molestie auctor. Etiam molestie placerat purus, et euismod erat aliquam in. Morbi id suscipit justo. - -Proin est ante, consequat at varius a, mattis quis felis. Sed accumsan nibh sit amet ipsum elementum posuere. Vestibulum bibendum id diam sit amet gravida. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi nec dolor vel ipsum dignissim hendrerit vel non ipsum. Praesent facilisis orci quis elit auctor lobortis. Phasellus cursus risus lectus, vel lobortis libero dapibus in. Quisque tristique tempus leo a pulvinar. Pellentesque a magna tincidunt, pellentesque massa nec, laoreet orci. Morbi congue ornare dolor quis commodo. Phasellus massa nisi, tincidunt at eros dictum, hendrerit lobortis urna. Maecenas porta, magna id mattis molestie, nibh tellus lobortis sem, eget tincidunt ipsum quam eu turpis. - -Ut gravida orci risus, vel rutrum mauris vehicula id. Etiam bibendum, neque a placerat condimentum, ex orci imperdiet lectus, quis dapibus arcu lacus eget lectus. Sed consequat non mi sit amet venenatis. Fusce vestibulum erat libero, eget hendrerit risus vulputate sollicitudin. Integer sed eleifend felis. Donec commodo, sem eu mattis placerat, urna odio aliquam tellus, et laoreet justo tellus eget erat. Fusce sed suscipit tortor. Nam hendrerit nibh ac nunc auctor lacinia. Pellentesque placerat condimentum ipsum, eget semper tortor hendrerit vel. Nullam non urna eu lacus pellentesque congue ut id eros. - -Nunc finibus leo in rhoncus tristique. Sed eu ipsum nec nisl egestas faucibus eget a felis. Pellentesque vitae nisi in nulla accumsan fermentum. Sed venenatis feugiat eleifend. Fusce porttitor varius placerat. Aliquam aliquet lacus sit amet mattis mollis. Sed vel nulla quis dolor suscipit vehicula ac viverra lorem. Duis viverra ipsum eget nulla ullamcorper fermentum. Mauris tincidunt arcu quis quam fringilla ornare. Donec et iaculis tortor. Nam ultricies libero vel ipsum aliquet efficitur. Morbi eget dolor aliquam, tempus sapien eget, viverra ante. Donec varius mollis ex, sed efficitur purus euismod interdum. Quisque vel sapien non neque tincidunt semper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. - -Suspendisse sit amet purus leo. Fusce lectus lorem, aliquam ac nulla eget, imperdiet ornare eros. Nullam sem augue, varius in nisi non, sollicitudin pellentesque ante. Etiam eu odio condimentum, tempor libero et, egestas arcu. Cras pellentesque eleifend aliquet. Pellentesque non blandit ligula. Ut congue viverra rhoncus. Phasellus mattis mi ac eros placerat, eu feugiat tellus ultrices. Aenean mollis laoreet libero eu imperdiet. Cras sed pulvinar mi, ac vehicula ligula. Vestibulum sit amet ex massa. In a egestas eros. - -Mauris pretium ipsum risus, venenatis cursus ante imperdiet id. Praesent eu turpis nec risus feugiat maximus ullamcorper ac lectus. Integer placerat at mi vel dapibus. Vestibulum fermentum turpis sit amet turpis viverra, id aliquet diam suscipit. Nam nec ex sed ante ullamcorper pharetra quis sit amet risus. Sed ac faucibus velit, id feugiat nibh. Nullam eget ipsum ex. Vivamus tincidunt non nunc non faucibus. Quisque bibendum viverra facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at nisi hendrerit quam suscipit egestas. Curabitur laoreet maximus ultricies. Duis ut tellus ac augue molestie dictum. - -Suspendisse rhoncus iaculis erat, ut ullamcorper est tristique eget. Donec auctor nec risus at gravida. Vivamus volutpat vulputate tellus, vel ultricies eros suscipit eget. Ut pulvinar id mi eu tempus. Morbi malesuada augue in dui varius, nec blandit neque vehicula. Donec ornare nec nisl in mollis. Morbi enim nisi, rhoncus nec est id, dapibus tempus urna. Ut id elit a felis vestibulum consectetur. Duis lectus quam, pharetra sit amet diam sed, posuere vestibulum erat. Fusce vitae maximus massa. Nullam id metus tempus, iaculis risus eu, lobortis urna. Quisque in congue urna. Pellentesque placerat neque in augue dapibus, non varius ex malesuada. Curabitur ut eleifend libero. Fusce vitae ligula luctus, fermentum enim vitae, ultrices erat. - -Sed viverra augue turpis, scelerisque egestas sapien mattis eu. Duis laoreet magna at ex pharetra dapibus. Praesent eget odio vel quam venenatis dictum. Nulla in sollicitudin dolor. Mauris lobortis nec eros vel rhoncus. Vestibulum porta viverra venenatis. Curabitur vel scelerisque quam, a egestas velit. Praesent volutpat tincidunt magna at laoreet. - -Cras nec lorem odio. Pellentesque quis dui urna. Praesent at tellus ac lectus scelerisque placerat nec eu risus. Vestibulum sit amet mattis ligula. Vivamus sed nisi at leo elementum accumsan at sit amet arcu. Aenean mattis tellus nec leo gravida, eget hendrerit nisl faucibus. Mauris pellentesque luctus condimentum. Maecenas pretium sapien nunc, eget commodo dolor maximus id. Mauris vestibulum accumsan massa a dictum. Phasellus interdum quam ligula, ut maximus diam blandit aliquam. Nunc vitae ex eu erat condimentum consectetur. Maecenas interdum condimentum volutpat. - -Donec et enim a libero rutrum laoreet. Praesent a condimentum sem, at tincidunt quam. In vel molestie risus. Sed urna dui, molestie vitae mollis laoreet, tempor quis lectus. Praesent vitae auctor est, et aliquet nunc. Curabitur vulputate blandit nulla, at gravida metus. Maecenas gravida dui eu iaculis tristique. Pellentesque posuere turpis nec auctor eleifend. Suspendisse bibendum diam eu tellus lobortis, et laoreet quam congue. In hac habitasse platea dictumst. Morbi dictum neque velit, eget rutrum eros ultrices sit amet. - -Phasellus fermentum risus pharetra consectetur bibendum. Donec magna tortor, lacinia vitae nibh quis, aliquet pretium lorem. Donec turpis nisi, pretium eu enim volutpat, mattis malesuada augue. Nullam vel tellus iaculis, sollicitudin elit eget, tincidunt lacus. Fusce elementum elementum felis et iaculis. Suspendisse porta eros nec neque malesuada, in malesuada ante sollicitudin. Vivamus bibendum viverra molestie. - -Integer feugiat, erat nec convallis aliquam, velit felis congue erat, molestie eleifend tellus erat in tellus. Nunc et justo purus. Donec egestas fermentum dui non feugiat. Quisque in sapien sagittis, gravida quam id, iaculis lectus. Cras sagittis rhoncus bibendum. Fusce quis metus in velit scelerisque tincidunt at non ipsum. Vivamus efficitur ante eu odio vulputate, vitae ultricies risus vehicula. Proin eget odio eu sem tincidunt feugiat vel id lorem. - -Vestibulum sit amet nulla dignissim, euismod mi in, fermentum tortor. Donec ut aliquet libero, lacinia accumsan velit. Donec et nulla quam. Nullam laoreet odio nec nunc imperdiet, a congue eros venenatis. Quisque nec tellus sit amet neque interdum posuere. Duis quis mi gravida, tincidunt diam convallis, ultricies augue. Mauris consequat risus non porttitor congue. Ut in ligula consequat, viverra nunc a, eleifend enim. Duis ligula urna, imperdiet nec facilisis et, ornare eu ex. Proin lobortis lectus a lobortis porttitor. Nulla leo metus, egestas eu libero sed, pretium faucibus felis. Vestibulum non sem tortor. Nam cursus est leo. Vivamus luctus enim odio, non interdum sem dapibus a. Aenean accumsan consequat lectus in imperdiet. - -Donec vehicula laoreet ipsum in posuere. Quisque vel quam imperdiet, sollicitudin nisi quis, suscipit velit. Morbi id sodales mauris. Curabitur tellus arcu, feugiat sed dui sit amet, sodales sagittis libero. Aenean vel suscipit metus, non placerat leo. Vestibulum quis nulla elit. Proin scelerisque non ante ut commodo. Interdum et malesuada fames ac ante ipsum primis in faucibus. - -Sed non urna dolor. Suspendisse convallis mi porta pulvinar ultrices. Suspendisse quam ipsum, hendrerit non scelerisque molestie, interdum dictum nunc. Morbi condimentum condimentum turpis eu luctus. Pellentesque sagittis sollicitudin odio, sed ultricies felis ornare sit amet. Sed ultrices ex leo, a tincidunt nisl gravida sed. Nullam ornare accumsan porta. Praesent consectetur id est nec sollicitudin. - -In hac habitasse platea dictumst. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sed ultrices nibh. Duis accumsan suscipit eros, a dictum odio tempus sit amet. Aenean imperdiet erat ac lacus finibus, scelerisque cursus massa imperdiet. Mauris molestie risus ut lacinia posuere. Nulla et sodales purus. Maecenas orci erat, placerat in tristique quis, placerat in mi. - -Donec sollicitudin pellentesque odio in feugiat. Morbi eu dolor ut mauris congue sollicitudin. Aliquam erat volutpat. Nulla id varius dui. Curabitur finibus urna ante, consectetur interdum nisi volutpat a. Quisque quis mi tristique, consequat tellus eget, rutrum sapien. Vivamus vitae tellus vulputate, rutrum ex eu, vulputate sem. Suspendisse viverra lorem tellus, vel interdum orci gravida quis. Ut laoreet arcu at mi ullamcorper finibus. Duis porta sagittis vestibulum. Sed commodo nisl vitae urna sollicitudin, nec lacinia est sodales. Curabitur imperdiet sodales dui sed iaculis. Sed ac tellus maximus, eleifend quam sit amet, feugiat elit. Aenean viverra, dui at mattis varius, est odio vestibulum sapien, sit amet mollis libero massa nec velit. Etiam quis sodales justo. - -Ut ultricies, sem eget sodales feugiat, nunc arcu congue elit, ac tempor justo massa nec purus. Maecenas enim nunc, pharetra eget dictum sit amet, tempus pellentesque velit. Suspendisse venenatis ligula in nulla mattis, et imperdiet ex tincidunt. Etiam vulputate, tellus et ultrices suscipit, enim velit laoreet massa, vitae congue odio enim ac urna. Morbi quam lorem, iaculis ac varius sagittis, euismod quis dolor. In ut dui eu purus feugiat consectetur. Vestibulum cursus velit quis lacus pellentesque iaculis. Cras in risus sed mauris porta rutrum. Nulla facilisi. Nullam eu bibendum est, non pellentesque lectus. Sed imperdiet feugiat lorem, quis convallis ante auctor in. Maecenas justo magna, scelerisque sit amet tellus eget, varius elementum risus. Duis placerat et quam sed varius. - -Duis nec nibh vitae nibh dignissim mollis quis sed felis. Curabitur vitae quam placerat, venenatis purus ut, euismod nisl. Curabitur porttitor nibh eu pulvinar ullamcorper. Suspendisse posuere nec ipsum ac dapibus. Cras convallis consectetur urna. Phasellus a nibh in dolor lacinia posuere id eget augue. In eu pharetra lorem, vitae cursus lacus. Aliquam tincidunt nibh lectus. Aenean facilisis ultricies posuere. Sed ut placerat orci. Curabitur scelerisque gravida blandit. Maecenas placerat ligula eget suscipit fringilla. Mauris a tortor justo. Aliquam hendrerit semper mollis. Phasellus et tincidunt libero. Etiam vel quam libero. - -Quisque aliquet tempor ex. Ut ante sem, vehicula at enim vel, gravida porta elit. Etiam vitae lacus a neque lobortis consectetur. Mauris sed interdum odio. Mauris elementum ex blandit tempor cursus. Integer in enim in leo viverra elementum. Fusce consectetur metus et sem rutrum, mattis euismod diam semper. Nunc sed ipsum vel urna consequat vehicula. Donec cursus pretium lorem, vestibulum pretium felis commodo sit amet. Nam blandit felis enim, eget gravida ex faucibus a. In nec neque massa. Etiam laoreet posuere ipsum. Praesent volutpat nunc dolor, ac vulputate magna facilisis non. Aenean congue turpis vel lectus sollicitudin tristique. Sed nec consequat purus, non vehicula quam. Etiam ultricies, est ac dictum tincidunt, turpis turpis pretium massa, a vulputate libero justo at nibh. - -Aliquam erat volutpat. Cras ultrices augue ac sollicitudin lobortis. Curabitur et aliquet purus. Duis feugiat semper facilisis. Phasellus lobortis cursus velit, a sollicitudin tortor. Nam feugiat sapien non dapibus condimentum. Morbi at mi bibendum, commodo quam at, laoreet enim. Integer eu ultrices enim. Sed vestibulum eu urna ut dictum. Curabitur at mattis leo, sed cursus massa. Aliquam porttitor, felis quis fermentum porttitor, justo velit feugiat nulla, eget condimentum sem dui ut sapien. - -In fringilla elit eu orci aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut eget fringilla tellus. Curabitur fermentum, mi et condimentum suscipit, elit neque bibendum dui, et hendrerit nunc metus id ipsum. Morbi placerat mi in hendrerit congue. Ut feugiat mauris eget scelerisque viverra. Vivamus sit amet erat dictum, sagittis lectus nec, pulvinar lorem. Sed non enim ac dui sollicitudin aliquet. Quisque ut lacus dolor. Fusce hendrerit malesuada euismod. Nulla faucibus vel mauris eu mollis. Mauris est diam, fringilla ac arcu feugiat, efficitur volutpat turpis. Aliquam venenatis cursus massa sed porttitor. Ut ac finibus enim, in tincidunt sapien. - -Nunc faucibus semper turpis a lacinia. Phasellus gravida, libero vel pulvinar ornare, ex sem tincidunt lectus, sit amet convallis augue risus at tortor. Quisque sit amet ipsum id nulla posuere vestibulum. Pellentesque scelerisque mauris vel leo viverra sodales. Nulla viverra aliquam ex, ut rutrum enim fermentum venenatis. Aenean eget dapibus ex, eget faucibus metus. Vestibulum volutpat leo in diam semper, eget porta magna suscipit. Sed sit amet nulla blandit, aliquam dolor ac, gravida velit. Sed vel velit viverra, maximus est id, convallis justo. - -Curabitur nulla ante, vulputate at libero vel, ullamcorper rutrum nibh. Pellentesque porttitor eu mauris id mattis. Duis vulputate augue elit, eget interdum justo pretium vel. Maecenas eu vulputate arcu, eget posuere purus. Suspendisse viverra a velit dictum eleifend. Suspendisse vitae dapibus diam. Donec vehicula justo in ante interdum, eu luctus diam placerat. Vivamus convallis ipsum eu orci suscipit, sed fermentum enim euismod. Maecenas faucibus elit vitae ex ornare tristique. Donec vestibulum nec elit sit amet porttitor. Aenean tempor lectus eget tortor hendrerit luctus. Nullam interdum vitae lectus vel feugiat. Cras in risus non magna consectetur lobortis. Sed faucibus enim quis gravida convallis. - -Phasellus eget massa sit amet libero ultrices suscipit. Vivamus at risus sapien. Nam mollis nunc eget velit dictum maximus. Sed pellentesque, nunc ac fringilla lacinia, quam enim mattis ex, sed euismod tortor metus eu neque. Ut mattis nisl ut lectus rhoncus, sodales bibendum eros porta. Nulla porttitor enim nec diam sagittis, eget porta velit efficitur. Vestibulum ultricies eros neque. Phasellus rutrum suscipit enim, in interdum ante gravida vitae. Sed in sagittis diam, non commodo velit. - -Morbi hendrerit odio orci, nec tincidunt odio rhoncus nec. Mauris neque velit, vehicula a lorem at, suscipit tristique dui. Sed finibus, nisl in mattis convallis, turpis neque sodales lacus, eu porta enim magna non diam. Nam commodo sodales risus consectetur malesuada. In eget elementum justo. Phasellus sit amet massa imperdiet, dapibus nunc sit amet, suscipit orci. Fusce condimentum laoreet feugiat. Ut ut viverra ante. Praesent bibendum interdum commodo. Nulla mollis nisi a est ornare volutpat. Sed at ligula eu nisi dapibus tempus. Proin cursus vestibulum justo, nec efficitur justo dignissim vel. Nunc quis maximus eros. - -Cras viverra, diam a tristique mattis, libero felis vulputate tellus, a ornare felis leo a dui. Nulla ante nulla, finibus ut tellus ut, blandit pharetra nibh. Proin eleifend fermentum ex, eget auctor libero vulputate in. Nullam ultricies, mauris placerat pretium placerat, leo urna lobortis leo, vel placerat arcu libero sed mauris. Aliquam mauris ligula, ornare at urna at, eleifend gravida ligula. Vestibulum consectetur ut nulla non scelerisque. Donec ornare, sem nec elementum aliquam, urna nulla bibendum metus, eu euismod dui ligula ac est. Fusce laoreet erat eu ex lobortis, quis bibendum ligula interdum. Sed vel mi erat. Vivamus id lacus ac enim mattis tempor. Nunc ultricies pellentesque enim sed euismod. Fusce tincidunt convallis elit quis aliquam. Mauris nulla ipsum, sollicitudin quis diam ac, feugiat volutpat tellus. In nibh nibh, vulputate quis tincidunt quis, pulvinar eget magna. Pellentesque quis finibus dolor. Suspendisse viverra vitae lectus non eleifend. - -Nunc ut orci et sapien maximus semper. Nulla dignissim sem urna, ac varius lectus ultricies id. Quisque aliquet pulvinar pretium. In ultricies molestie tellus vehicula porta. Nam enim lorem, aliquam eget ex et, hendrerit volutpat quam. Maecenas diam lacus, pellentesque eget tempus ac, pharetra eu elit. Donec vel eros a sem facilisis vulputate. Nullam ac nisi vulputate, laoreet nisl ac, eleifend sem. Nullam mi massa, rhoncus sed pharetra interdum, tincidunt eget nunc. Aliquam viverra mattis posuere. Mauris et dui sed nisl sollicitudin fermentum quis ut arcu. Nam placerat eget orci at tincidunt. Curabitur vel turpis metus. Phasellus nibh nulla, fermentum scelerisque sem vel, gravida tincidunt velit. Pellentesque vel quam tempor, finibus massa pellentesque, condimentum dui. - -Donec at mattis neque. Etiam velit diam, consequat auctor mauris id, hendrerit faucibus metus. Maecenas ullamcorper eros a est sodales, ac consectetur odio scelerisque. Donec leo metus, imperdiet at pellentesque vel, feugiat id erat. Suspendisse at magna enim. Vestibulum placerat sodales lorem id sollicitudin. Aenean at euismod ligula, eget mollis diam. Phasellus pulvinar, orci nec pretium condimentum, est erat facilisis purus, quis feugiat augue elit aliquam nulla. Aenean vitae tortor id risus congue tincidunt. Sed dolor enim, mattis a ullamcorper id, volutpat ac leo. - -Proin vehicula feugiat augue, id feugiat quam sodales quis. Donec et ultricies massa, a lacinia nulla. Duis aliquam augue ornare euismod viverra. Ut lectus risus, rutrum sit amet efficitur a, luctus nec nisl. Cras volutpat ullamcorper congue. Sed vitae odio metus. Phasellus aliquet euismod varius. - -Nullam sem ex, malesuada ut magna ut, pretium mollis arcu. Nam porttitor eros cursus mi lacinia faucibus. Suspendisse aliquet eleifend iaculis. Maecenas sit amet viverra tortor. Nunc a mollis risus. Etiam tempus dolor in tortor malesuada mattis. Ut tincidunt venenatis est sit amet dignissim. Vestibulum massa enim, tristique sed scelerisque eu, fringilla ac velit. Donec efficitur quis urna sit amet malesuada. Vestibulum consequat ac ligula in dapibus. Maecenas massa massa, molestie non posuere nec, elementum ut magna. In nisi erat, mollis non venenatis eu, faucibus in justo. Morbi gravida non ex non egestas. Pellentesque finibus laoreet diam, eu commodo augue congue vitae. - -Aenean sem mi, ullamcorper dapibus lobortis vitae, interdum tincidunt tortor. Vivamus eget vulputate libero. Ut bibendum posuere lectus, vel tincidunt tortor aliquet at. Phasellus malesuada orci et bibendum accumsan. Aliquam quis libero vel leo mollis porta. Sed sagittis leo ac lacus dictum, ac malesuada elit finibus. Suspendisse pharetra luctus commodo. Vivamus ultricies a odio non interdum. Vivamus scelerisque tincidunt turpis quis tempor. Pellentesque tortor ligula, varius non nunc eu, blandit sollicitudin neque. Nunc imperdiet, diam et tristique luctus, ipsum ex condimentum nunc, sit amet aliquam justo velit sed libero. Duis vel suscipit ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed tincidunt neque vel massa ultricies, id dictum leo consequat. Curabitur lobortis ultricies tellus, eget mattis nisl aliquam sit amet. - -Proin at suscipit justo. Vivamus ut vestibulum nisl. Pellentesque enim odio, pharetra non magna sed, efficitur auctor magna. Praesent tincidunt ante quis ante hendrerit viverra. Pellentesque vel ipsum id magna vulputate efficitur. Sed nec neque accumsan, pulvinar sapien quis, euismod mauris. Donec condimentum laoreet sapien quis gravida. Quisque sed mattis purus. Vestibulum placerat vel neque maximus scelerisque. - -Vestibulum mattis quam quis efficitur elementum. Duis dictum dolor ac scelerisque commodo. Fusce sollicitudin nisi sit amet dictum placerat. Suspendisse euismod pharetra eleifend. In eros nisl, porttitor sed mauris at, consectetur aliquet mauris. Donec euismod viverra neque sed fermentum. Phasellus libero magna, accumsan ut ultricies vitae, dignissim eget metus. Donec tellus turpis, interdum eget maximus nec, hendrerit eget massa. Curabitur auctor ligula in iaculis auctor. In ultrices quam suscipit cursus finibus. Aenean id mi at dolor interdum iaculis vitae ut lorem. Nullam sed nibh fringilla, lacinia odio nec, placerat erat. In dui libero, viverra ac viverra ac, pellentesque sit amet turpis. - -Nulla in enim ex. Sed feugiat est et consectetur venenatis. Cras varius facilisis dui vel convallis. Vestibulum et elit eget tellus feugiat pellentesque. In ut ante eu purus aliquet posuere. Nulla nec ornare sem, sed luctus lorem. Nam varius iaculis odio, eget faucibus nisl ullamcorper in. Sed eget cursus felis, nec efficitur nisi. - -Vivamus commodo et sem quis pulvinar. Pellentesque libero ante, venenatis vitae ligula sit amet, ornare sollicitudin nulla. Mauris eget tellus hendrerit, pulvinar metus quis, tempor nisi. Proin magna ex, laoreet sed tortor quis, varius fermentum enim. Integer eu dolor dictum, vulputate tortor et, aliquet ligula. Vestibulum vitae justo id mauris luctus sollicitudin. Suspendisse eget auctor neque, sodales egestas lorem. Vestibulum lacinia egestas metus vitae euismod. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus ex tellus, volutpat nec pulvinar sit amet, condimentum vitae dui. Curabitur vel felis sodales, lacinia nunc iaculis, ullamcorper augue. Pellentesque consequat dolor quis eros efficitur malesuada. Nulla ut malesuada lectus. - -Morbi et tristique ante. Aliquam erat volutpat. Vivamus vitae dui nec turpis pellentesque fermentum. Quisque eget velit massa. Pellentesque tristique aliquam nisl, eu sollicitudin justo venenatis sed. Duis eleifend sem eros, ut aliquam libero porttitor id. Sed non nunc consequat, rhoncus diam eu, commodo erat. Praesent fermentum in lectus id blandit. Donec quis ipsum at justo volutpat finibus. Nulla blandit justo nulla, at mollis lacus consequat eget. Aenean sollicitudin quis eros ut ullamcorper. - -Pellentesque venenatis nulla ut mi aliquet feugiat. Cras semper vel magna nec pharetra. Integer mattis felis et sapien commodo imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis quis luctus felis. Vestibulum justo nibh, aliquam non lectus vitae, molestie placerat justo. Donec lorem nibh, gravida sit amet hendrerit ac, maximus id ipsum. Nunc ac libero sodales risus eleifend sagittis. Phasellus est massa, lobortis elementum ex sed, scelerisque consectetur neque. Nunc faucibus neque id lorem malesuada, eget convallis ex mattis. - -Sed turpis tortor, fermentum non turpis id, posuere varius nibh. Donec iaculis lorem dui. Etiam eros ante, sodales eget venenatis at, consectetur eget risus. Curabitur non aliquam ante, a pretium justo. Maecenas tempor nisl tortor, vitae dictum nisi ultrices eu. Duis eget dui ultrices, porttitor lacus sed, lobortis purus. Quisque mattis elit nec neque sagittis, sed commodo leo blandit. Mauris sodales interdum eleifend. Vestibulum condimentum consectetur augue, id luctus diam convallis et. - -Nunc suscipit risus in justo accumsan, a placerat magna tincidunt. Proin a nisl ipsum. Sed libero dui, tristique in augue quis, auctor tristique risus. Sed porttitor ex augue, eu porta augue molestie a. Duis rhoncus purus libero, eu tempus turpis condimentum at. Sed mollis nisi id lectus placerat tincidunt. Maecenas non scelerisque elit, quis rutrum orci. Donec in tellus pharetra urna ornare lobortis. Phasellus id risus at nisi varius rutrum eu ut turpis. - -Duis dictum justo quis nisl porta, eget tincidunt magna suscipit. Sed velit massa, ullamcorper eu sodales ac, pretium a massa. Duis et rutrum tortor. Nulla accumsan hendrerit sapien, cursus volutpat eros egestas eget. Donec sollicitudin at ante quis sollicitudin. Aenean blandit feugiat diam, id feugiat eros faucibus eget. Donec viverra dolor vel justo scelerisque dignissim. Nulla semper sem nunc, rhoncus semper tellus ultricies sed. Duis in ornare diam. Donec vehicula feugiat varius. Maecenas ut suscipit est. Vivamus sem sem, finibus at dolor sit amet, euismod dapibus ligula. Vestibulum fringilla odio dapibus, congue massa eget, congue sem. Donec feugiat magna eget tortor lacinia scelerisque non et ipsum. - -Suspendisse potenti. Nunc convallis sollicitudin ex eget venenatis. Sed iaculis nibh ex, vel ornare ligula congue dignissim. Quisque sollicitudin dolor ac dui vestibulum, sit amet molestie nisi aliquet. Donec at risus felis. Aenean sollicitudin metus a feugiat porta. Aenean a tortor ut dolor cursus sagittis. Vivamus consectetur porttitor nunc in facilisis. Proin sit amet mi vel lectus consectetur ultrices. - -Sed cursus lectus vitae nunc tristique, nec commodo turpis dapibus. Pellentesque luctus ex id facilisis ornare. Morbi quis placerat dolor. Donec in lectus in arcu mattis porttitor ac sit amet metus. Cras congue mauris non risus sodales, vitae feugiat ipsum bibendum. Nulla venenatis urna sed libero elementum, a cursus lorem commodo. Mauris faucibus lobortis eros nec commodo. - -Nullam suscipit ligula ullamcorper lorem commodo blandit. Nulla porta nibh quis pulvinar placerat. Vivamus eu arcu justo. Vestibulum imperdiet est ut fermentum porttitor. Pellentesque consectetur libero in sapien efficitur scelerisque. Curabitur ac erat sit amet odio aliquet dignissim. Pellentesque mi sem, rhoncus et luctus at, porttitor rutrum lectus. Vestibulum sollicitudin sollicitudin suscipit. Aenean efficitur dolor non ultrices imperdiet. Donec vel sem ex. - -Sed convallis mauris aliquam rutrum cursus. Ut tempor porttitor sodales. Etiam eu risus ac augue gravida egestas et eu dolor. Proin id magna ex. Suspendisse quis lectus quis lorem ultricies tempus. Donec porttitor velit vitae tincidunt faucibus. Aliquam vitae semper nisi. Morbi ultrices, leo non pretium dapibus, dui libero pellentesque ex, vel placerat enim ante vitae dui. Nunc varius, sem sit amet sagittis lobortis, lectus odio scelerisque mauris, ut vestibulum orci magna quis neque. Sed id congue justo. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris congue nisi est, malesuada mollis elit tincidunt sed. Curabitur sed ex sit amet felis tristique elementum vitae vel nibh. - -Etiam mollis pretium lobortis. Mauris augue lacus, efficitur at lacus sed, mollis tincidunt lectus. Aliquam erat volutpat. Donec at euismod elit, et mattis felis. Sed id lobortis urna. Morbi imperdiet vestibulum leo, sed maximus leo blandit eu. Aliquam semper lorem neque, nec euismod turpis mattis mollis. Quisque lobortis urna ultrices odio pretium, ac venenatis orci faucibus. Suspendisse bibendum odio ligula, sed lobortis massa pharetra nec. Donec turpis justo, iaculis at dictum ac, finibus eu libero. Maecenas quis porttitor mi, sit amet aliquet neque. - -Vivamus auctor vulputate ante, at egestas lorem. Donec eu risus in nulla mollis ultricies at et urna. Duis accumsan porta egestas. Ut vel euismod augue. Fusce convallis nulla ante, nec fringilla velit aliquet at. Nam malesuada dapibus ligula, a aliquam nibh scelerisque ac. Praesent malesuada neque et pellentesque interdum. Curabitur volutpat at turpis vitae tristique. Vivamus porttitor semper congue. Quisque suscipit lacus mi, rhoncus ultrices tortor auctor quis. Maecenas neque neque, molestie ac facilisis eget, luctus ac lorem. In ut odio ut lacus suscipit pulvinar vitae sed elit. Nulla imperdiet, sem quis euismod sagittis, dui erat luctus dolor, faucibus faucibus erat sem eget nunc. Nam accumsan placerat malesuada. Maecenas convallis finibus pulvinar. - -Cras at placerat tortor. Morbi facilisis auctor felis sit amet molestie. Donec sodales sed lorem vitae suscipit. Etiam fermentum pharetra ipsum, nec luctus orci gravida eu. Pellentesque gravida, est non condimentum tempus, mauris ligula molestie est, in congue dolor nisl vel sapien. Duis congue tempor augue, id rutrum eros porta dapibus. Etiam rutrum eget est eget vestibulum. Aenean mollis arcu vel consequat varius. Praesent at condimentum felis. Duis nec interdum nisl. Donec commodo lorem sed sapien scelerisque malesuada non eu urna. In blandit non ipsum at porta. Nam lobortis leo vitae dui auctor, non feugiat quam bibendum. Donec auctor lectus sagittis laoreet maximus. Maecenas rhoncus laoreet porttitor. Vestibulum porttitor augue ut lectus hendrerit, eget posuere mi gravida. - -Sed mattis ex in erat pulvinar, eu imperdiet magna dapibus. Etiam nisi nibh, tempus non tellus sit amet, mattis tempor odio. Quisque nec lorem feugiat, lobortis odio et, commodo nunc. Maecenas semper purus nisi, nec vehicula nibh eleifend vitae. Nulla fermentum a lectus at maximus. Phasellus finibus metus non euismod ultrices. Etiam a pulvinar ante. Quisque convallis nec metus sit amet facilisis. Praesent laoreet massa et sollicitudin laoreet. Vestibulum in mauris aliquet, convallis mi ut, elementum purus. Nulla purus nulla, sodales at hendrerit quis, tempus sed lectus. - -Nam ut laoreet neque, ut maximus nibh. Maecenas quis justo pellentesque, sollicitudin elit at, venenatis velit. Aenean nunc velit, vehicula scelerisque odio at, consectetur laoreet purus. Duis dui purus, malesuada quis ipsum sit amet, tempor interdum libero. Curabitur porta scelerisque sapien, vitae cursus diam condimentum eu. Phasellus sed orci quam. Nullam vitae dui quis purus tincidunt vestibulum. Curabitur quis nulla porta, cursus arcu non, auctor enim. Etiam sollicitudin ex id sem vehicula mollis. Morbi viverra laoreet tincidunt. Praesent ut semper dui. Nam sit amet pretium neque. Mauris vitae luctus diam, in lacinia purus. Maecenas ut placerat justo, ut porta felis. Integer eu mauris ante. - -Aenean porttitor tellus diam, tempor consequat metus efficitur id. Suspendisse ut felis at erat tempor dictum at nec sapien. Sed vestibulum interdum felis, ac mattis mauris porta in. Nunc et condimentum massa. Sed cursus dictum justo et luctus. Integer convallis enim nisl, a rutrum lectus ultricies in. Donec dapibus lacus at nulla dapibus, id sollicitudin velit hendrerit. Fusce a magna at orci mollis rutrum ac a dolor. Aliquam erat volutpat. Morbi varius porta nunc, sit amet sodales ex hendrerit commodo. Donec tincidunt tortor sapien, vitae egestas sapien vehicula eget. - -Suspendisse potenti. Donec pulvinar felis nec leo malesuada interdum. Integer posuere placerat maximus. Donec nibh ipsum, tincidunt vitae luctus vitae, bibendum at leo. Sed cursus nisl ut ex faucibus aliquet sed nec eros. Curabitur molestie posuere felis. Integer faucibus velit eget consequat iaculis. Mauris sed vulputate odio. Phasellus maximus, elit a pharetra egestas, lorem magna semper tellus, vestibulum semper diam felis at sapien. Suspendisse facilisis, nisl sit amet euismod vehicula, libero nulla vehicula dolor, quis fermentum nibh elit sit amet diam. - -Morbi lorem enim, euismod eu varius ut, scelerisque quis odio. Nam tempus vitae eros id molestie. Nunc pretium in nulla eget accumsan. Quisque mattis est ut semper aliquet. Maecenas eget diam elementum, fermentum ipsum a, euismod sapien. Duis quam ligula, cursus et velit nec, ullamcorper tincidunt magna. Donec vulputate nisl est, et ullamcorper urna tempor sit amet. - -Proin lacinia dui non turpis congue pretium. Morbi posuere metus vel purus imperdiet interdum. Morbi venenatis vel eros non ultricies. Nulla vel semper elit. Ut quis purus tincidunt, auctor justo ut, faucibus turpis. Proin quis mattis erat, at faucibus ligula. Mauris in mauris enim. Donec facilisis enim at est feugiat hendrerit. Nam vel nisi lorem. Fusce ultricies convallis diam, in feugiat tortor luctus quis. Donec tempor, leo vitae volutpat aliquam, magna elit feugiat leo, quis placerat sapien felis eget arcu. Donec ornare fermentum eleifend. Integer a est orci. - -Proin rhoncus egestas leo. Nulla ultricies porta elit quis ornare. Nunc fermentum interdum vehicula. In in ligula lorem. Donec nec arcu sit amet orci lobortis iaculis. Mauris at mollis erat, sit amet mollis tortor. Mauris laoreet justo ullamcorper porttitor auctor. Aenean sit amet aliquam lectus, id fermentum eros. Praesent urna sem, vehicula ac fermentum id, dapibus ut purus. Vestibulum vitae tempus nunc. Donec at nunc ornare metus volutpat porta at eget magna. Donec varius aliquet metus, eu lobortis risus aliquam sed. Ut dapibus fermentum velit, ac tincidunt libero faucibus at. - -In in purus auctor, feugiat massa quis, facilisis nisi. Donec dolor purus, gravida eget dolor ac, porttitor imperdiet urna. Donec faucibus placerat erat, a sagittis ante finibus ac. Sed venenatis dignissim elit, in iaculis felis posuere faucibus. Praesent sed viverra dolor. Mauris sed nulla consectetur nunc laoreet molestie in ut metus. Proin ac ex sit amet magna vulputate hendrerit ac condimentum urna. Proin ligula metus, gravida et sollicitudin facilisis, iaculis ut odio. Cras tincidunt urna et augue varius, ut facilisis urna consequat. Aenean vehicula finibus quam. Ut iaculis eu diam ac mollis. Nam mi lorem, tristique eget varius at, sodales at urna. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin vitae dictum erat, et auctor ipsum. Nullam nunc nunc, sollicitudin quis magna a, vestibulum fermentum mauris. Praesent at erat dolor. Proin laoreet tristique nulla vel efficitur. Nam sed ultrices nibh, id rutrum nunc. Curabitur eleifend a erat sit amet sollicitudin. Nullam metus quam, laoreet vitae dapibus id, placerat sed leo. Aliquam erat volutpat. Donec turpis nisl, cursus eu ex sit amet, lacinia pellentesque nisl. Sed id ipsum massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec interdum scelerisque lorem eu mattis. - -Vivamus ac tristique massa, nec facilisis nisl. Nam ipsum neque, tincidunt vel urna in, cursus imperdiet enim. Nam pellentesque egestas tempus. Morbi facilisis imperdiet libero vitae fringilla. Nam lacinia ligula at sapien facilisis malesuada. Nullam accumsan pulvinar sem, et cursus libero porta sit amet. Curabitur vulputate erat elit, ut pulvinar erat maximus vel. - -Cras aliquet metus ut purus sagittis, vel venenatis ante consectetur. Pellentesque nulla lacus, viverra viverra mattis non, placerat vitae nibh. Donec enim turpis, accumsan sit amet tincidunt eu, imperdiet non metus. Morbi ipsum eros, tincidunt vel est ac, tristique porttitor nibh. Praesent ut ullamcorper mauris. Sed laoreet sit amet diam congue venenatis. Integer porta purus nec orci sagittis posuere. - -Donec vehicula mauris eget lacus mollis venenatis et sed nibh. Nam sodales ligula ipsum, scelerisque lacinia ligula sagittis in. Nam sit amet ipsum at erat malesuada congue. Aenean ut sollicitudin sapien. Etiam at tempor odio. Mauris vitae purus ut magna suscipit consequat. Vivamus quis sapien neque. Nulla vulputate sem sit amet massa pellentesque, eleifend tristique ligula egestas. Suspendisse tincidunt gravida mi, in pulvinar lectus egestas non. Aenean imperdiet ex sit amet nunc sollicitudin porta. Integer justo odio, ultricies at interdum in, rhoncus vitae sem. Sed porttitor arcu quis purus aliquet hendrerit. Praesent tempor tortor at dolor dictum pulvinar. Nulla aliquet nunc non ligula scelerisque accumsan. Donec nulla justo, congue vitae massa in, faucibus hendrerit magna. Donec non egestas purus. - -’†•¶abc Vivamus iaculis, lacus efficitur faucibus porta, dui nulla facilisis ligula, ut sodales odio nunc id sapien. Cras viverra auctor ipsum, dapibus mattis neque dictum sed. Sed convallis fermentum molestie. Nulla facilisi turpis duis. \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_utf16be.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_utf16be.txt deleted file mode 100644 index 468eee80007..00000000000 Binary files a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_utf16be.txt and /dev/null differ diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_utf16le.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_utf16le.txt deleted file mode 100644 index b9a7dff430d..00000000000 Binary files a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_utf16le.txt and /dev/null differ diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_utf8bom.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_utf8bom.txt deleted file mode 100644 index edd30bae3c9..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/lorem_utf8bom.txt +++ /dev/null @@ -1,283 +0,0 @@ -öäüß Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vulputate, ipsum quis interdum fermentum, lorem sem fermentum eros, vitae auctor neque lacus in nisi. Suspendisse potenti. Maecenas et scelerisque elit, in tincidunt quam. Sed eu tincidunt quam. Nullam justo ex, imperdiet a imperdiet et, fermentum sit amet eros. Aenean quis tempus sem. Pellentesque accumsan magna mi, ut mollis velit sagittis id. Etiam quis ipsum orci. Fusce purus ante, accumsan a lobortis at, venenatis eu nisl. Praesent ornare sed ante placerat accumsan. Suspendisse tempus dignissim fermentum. Nunc a leo ac lacus sodales iaculis eu vitae mi. In feugiat ante at massa finibus cursus. Suspendisse posuere fringilla ornare. Mauris elementum ac quam id convallis. Vestibulum non elit quis urna volutpat aliquam a eu lacus. - -Aliquam vestibulum imperdiet neque, suscipit aliquam elit ultrices bibendum. Suspendisse ultrices pulvinar cursus. Morbi risus nisi, cursus consequat rutrum vitae, molestie sed dui. Fusce posuere, augue quis dignissim aliquam, nisi ipsum porttitor ante, quis fringilla nisl turpis ac nisi. Nulla varius enim eget lorem vehicula gravida. Donec finibus malesuada leo nec semper. Proin ac enim eros. Vivamus non tincidunt nisi, vel tristique lorem. - -Nunc consequat ex id eros dignissim, id rutrum risus laoreet. Sed euismod non erat eu ultricies. Etiam vehicula gravida lacus ut porta. Vestibulum eu eros quis nunc aliquet luctus. Cras quis semper ligula. Nullam gravida vehicula quam sed porta. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In porta cursus vulputate. Quisque porta a nisi eget cursus. Aliquam risus leo, luctus ac magna in, efficitur cursus magna. In condimentum non mi id semper. Donec interdum ante eget commodo maximus. - -Vivamus sit amet vestibulum lectus. Fusce tincidunt mi sapien, dictum sollicitudin diam vulputate in. Integer fringilla consequat mollis. Cras aliquet consequat felis eget feugiat. Nunc tempor cursus arcu, vitae ornare nunc varius et. Vestibulum et tortor vel ante viverra porttitor. Nam at tortor ullamcorper, facilisis augue quis, tristique erat. Aenean ut euismod nibh. Quisque eu tincidunt est, nec euismod eros. - -Proin vehicula nibh non viverra egestas. Phasellus sem dolor, ultricies ac sagittis tristique, lacinia a purus. Vestibulum in ante eros. Pellentesque lacus nulla, tristique vitae interdum vel, malesuada ac diam. Aenean bibendum posuere turpis in accumsan. Ut est nulla, ullamcorper quis turpis at, viverra sagittis mauris. Sed in interdum purus. Praesent scelerisque nibh eget sem euismod, ut imperdiet mi venenatis. Vivamus pulvinar orci sed dapibus auctor. Nulla facilisi. Vestibulum tincidunt erat nec porttitor egestas. Mauris quis risus ante. Nulla facilisi. - -Aliquam ullamcorper ornare lobortis. Phasellus quis sem et ipsum mollis malesuada sed in ex. Ut aliquam ex eget metus finibus maximus. Proin suscipit mauris eu nibh lacinia, quis feugiat dui dapibus. Nam sed libero est. Aenean vulputate orci sit amet diam faucibus, eu sagittis sapien volutpat. Nam imperdiet felis turpis, at pretium odio pulvinar in. Sed vestibulum id eros nec ultricies. Sed quis aliquam tortor, vitae ullamcorper tellus. Donec egestas laoreet eros, id suscipit est rutrum nec. Sed auctor nulla eget metus aliquam, ut condimentum enim elementum. - -Aliquam suscipit non turpis sit amet bibendum. Fusce velit ligula, euismod et maximus at, luctus sed neque. Quisque pretium, nisl at ullamcorper finibus, lectus leo mattis sapien, vel euismod mauris diam ullamcorper ex. Nulla ut risus finibus, lacinia ligula at, auctor erat. Mauris consectetur sagittis ligula vel dapibus. Nullam libero libero, lobortis aliquam libero vel, venenatis ultricies leo. Duis porttitor, nibh congue fermentum posuere, erat libero pulvinar tortor, a pellentesque nunc ipsum vel sem. Nullam volutpat, eros sit amet facilisis consectetur, ipsum est vehicula massa, non vestibulum neque elit in mauris. Nunc hendrerit ipsum non enim bibendum, vitae rhoncus mi egestas. Etiam ullamcorper massa vel nisl sagittis, nec bibendum arcu malesuada. Aenean aliquet turpis justo, a consectetur arcu mollis convallis. Etiam tellus ipsum, ultricies vitae lorem et, ornare facilisis orci. Praesent fringilla justo urna, vel mollis neque pulvinar vestibulum. - -Donec non iaculis erat. Aliquam et mi sed nunc pulvinar ultricies in ut ipsum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent feugiat lacus ac dignissim semper. Phasellus vitae quam nisi. Morbi vel diam ultricies risus lobortis ornare. Fusce maximus et ligula quis iaculis. Sed congue ex eget felis convallis, sit amet hendrerit elit tempor. Donec vehicula blandit ante eget commodo. Vestibulum eleifend diam at feugiat euismod. Etiam magna tellus, dignissim eget fermentum vel, vestibulum vitae mauris. Nam accumsan et erat id sagittis. Donec lacinia, odio ut ornare ultricies, dolor velit accumsan tortor, non finibus erat tellus quis ligula. Nunc quis metus in leo volutpat ornare vulputate eu nisl. - -Donec quis viverra ex. Nullam id feugiat mauris, eu fringilla nulla. Vestibulum id maximus elit. Cras elementum elit sed felis lobortis, eget sagittis nisi hendrerit. Vivamus vitae elit neque. Donec vulputate lacus ut libero ultrices accumsan. Vivamus accumsan nulla orci, in dignissim est laoreet sagittis. Proin at commodo velit. Curabitur in velit felis. Aliquam erat volutpat. Sed consequat, nulla et cursus sodales, nisi lacus mattis risus, quis eleifend erat ex nec turpis. Sed suscipit ultrices lorem in hendrerit. - -Morbi vitae lacus nec libero ornare tempus eu et diam. Suspendisse magna ipsum, fermentum vel odio quis, molestie aliquam urna. Fusce mollis turpis a eros accumsan porttitor. Pellentesque rhoncus dolor sit amet magna rutrum, et dapibus justo tempor. Sed purus nisi, maximus vitae fringilla eu, molestie nec urna. Fusce malesuada finibus pretium. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec sed aliquet eros. Pellentesque luctus diam ante, eget euismod nisl aliquet eu. Sed accumsan elit purus, tempor varius ligula tempus nec. Curabitur ornare leo suscipit suscipit fermentum. Morbi eget nulla est. Maecenas faucibus interdum tristique. - -Etiam ut elit eros. Nulla pharetra suscipit molestie. Nulla facilisis bibendum nisl non molestie. Curabitur turpis lectus, facilisis vel diam non, vulputate ultrices mauris. Aenean placerat aliquam convallis. Suspendisse sed scelerisque tellus. Vivamus lacinia neque eget risus cursus suscipit. Proin consequat dolor vel neque tempor, eu aliquam sem scelerisque. Duis non eros a purus malesuada pharetra non et nulla. Suspendisse potenti. Mauris libero eros, finibus vel nulla id, sagittis dapibus ante. Proin iaculis sed nunc et cursus. - -Quisque accumsan lorem sit amet lorem aliquet euismod. Curabitur fermentum rutrum posuere. Etiam ultricies, sem id pellentesque suscipit, urna magna lacinia eros, quis efficitur risus nisl at lacus. Nulla quis lacus tortor. Mauris placerat ex in dolor tincidunt, vel aliquet nisi pretium. Cras iaculis risus vitae pellentesque aliquet. Quisque a enim imperdiet, ullamcorper arcu vitae, rutrum risus. Nullam consectetur libero at felis fringilla, nec congue nibh dignissim. Nam et lobortis felis, eu pellentesque ligula. Aenean facilisis, ligula non imperdiet maximus, massa orci gravida sapien, at sagittis lacus nisl in lacus. Nulla quis mauris luctus, scelerisque felis consequat, tempus risus. Fusce auctor nisl non nulla luctus molestie. Maecenas sapien nisl, auctor non dolor et, iaculis scelerisque lorem. Suspendisse egestas enim aliquet, accumsan mauris nec, posuere quam. Nulla iaculis dui dui, sit amet vestibulum erat ultricies ac. - -Cras eget dolor erat. Proin at nisl ut leo consectetur ultricies vel ut arcu. Nulla in felis malesuada, ullamcorper tortor et, convallis massa. Nunc urna justo, ornare in nibh vitae, hendrerit condimentum libero. Etiam vitae libero in purus venenatis fringilla. Nullam velit nulla, consequat ut turpis non, egestas hendrerit nibh. Duis tortor turpis, interdum non ante ac, cursus accumsan lectus. Cras pharetra bibendum augue quis dictum. Sed euismod vestibulum justo. Proin porta lobortis purus. Duis venenatis diam tortor, sit amet condimentum eros rhoncus a. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc at magna nec diam lobortis efficitur sit amet ut lacus. Nulla quis orci tortor. Pellentesque tempus velit a odio finibus porta. - -Proin feugiat mauris a tellus scelerisque convallis. Maecenas libero magna, blandit nec ultrices id, congue vel mi. Aliquam lacinia, quam vel condimentum convallis, tortor turpis aliquam odio, sed blandit libero lacus et eros. In eleifend iaculis magna ac finibus. Praesent auctor facilisis tellus in congue. Sed molestie lobortis dictum. Nam quis dignissim augue, vel euismod lorem. Curabitur posuere dapibus luctus. Donec ultricies dictum lectus, quis blandit arcu commodo ac. Aenean tincidunt ligula in nunc imperdiet dignissim. Curabitur egestas sollicitudin sapien ut semper. Aenean nec dignissim lacus. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec aliquam dictum vehicula. Donec tortor est, volutpat non nisi nec, varius gravida ex. Nunc vel tristique nunc, vitae mattis nisi. Nunc nec luctus ex, vitae tincidunt lectus. In hac habitasse platea dictumst. Curabitur lobortis ex eget tincidunt tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut a vehicula mi. - -Fusce eu libero finibus, interdum nulla a, placerat neque. Cras bibendum tempor libero nec feugiat. Cras ut sodales eros. Proin viverra, massa sit amet viverra egestas, neque nisl porta ex, sit amet hendrerit libero ligula vel urna. Mauris suscipit lacus id justo rhoncus suscipit. Etiam vel libero tellus. Maecenas non diam molestie, condimentum tellus a, bibendum enim. Mauris aliquet imperdiet tellus, eget sagittis dolor. Sed blandit in neque et luctus. Cras elementum sagittis nunc, vel mollis lorem euismod et. Donec posuere at lacus eget suscipit. - -Nulla nunc mi, pretium non massa vel, tempor semper magna. Nunc a leo pulvinar, tincidunt nunc at, dignissim mi. Aliquam erat volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut viverra nulla a nisl finibus, at hendrerit ligula ullamcorper. Donec a lorem semper, tempor magna et, lobortis libero. Mauris id sapien leo. Donec dignissim, quam vitae porttitor dignissim, quam justo mattis dui, vel consequat odio elit quis orci. Etiam nec pretium neque, sit amet pretium orci. Duis ac tortor venenatis, feugiat purus non, feugiat nunc. Proin scelerisque nisl in turpis aliquam vulputate. - -Praesent sed est semper, fringilla lorem vitae, tincidunt nibh. Cras eros metus, auctor at mauris sit amet, sodales semper orci. Nunc a ornare ex. Curabitur bibendum arcu congue urna vulputate egestas. Vestibulum finibus id risus et accumsan. Aenean ut volutpat tellus. Aenean tincidunt malesuada urna sit amet vestibulum. Mauris vel tellus dictum, varius lacus quis, dictum arcu. - -Aenean quis metus eu erat feugiat cursus vel at ligula. Proin dapibus sodales urna, id euismod lectus tempus id. Pellentesque ex ligula, convallis et erat vel, vulputate condimentum nisl. Pellentesque pharetra nulla quis massa eleifend hendrerit. Praesent sed massa ipsum. Maecenas vehicula dolor massa, id sodales urna faucibus et. Mauris ac quam non massa tincidunt feugiat et at lacus. Fusce libero massa, vulputate vel scelerisque non, mollis in leo. Ut sit amet ultricies odio. Suspendisse in sapien viverra, facilisis purus ut, pretium libero. - -Vivamus tristique pharetra molestie. Nam a volutpat purus. Praesent consequat gravida nisi, ac blandit nisi suscipit ut. Quisque posuere, ligula a ultrices laoreet, ligula nunc vulputate libero, ut rutrum erat odio tincidunt justo. Sed vitae leo at leo fringilla bibendum. Vestibulum ut augue nec dolor auctor accumsan. Praesent laoreet id eros pulvinar commodo. Suspendisse potenti. Ut pharetra, mauris vitae blandit fringilla, odio ante tincidunt lorem, sit amet tempor metus diam ut turpis. - -Praesent quis egestas arcu. Nullam at porta arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi vulputate ligula malesuada ligula luctus, vulputate tempus erat bibendum. Nunc ullamcorper non lectus at euismod. Etiam nibh felis, tincidunt a metus vel, pellentesque rhoncus neque. Etiam at diam in erat luctus interdum. Nunc vel ipsum pulvinar, sollicitudin lacus ac, tempus urna. Etiam vel lacinia sapien. Pellentesque sagittis velit vel mi efficitur iaculis. Integer euismod sit amet urna in sagittis. Cras eleifend ut nibh in facilisis. Donec et lacus vitae nunc placerat sodales. Nulla sed hendrerit ligula, at dapibus sapien. - -Praesent at iaculis ex. Curabitur est purus, cursus a faucibus quis, dictum id velit. Donec dignissim fringilla viverra. Nunc mauris felis, laoreet sit amet sagittis at, vestibulum in libero. Maecenas quis orci turpis. Quisque ut nibh vitae magna mollis consequat id at mauris. Aliquam eu odio eget nulla bibendum sodales. Quisque vel orci eleifend nisi pretium lacinia. Suspendisse eget risus eget mi volutpat molestie eget quis lacus. Duis nisi libero, tincidunt nec nulla id, faucibus cursus felis. - -Donec tempor eget risus pellentesque molestie. Phasellus porta neque vel arcu egestas, nec blandit velit fringilla. Nullam porta faucibus justo vitae laoreet. Pellentesque viverra id nunc eu varius. Nulla pulvinar lobortis iaculis. Etiam vestibulum odio nec velit tristique, a tristique nisi mattis. In sed fringilla orci, vitae efficitur odio. Quisque dui odio, ornare eget velit at, lacinia consequat libero. Quisque lectus nulla, aliquet eu leo in, porta rutrum diam. Donec nec mattis neque. Nam rutrum, odio ac eleifend bibendum, dolor arcu rutrum neque, eget porta elit tellus a lacus. Sed massa metus, sollicitudin et sapien eu, finibus tempus orci. Proin et sapien sit amet erat molestie interdum. In quis rutrum velit, faucibus ultrices tellus. - -Sed sagittis sed justo eget tincidunt. Maecenas ut leo sagittis, feugiat magna et, viverra velit. Maecenas ex arcu, feugiat at consequat vitae, auctor eu massa. Integer egestas, enim vitae maximus convallis, est lectus pretium mauris, ac posuere lectus nisl quis quam. Aliquam tempus laoreet mi, vitae dapibus dolor varius dapibus. Suspendisse potenti. Donec sit amet purus nec libero dapibus tristique. Pellentesque viverra bibendum ligula. Donec sed felis et ex lobortis laoreet. Phasellus a fringilla libero, vitae malesuada nulla. Pellentesque blandit mattis lacus, et blandit tortor laoreet consequat. Suspendisse libero nunc, viverra sed fermentum in, accumsan egestas arcu. Proin in placerat elit. Sed interdum imperdiet malesuada. Suspendisse aliquet quis mauris eget sollicitudin. - -Vivamus accumsan tellus non erat volutpat, quis dictum dolor feugiat. Praesent rutrum nunc ac est mollis cursus. Fusce semper volutpat dui ut egestas. Curabitur sit amet posuere massa. Cras tincidunt nulla et mi mollis imperdiet. Suspendisse scelerisque ex id sodales vulputate. In nunc augue, pharetra in placerat eu, mattis id tellus. Vivamus cursus efficitur vehicula. Nulla aliquet vehicula aliquet. - -Sed cursus tellus sed porta pulvinar. Sed vitae nisi neque. Nullam aliquet, lorem et efficitur scelerisque, arcu diam aliquam felis, sed pulvinar lorem odio et turpis. Praesent convallis pulvinar turpis eu iaculis. Aliquam nec gravida mi. Curabitur eu nibh tempor, blandit justo in, ultrices felis. Fusce placerat metus non mi sagittis rutrum. Morbi sed dui fringilla, sagittis mauris eget, imperdiet nunc. Phasellus hendrerit sem elit, id hendrerit libero auctor sit amet. Integer sodales elit sit amet consequat cursus. - -Nam semper est eget nunc mollis, in pellentesque lectus fringilla. In finibus vel diam id semper. Nunc mattis quis erat eu consectetur. In hac habitasse platea dictumst. Nullam et ipsum vestibulum ex pulvinar ultricies sit amet id velit. Aenean suscipit mi tortor, a lobortis magna viverra non. Nulla condimentum aliquet ante et ullamcorper. Pellentesque porttitor arcu a posuere tempus. Aenean lacus quam, imperdiet eu justo vitae, pretium efficitur ex. Duis id purus id magna rhoncus ultrices id eu risus. Nunc dignissim et libero id dictum. - -Quisque a tincidunt neque. Phasellus commodo mi sit amet tempor fringilla. Ut rhoncus, neque non porttitor elementum, libero nulla egestas augue, sed fringilla sapien felis ac velit. Phasellus viverra rhoncus mollis. Nam ullamcorper leo vel erat laoreet luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus semper a metus a cursus. Nulla sed orci egestas, efficitur purus ac, malesuada tellus. Aenean rutrum velit at tellus fermentum mollis. Aliquam eleifend euismod metus. - -In hac habitasse platea dictumst. Vestibulum volutpat neque vitae porttitor laoreet. Nam at tellus consequat, sodales quam in, pulvinar arcu. Maecenas varius convallis diam, ac lobortis tellus pellentesque quis. Maecenas eget augue massa. Nullam volutpat nibh ac justo rhoncus, ut iaculis tellus rutrum. Fusce efficitur efficitur libero quis condimentum. Curabitur congue neque non tincidunt tristique. Fusce eget tempor ex, at pellentesque odio. Praesent luctus dictum vestibulum. Etiam non orci nunc. Vivamus vitae laoreet purus, a lobortis velit. Curabitur tincidunt purus ac lectus elementum pellentesque. Quisque sed tincidunt est. - -Sed vel ultrices massa, vitae ultricies justo. Cras finibus mauris nec lacus tempus dignissim. Cras faucibus maximus velit, eget faucibus orci luctus vehicula. Nulla massa nunc, porta ac consequat eget, rhoncus non tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce sed maximus metus, vel imperdiet ipsum. Ut scelerisque lectus at blandit porttitor. Ut vulputate nunc pharetra, aliquet sapien ac, sollicitudin sapien. Aenean eget ante lorem. Nam accumsan venenatis tellus id dignissim. - -Curabitur fringilla, magna non maximus dapibus, nulla sapien vestibulum lectus, sit amet semper dolor neque vitae nisl. Nunc ultrices vehicula augue sed iaculis. Maecenas nec diam mollis, suscipit orci et, vestibulum ante. Pellentesque eu nisl tortor. Nunc eleifend, lacus quis volutpat volutpat, nisi mi molestie sem, quis mollis ipsum libero a tellus. Ut viverra dolor mattis convallis interdum. Sed tempus nisl at nunc scelerisque aliquet. Quisque tempor tempor lorem id feugiat. Nullam blandit lectus velit, vitae porta lacus tincidunt a. Vivamus sit amet arcu ultrices, tincidunt mi quis, viverra quam. Aenean fringilla libero elementum lorem semper, quis pulvinar eros gravida. Nullam sodales blandit mauris, sed fermentum velit fermentum sit amet. Donec malesuada mauris in augue sodales vulputate. Vestibulum gravida turpis id elit rhoncus dignissim. Integer non congue lorem, eu viverra orci. - -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec at dolor magna. Aliquam consectetur erat augue, id iaculis velit pharetra ac. Integer rutrum venenatis dignissim. Integer non sodales elit. Curabitur ut magna ut nibh feugiat aliquam ac ut risus. Morbi nibh quam, aliquam id placerat nec, vestibulum eget velit. Suspendisse at dignissim quam. Vivamus aliquet sem sed nisl volutpat, ut cursus orci ultrices. Aliquam ultrices lacinia enim, vitae aliquet neque. - -Quisque scelerisque finibus diam in mattis. Cras cursus auctor velit. Aliquam sem leo, fermentum et maximus et, molestie a libero. Aenean justo elit, rutrum a ornare id, egestas eget enim. Aenean auctor tristique erat. Curabitur condimentum libero lacus, nec consequat orci vestibulum sed. Fusce elit ligula, blandit vitae sapien vitae, dictum ultrices risus. Nam laoreet suscipit sapien, at interdum velit faucibus sit amet. Duis quis metus egestas lectus elementum posuere non nec libero. Aliquam a dolor bibendum, facilisis nunc a, maximus diam. Vestibulum suscipit tristique magna, non dignissim turpis sodales sed. Nunc ornare, velit ac facilisis fringilla, dolor mi consectetur lorem, vitae finibus erat justo suscipit urna. Maecenas sit amet eros erat. Nunc non arcu ornare, suscipit lorem eget, sodales mauris. Aliquam tincidunt, quam nec mollis lacinia, nisi orci fermentum libero, consequat eleifend lectus quam et sapien. Vestibulum a quam urna. - -Cras arcu leo, euismod ac ullamcorper at, faucibus sed massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus porttitor velit in enim interdum, non commodo metus ornare. Morbi vel lorem quis nisl luctus tristique quis vitae nisl. Suspendisse condimentum tortor enim, nec eleifend ipsum euismod et. Sed gravida quam ut tristique lacinia. Mauris eu interdum ipsum, ac ultrices odio. Nullam auctor tellus a risus porttitor vehicula. Nulla blandit euismod dictum. In pharetra, enim iaculis pulvinar interdum, dui nunc placerat nunc, sit amet pretium lectus nulla vitae quam. Phasellus quis enim sollicitudin, varius nulla id, ornare purus. Donec quam lacus, vestibulum quis nunc ac, mollis dictum nisi. Cras ut mollis elit. Maecenas ultrices ligula at risus faucibus scelerisque. Etiam vitae porttitor purus. Curabitur blandit lectus urna, ut hendrerit tortor feugiat ut. - -Phasellus fringilla, sapien pellentesque commodo pharetra, ante libero aliquam tellus, ut consectetur augue libero a sapien. Maecenas blandit luctus nisl eget aliquet. Maecenas vitae porta dolor, faucibus laoreet sapien. Suspendisse lobortis, ipsum sed vehicula aliquam, elit purus scelerisque dui, rutrum consectetur diam odio et lorem. In nec lacinia metus. Donec viverra libero est, vel bibendum erat condimentum quis. Donec feugiat purus leo. In laoreet vitae felis a porttitor. Mauris ullamcorper, lacus id condimentum suscipit, neque magna pellentesque arcu, eget cursus neque tellus id metus. Curabitur volutpat ac orci vel ultricies. - -Sed ut finibus erat. Sed diam purus, varius non tincidunt quis, ultrices sit amet ipsum. Donec et egestas nulla. Suspendisse placerat nisi at dui laoreet iaculis. Aliquam aliquet leo at augue faucibus molestie. Nullam lacus augue, hendrerit sed nisi eu, faucibus porta est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam ut leo aliquet sem fermentum rutrum quis ac justo. Integer placerat aliquam nisl ut sagittis. Proin erat orci, lobortis et sem eget, eleifend fringilla augue. Mauris varius laoreet arcu, sed tincidunt felis. Pellentesque venenatis lorem odio, id pulvinar velit molestie feugiat. Donec mattis lacus sed eleifend pulvinar. - -Sed condimentum ex in tincidunt hendrerit. Etiam eget risus lacinia, euismod nibh eu, pellentesque quam. Proin elit eros, convallis id mauris ac, bibendum ultrices lectus. Morbi venenatis, purus id fermentum consequat, nunc libero tincidunt ligula, non dictum ligula orci nec quam. Nulla nec ultrices lorem. Aenean maximus augue vel dictum pharetra. Etiam turpis urna, pellentesque quis malesuada eu, molestie faucibus felis. - -Vestibulum pharetra augue ut quam blandit congue in nec risus. Proin eu nibh eu dui eleifend porta vitae id lectus. Proin lacus nibh, lobortis sed ligula vitae, interdum lobortis erat. Suspendisse potenti. In sollicitudin quis sapien ut aliquet. Mauris ac nulla arcu. Fusce tristique justo quis lectus mollis, eu volutpat lectus finibus. Vivamus venenatis facilisis ex ut vestibulum. - -Etiam varius lobortis purus, in hendrerit elit tristique at. In tempus, augue vestibulum fermentum gravida, ligula tellus vulputate arcu, eu molestie ex sapien at purus. Vestibulum nec egestas metus. Duis pulvinar quam nec consequat interdum. Aenean non dapibus lacus. Aliquam sit amet aliquet nulla. Sed venenatis volutpat purus nec convallis. Phasellus aliquet semper sodales. Cras risus sapien, condimentum auctor urna a, pulvinar ornare nisl. Sed tincidunt felis elit, ut elementum est bibendum ac. Morbi interdum justo vel dui faucibus condimentum. - -Sed convallis eu sem at tincidunt. Nullam at auctor est, et ullamcorper ipsum. Pellentesque eget ante ante. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer euismod, sapien sed dapibus ornare, nibh enim maximus lacus, lacinia placerat urna quam quis felis. Morbi accumsan id nisl ut condimentum. Donec bibendum nisi est, sed volutpat lorem rhoncus in. Vestibulum ac lacinia nunc, eget volutpat magna. Integer aliquam pharetra ipsum, id placerat nunc volutpat quis. Etiam urna diam, rhoncus sit amet varius vel, euismod vel sem. Nullam vel molestie urna. Vivamus ornare erat at venenatis euismod. Suspendisse potenti. Fusce diam justo, tincidunt vel sem at, commodo faucibus nisl. Duis gravida efficitur diam, vel sagittis erat pulvinar ut. - -Quisque vel pharetra felis. Duis efficitur tortor dolor, vitae porttitor erat fermentum sed. Sed eu mi purus. Etiam dignissim tortor eu tempus molestie. Aenean pretium erat enim, in hendrerit ante hendrerit at. Sed ut risus vel nunc venenatis ultricies quis in lacus. Pellentesque vitae purus euismod, placerat risus non, ullamcorper augue. Quisque varius quam ligula, nec aliquet ex faucibus vitae. Quisque rhoncus sit amet leo tincidunt mattis. Cras id mauris eget purus pretium gravida sit amet eu augue. Aliquam dapibus odio augue, id lacinia velit pulvinar eu. - -Mauris fringilla, tellus nec pharetra iaculis, neque nisi ultrices massa, et tincidunt sem dui sed mi. Curabitur erat lorem, venenatis quis tempus lacinia, tempus sit amet nunc. Aliquam at neque ac metus commodo dictum quis vitae justo. Phasellus eget lacus tempus, blandit lorem vel, rutrum est. Aenean pharetra sem ut augue lobortis dignissim. Sed rhoncus at nulla id ultrices. Cras id condimentum felis. In suscipit luctus vulputate. Donec tincidunt lacus nec enim tincidunt sollicitudin ut quis enim. Nam at libero urna. Praesent sit amet massa vitae massa ullamcorper vehicula. - -Nullam bibendum augue ut turpis condimentum bibendum. Proin sit amet urna hendrerit, sodales tortor a, lobortis lectus. Integer sagittis velit turpis, et tincidunt nisi commodo eget. Duis tincidunt elit finibus accumsan cursus. Aenean dignissim scelerisque felis vel lacinia. Nunc lacinia maximus luctus. In hac habitasse platea dictumst. Vestibulum eget urna et enim tempor tempor. Nam feugiat, felis vel vestibulum tempus, orci justo viverra diam, id dapibus lorem justo in ligula. - -Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In ac pellentesque sem. Vestibulum lacinia magna dui, eu lacinia augue placerat et. Maecenas pulvinar congue est. Pellentesque commodo dui non pulvinar scelerisque. Etiam interdum est posuere sem bibendum, ac commodo magna dictum. Cras ipsum turpis, rhoncus nec posuere vitae, laoreet a arcu. Integer ac massa sit amet enim placerat lacinia sed ultrices arcu. Suspendisse sem nibh, luctus sit amet volutpat in, pellentesque eu metus. Ut gravida neque eget mi accumsan tempus. Nam sit amet aliquet nibh. - -Pellentesque a purus cursus nulla hendrerit congue quis et odio. Aenean hendrerit, leo ullamcorper sagittis hendrerit, erat dui molestie quam, sed condimentum lacus risus sed tellus. Morbi a dapibus lectus, ut feugiat ex. Phasellus pretium quam et sapien mollis, vel iaculis dui dignissim. Sed ullamcorper est turpis, a viverra lorem consectetur in. Aenean aliquet nibh non cursus rutrum. Suspendisse at tristique urna, id lobortis urna. In hac habitasse platea dictumst. Phasellus libero velit, rutrum sed tellus nec, dapibus tincidunt ligula. Quisque vel dui venenatis, consequat nisl ut, lacinia ipsum. Phasellus vitae magna pellentesque, lobortis est id, faucibus quam. Nam eleifend faucibus dui vel pellentesque. - -Etiam ut est non lacus tincidunt interdum. Maecenas sed massa urna. Quisque ut nibh tortor. Pellentesque felis ipsum, tempor finibus ipsum et, euismod pretium metus. Donec sit amet est ipsum. Quisque rhoncus justo non finibus elementum. Nulla nec lectus ac tortor placerat fringilla. Phasellus ac ultrices nunc, eu efficitur nisl. Nulla rhoncus nunc vitae ante dictum tincidunt. Nunc ultrices, massa sit amet malesuada dignissim, lectus lacus consequat sapien, non eleifend metus sem in eros. Phasellus mauris ante, dictum sit amet suscipit ac, rhoncus eget nisi. Phasellus at orci mollis, imperdiet neque eget, faucibus nulla. In at purus massa. Pellentesque quis rutrum lectus. - -Integer eu faucibus turpis, sit amet mollis massa. Vestibulum id nulla commodo, rutrum ipsum sed, semper ante. Phasellus condimentum orci nec nibh convallis, ac maximus orci ullamcorper. Maecenas vitae sollicitudin mi. Integer et finibus lectus, et condimentum ligula. Donec elementum tristique quam vitae dapibus. Morbi euismod ipsum in tristique ullamcorper. - -Duis fermentum non enim eu auctor. Quisque lacinia nibh vehicula nibh posuere, eu volutpat turpis facilisis. Ut ac faucibus nulla. Sed eleifend quis ex et pellentesque. Vestibulum sollicitudin in libero id fringilla. Phasellus dignissim purus consequat, condimentum dui sit amet, condimentum ante. Pellentesque ac consectetur massa, quis sagittis est. Nulla maximus tristique risus accumsan convallis. Curabitur imperdiet ac lacus a ultrices. Nulla facilisi. Sed quis quam quis lectus placerat lobortis vel sed turpis. In mollis dui id neque iaculis, ut aliquet tellus malesuada. Proin at luctus odio, vel blandit sapien. Praesent dignissim tortor vehicula libero fringilla, nec ultrices erat suscipit. Maecenas scelerisque purus in dapibus fermentum. - -Curabitur magna odio, mattis in tortor ut, porttitor congue est. Vestibulum mollis lacinia elementum. Fusce maximus erat vitae nunc rutrum lobortis. Integer ligula eros, auctor vel elit non, posuere luctus lacus. Maecenas quis auctor massa. Ut ipsum lacus, efficitur posuere euismod et, hendrerit efficitur est. Phasellus fringilla, quam id tincidunt pretium, nunc dui sollicitudin orci, eu dignissim nisi metus ut magna. Integer lobortis interdum dolor, non bibendum purus posuere et. Donec non lectus aliquet, pretium dolor eu, cursus massa. Sed ut dui sapien. In sed vestibulum massa. Pellentesque blandit, dui non sodales vehicula, orci metus mollis nunc, non pharetra ex tellus ac est. Mauris sagittis metus et fermentum pretium. Nulla facilisi. Quisque quis ante ut nulla placerat mattis ut quis nisi. - -Sed quis nulla ligula. Quisque dignissim ligula urna, sed aliquam purus semper at. Suspendisse potenti. Nunc massa lectus, pharetra vehicula arcu bibendum, imperdiet sodales ipsum. Nam ac sapien diam. Mauris iaculis fringilla mattis. Pellentesque tempus eros sit amet justo volutpat mollis. Phasellus ac turpis ipsum. Morbi vel ante elit. Aenean posuere quam consequat velit varius suscipit. Donec tempor quam ut nibh cursus efficitur. - -Morbi molestie dolor nec sem egestas suscipit. Etiam placerat pharetra lectus, et ullamcorper risus tristique in. Sed faucibus ullamcorper lectus eget fringilla. Maecenas malesuada hendrerit congue. Sed eget neque a erat placerat tincidunt. Aliquam vitae dignissim turpis. Fusce at placerat magna, a laoreet lectus. Maecenas a purus nec diam gravida fringilla. Nam malesuada euismod ante non vehicula. In faucibus bibendum leo, faucibus posuere nisl pretium quis. Fusce finibus bibendum finibus. Vestibulum eu justo maximus, hendrerit diam nec, dignissim sapien. Aenean dolor lacus, malesuada quis vestibulum ac, venenatis ac ipsum. Cras a est id nunc finibus facilisis. Cras lacinia neque et interdum vehicula. Suspendisse vulputate tellus elit, eget tempor dui finibus vel. - -Cras sed pretium odio. Proin hendrerit elementum felis in tincidunt. Nam sed turpis vel justo molestie accumsan condimentum eu nunc. Praesent lobortis euismod rhoncus. Nulla vitae euismod nibh, quis mattis mi. Fusce ultrices placerat porttitor. Duis sem ipsum, pellentesque sit amet odio a, molestie vulputate mauris. - -Duis blandit mollis ligula, sit amet mattis ligula finibus sit amet. Nunc a leo molestie, placerat diam et, vestibulum leo. Suspendisse facilisis neque purus, nec pellentesque ligula fermentum nec. Aenean malesuada mauris lorem, eu blandit arcu pulvinar quis. Duis laoreet urna lacus, non maximus arcu rutrum ultricies. Nulla augue dolor, suscipit eu mollis eu, aliquam condimentum diam. Ut semper orci luctus, pharetra turpis at, euismod mi. Nulla leo diam, finibus sit amet purus sed, maximus dictum lorem. Integer eu mi id turpis laoreet rhoncus. - -Integer a mauris tincidunt, finibus orci ut, pretium mauris. Nulla molestie nunc mi, id finibus lorem elementum sed. Proin quis laoreet ante. Integer nulla augue, commodo id molestie quis, rutrum ut turpis. Suspendisse et tortor turpis. Sed ut pharetra massa. Pellentesque elementum blandit sem, ut elementum tellus egestas a. Fusce eu purus nibh. - -Cras dignissim ligula scelerisque magna faucibus ullamcorper. Proin at condimentum risus, auctor malesuada quam. Nullam interdum interdum egestas. Nulla aliquam nisi vitae felis mollis dictum. Suspendisse dapibus consectetur tortor. Ut ut nisi non sem bibendum tincidunt. Vivamus suscipit leo quis gravida dignissim. - -Aliquam interdum, leo id vehicula mollis, eros eros rhoncus diam, non mollis ligula mi eu mauris. Sed ultrices vel velit sollicitudin tincidunt. Nunc auctor metus at ligula gravida elementum. Praesent interdum eu elit et mollis. Duis egestas quam sit amet velit dignissim consequat. Aliquam ac turpis nec nunc convallis sagittis. Fusce blandit, erat ac fringilla consectetur, dolor eros sodales leo, vel aliquet risus nisl et diam. Aliquam luctus felis vitae est eleifend euismod facilisis et lacus. Sed leo tellus, auctor eu arcu in, volutpat sagittis nisl. Pellentesque nisl ligula, placerat vel ullamcorper at, vulputate ac odio. Morbi ac faucibus orci, et tempus nulla. Proin rhoncus rutrum dolor, in venenatis mauris. Suspendisse a fermentum augue, non semper mi. Nunc eget pretium neque. Phasellus augue erat, feugiat ac aliquam congue, rutrum non sapien. Pellentesque ac diam gravida, consectetur felis at, ornare neque. - -Nullam interdum mattis sapien quis porttitor. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus aliquet rutrum ipsum id euismod. Maecenas consectetur massa et mi porta viverra. Nunc quam nibh, dignissim vitae maximus et, ullamcorper nec lorem. Nunc vitae justo dapibus, luctus lacus vitae, pretium elit. Maecenas et efficitur leo. Curabitur mauris lectus, placerat quis vehicula vitae, auctor ut urna. Quisque rhoncus pharetra luctus. In hac habitasse platea dictumst. Integer sit amet metus nec eros malesuada aliquam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi hendrerit mi ac leo aliquam, sit amet ultricies libero commodo. Mauris dapibus purus metus, sit amet viverra nibh imperdiet et. Nullam porta nulla tellus, quis vehicula diam imperdiet non. Vivamus enim massa, bibendum in fermentum in, ultrices at ex. - -Suspendisse fermentum id nibh eget accumsan. Duis dapibus bibendum erat ut sollicitudin. Aliquam nec felis risus. Pellentesque rhoncus ligula id sem maximus mollis sed nec massa. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ipsum ipsum, sodales sed enim id, convallis faucibus eros. Donec ultricies dictum tincidunt. Cras vitae nibh arcu. Pellentesque cursus, sapien nec consequat fermentum, ipsum ante suscipit dui, imperdiet hendrerit est nisl eu massa. Quisque vitae sem ligula. Aenean iaculis metus ut mauris interdum laoreet. Vivamus sed gravida dolor. - -Morbi nulla metus, porttitor sed eros sit amet, efficitur efficitur est. In vel nisl urna. Ut aliquet tellus at congue convallis. Phasellus imperdiet lobortis sollicitudin. Integer sodales, sem eu ultricies pharetra, erat erat porttitor odio, eget dapibus libero ipsum eget velit. Phasellus gravida nulla nisl, eu pharetra mi auctor vel. Sed blandit pharetra velit, ut egestas libero placerat non. Aliquam a interdum quam. Proin at tortor nec dui sollicitudin tempus sed vestibulum elit. Nunc non sollicitudin velit. - -Aenean consequat diam velit, sed rutrum tortor faucibus dictum. Quisque at semper augue. Duis ut est eget mi ornare bibendum id et ligula. Phasellus consequat tortor non leo pulvinar posuere. Proin vestibulum eleifend felis, in hendrerit tortor sollicitudin eu. Phasellus hendrerit, lacus vel laoreet interdum, dui tortor consequat justo, commodo ultricies arcu felis vitae enim. Vivamus eu sapien at leo suscipit rutrum eu at justo. Aenean et dolor a libero ullamcorper posuere. Integer laoreet placerat nisi in vulputate. Mauris laoreet eget risus sed cursus. Donec scelerisque neque a libero eleifend hendrerit. Nulla varius condimentum nunc sit amet fermentum. Aliquam lorem ex, varius nec mollis ut, ultrices in neque. Morbi sit amet porta leo. Integer iaculis fermentum lacus in vestibulum. - -Ut gravida, tellus ut maximus ultrices, erat est venenatis nisl, vitae pretium massa ex ac magna. Sed non purus eget ligula aliquet volutpat non quis arcu. Nam aliquam tincidunt risus, sit amet fringilla sapien vulputate ut. Mauris luctus suscipit pellentesque. Nunc porttitor dapibus ex quis tempus. Ut ullamcorper metus a eros vulputate, vitae viverra lectus convallis. Mauris semper imperdiet augue quis tincidunt. Integer porta pretium magna, sed cursus sem scelerisque sollicitudin. Nam efficitur, nibh pretium eleifend vestibulum, purus diam posuere sem, in egestas mauris augue sit amet urna. - -Vestibulum tincidunt euismod massa in congue. Duis interdum metus non laoreet fringilla. Donec at ligula congue, tincidunt nunc non, scelerisque nunc. Donec bibendum magna non est scelerisque feugiat at nec neque. Ut orci tortor, tempus eget massa non, dignissim faucibus dolor. Nam odio risus, accumsan pretium neque eget, accumsan dignissim dui. In ut neque auctor, scelerisque tellus sed, ullamcorper nisi. Suspendisse varius cursus quam at hendrerit. Vivamus elit libero, sagittis vitae sem ac, vulputate iaculis ligula. - -Sed lobortis laoreet purus sit amet rutrum. Pellentesque feugiat non leo vel lacinia. Quisque feugiat nisl a orci bibendum vestibulum. In et sollicitudin urna. Morbi a arcu ac metus faucibus tempus. Nam eu imperdiet sapien, suscipit mattis tortor. Aenean blandit ipsum nisi, a eleifend ligula euismod at. Integer tincidunt pharetra felis, mollis placerat mauris hendrerit at. Curabitur convallis, est sit amet luctus volutpat, massa lacus cursus augue, sed eleifend magna quam et risus. Aliquam lobortis tincidunt metus vitae porttitor. Suspendisse potenti. Aenean ullamcorper, neque id commodo luctus, nulla nunc lobortis quam, id dapibus neque dui nec mauris. Etiam quis lorem quis elit commodo ornare. Ut pharetra purus ultricies enim ultrices efficitur. Proin vehicula tincidunt molestie. Mauris et placerat sem. - -Aliquam erat volutpat. Suspendisse velit turpis, posuere ac lacus eu, lacinia laoreet velit. Sed interdum felis neque, id blandit sem malesuada sit amet. Ut sagittis justo erat, efficitur semper orci tempor sed. Donec enim massa, posuere varius lectus egestas, pellentesque posuere mi. Cras tincidunt ut libero sed mattis. Suspendisse quis magna et tellus posuere interdum vel at purus. Pellentesque fringilla tristique neque, id aliquet tellus ultricies non. Duis ut tellus vel odio lobortis vulputate. - -Integer at magna ac erat convallis vestibulum. Sed lobortis porttitor mauris. Fusce varius lorem et volutpat pulvinar. Aenean ac vulputate lectus, vitae consequat velit. Suspendisse ex dui, varius ut risus ut, dictum scelerisque sem. Vivamus urna orci, volutpat ut convallis ac, venenatis vitae urna. In hac habitasse platea dictumst. Etiam eu purus arcu. Aenean vulputate leo urna, vel tristique dui sagittis euismod. Suspendisse non tellus efficitur ante rhoncus volutpat at et sapien. - -Sed dapibus accumsan porttitor. Phasellus facilisis lectus finibus ligula dignissim, id pulvinar lectus feugiat. Nullam egestas commodo nisi posuere aliquet. Morbi sit amet tortor sagittis, rutrum dui nec, dapibus sapien. Sed posuere tortor tortor, interdum auctor magna varius vitae. Vestibulum id sagittis augue. Curabitur fermentum arcu sem, eu condimentum quam rutrum non. Phasellus rutrum nibh quis lectus rhoncus pretium. Curabitur dictum interdum elit. Vestibulum maximus sodales imperdiet. Mauris auctor nec purus sed venenatis. In in urna purus. - -Duis placerat molestie suscipit. Morbi a elit id purus efficitur consequat. Nunc ac commodo turpis. Etiam sit amet lacus a ipsum tempus venenatis sed vel nibh. Duis elementum aliquam mi sed tristique. Morbi ligula tortor, semper ac est vel, lobortis maximus erat. Curabitur ipsum felis, laoreet vel condimentum eget, ullamcorper sit amet mauris. Nulla facilisi. Nam at purus sed mi egestas placerat vitae vel magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse at dignissim diam. Phasellus consectetur eget neque vel viverra. Donec sollicitudin mattis dolor vel malesuada. Vivamus vehicula leo neque, vitae fermentum leo posuere et. Praesent dui est, finibus sit amet tristique quis, pharetra vel nibh. - -Duis nulla leo, accumsan eu odio eget, sagittis semper orci. Quisque ullamcorper ligula quam, commodo porttitor mauris ullamcorper eu. Cras varius sagittis felis in aliquam. Duis sodales risus ac justo vehicula, nec mattis diam lacinia. Cras eget lectus ipsum. Ut commodo, enim vitae malesuada hendrerit, ex dolor egestas lectus, sit amet hendrerit metus diam nec est. Vestibulum tortor metus, lobortis sit amet ante eget, tempor molestie lacus. In molestie et urna et semper. Mauris mollis, sem non hendrerit condimentum, sapien nisi cursus est, non suscipit quam justo non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam enim est, porta ac feugiat vitae, rutrum in lorem. Duis vehicula tortor ut posuere maximus. - -Nullam vestibulum non tellus sed commodo. Quisque mattis elit sit amet sapien sollicitudin, ut condimentum nisl congue. Aenean sagittis massa vel elit faucibus fermentum. Donec tincidunt nisi nec nisl sodales pellentesque. Mauris congue congue ligula ut suscipit. Vivamus velit tortor, tempor et gravida eget, fermentum sit amet ante. Nullam fringilla, lorem at ultrices cursus, urna neque ornare dolor, eu lacinia orci enim sed nibh. Ut a ullamcorper lectus, id mattis purus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean maximus sollicitudin posuere. Nunc at augue lacus. Aenean efficitur leo sit amet lacinia efficitur. - -Quisque venenatis quam mi, in pharetra odio vulputate eu. In vel nisl pulvinar, pulvinar ligula ut, sodales risus. Sed efficitur lectus at vestibulum tincidunt. Vestibulum eu ullamcorper elit. Fusce vestibulum magna enim, et tempor lacus posuere vitae. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer leo elit, luctus nec mattis sit amet, sollicitudin in turpis. - -Proin convallis venenatis leo, vitae tristique erat iaculis nec. Nulla facilisi. Duis porttitor, sapien et bibendum vulputate, sem libero sodales lacus, non malesuada felis erat ut libero. Nam non felis semper, finibus est a, mattis mauris. Praesent nec eros quam. Nulla hendrerit, augue consectetur eleifend ultricies, purus mi condimentum nulla, eget dapibus est nunc sed libero. Nullam elementum dui erat, vitae luctus libero sollicitudin et. Nulla odio magna, placerat in augue eu, dapibus imperdiet odio. Suspendisse imperdiet metus sit amet rhoncus dapibus. Cras at enim et urna vehicula cursus eu a mauris. Integer magna ante, eleifend ac placerat vitae, porta at nisi. Cras eget malesuada orci. Curabitur nunc est, vulputate id viverra et, dignissim sed odio. Curabitur non mattis sem. Sed bibendum, turpis vitae vehicula faucibus, nunc quam ultricies lectus, vitae viverra felis turpis at libero. - -Nullam ut egestas ligula. Proin hendrerit justo a lectus commodo venenatis. Nulla facilisi. Ut cursus lorem quis est bibendum condimentum. Aenean in tristique odio. Fusce tempor hendrerit ipsum. Curabitur mollis felis justo, quis dapibus erat auctor vel. Sed augue lectus, finibus ut urna quis, ullamcorper vestibulum dui. Etiam molestie aliquam tempor. Integer mattis sollicitudin erat, et tristique elit varius vel. Mauris a ex justo. - -Nam eros est, imperdiet non volutpat rutrum, pellentesque accumsan ligula. Duis sit amet turpis metus. Aenean in rhoncus metus, ac fringilla ex. Suspendisse condimentum egestas purus, ut pharetra odio vulputate vel. Duis tincidunt massa a placerat ultrices. Mauris ultricies nibh sit amet condimentum malesuada. Duis tincidunt id ipsum sed congue. - -Praesent eu ex augue. Nullam in porta ligula. In tincidunt accumsan arcu, in pellentesque magna tristique in. Mauris eleifend libero ac nisl viverra faucibus. Nam sollicitudin dolor in commodo hendrerit. Cras at orci metus. Ut quis laoreet orci. Vivamus ultrices leo pellentesque tempor aliquet. Maecenas ut eros vitae purus placerat vestibulum. Etiam vitae gravida dolor, quis rhoncus diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. - -Suspendisse fringilla lacinia sagittis. Integer tincidunt consectetur tristique. Morbi non orci convallis, congue sapien quis, vulputate nunc. Donec a libero vel magna elementum facilisis non quis mi. Mauris posuere tellus non ipsum ultrices elementum. Vivamus massa velit, facilisis quis placerat aliquet, aliquet nec leo. Praesent a maximus sem. Sed neque elit, feugiat vel quam non, molestie sagittis nunc. Etiam luctus nunc ac mauris scelerisque, nec rhoncus lacus convallis. Nunc pharetra, nunc ac pulvinar aliquam, ex ipsum euismod augue, nec porttitor lacus turpis vitae neque. Fusce bibendum odio id tortor faucibus pellentesque. Sed ac porta nibh, eu gravida erat. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam quis ullamcorper felis. Nulla mattis sagittis ante ac tincidunt. Integer ac felis efficitur, viverra libero et, facilisis ligula. Suspendisse a metus a massa rhoncus posuere. Phasellus suscipit ligula ut lacus facilisis, ac pellentesque ex tempor. Quisque consectetur massa mi, ac molestie libero dictum quis. Proin porttitor ligula quis erat tincidunt venenatis. Proin congue nunc sed elit gravida, nec consectetur lectus sodales. Etiam tincidunt convallis ipsum at vestibulum. Quisque maximus enim et mauris porttitor, et molestie magna tristique. Morbi vitae metus elit. Maecenas sed volutpat turpis. Aliquam vitae dolor vestibulum, elementum purus eget, dapibus nibh. Nullam egestas dui ac rutrum semper. - -Etiam hendrerit est metus, et condimentum metus aliquam ac. Pellentesque id neque id ipsum rhoncus vulputate. Aliquam erat nisl, posuere sit amet ligula ac, fermentum blandit felis. Vivamus fermentum mi risus, non lacinia purus viverra id. Aenean ac sapien consequat, finibus mauris nec, porta sem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed quis consectetur ex, dignissim bibendum nulla. Phasellus ac libero at quam vehicula euismod non eu leo. Phasellus a sapien augue. - -Maecenas ligula dui, bibendum vitae mauris et, auctor laoreet felis. Duis non libero a mi semper mattis. Quisque consequat luctus massa, quis tristique eros auctor feugiat. Maecenas sodales euismod neque vitae facilisis. Nullam laoreet imperdiet velit at pellentesque. Etiam massa odio, facilisis a consequat vitae, placerat vel magna. Nunc sagittis eros nec urna fringilla, pulvinar vestibulum nibh scelerisque. Sed magna metus, cursus eu consequat et, pharetra a est. Suspendisse elementum neque a dui malesuada lacinia. Donec sed ipsum volutpat, cursus urna id, ullamcorper arcu. Maecenas laoreet nisl eget velit egestas sollicitudin. Etiam nisl turpis, mollis id dignissim vitae, tristique vehicula ante. Maecenas eget placerat est, at rutrum augue. Vivamus faucibus lacinia ullamcorper. Sed pulvinar urna sodales ante sodales, at gravida leo dictum. - -Morbi maximus, quam a lobortis bibendum, enim felis varius elit, ac vehicula elit nisl ut lacus. Quisque ut arcu augue. Praesent id turpis quam. Sed sed arcu eros. Maecenas at cursus lorem, ac eleifend nisi. Fusce mattis felis at commodo pharetra. Praesent ac commodo ipsum. Quisque finibus et eros vitae tincidunt. In hac habitasse platea dictumst. Praesent purus ipsum, luctus lobortis ornare quis, auctor eget justo. Nam vel enim sollicitudin, faucibus tortor eu, sagittis eros. Ut nec consectetur erat. Donec ultricies malesuada ligula, a hendrerit sapien volutpat in. Maecenas sed enim vitae sapien pulvinar faucibus. - -Proin semper nunc nibh, non consequat neque ullamcorper vel. Maecenas lobortis sagittis blandit. Aenean et arcu ultricies turpis malesuada malesuada. Ut quam ex, laoreet ut blandit cursus, feugiat vitae dolor. Etiam ex lacus, scelerisque vel erat vel, efficitur tincidunt magna. Morbi tristique lacinia dolor, in egestas magna ultrices vitae. Integer ultrices leo ac tempus venenatis. Praesent ac porta tortor. Vivamus ornare blandit tristique. Nulla rutrum finibus pellentesque. In non dui elementum, fermentum ipsum vel, varius magna. Pellentesque euismod tortor risus, ac pellentesque nisl faucibus eget. - -Vivamus eu enim purus. Cras ultrices rutrum egestas. Sed mollis erat nibh, at posuere nisl luctus nec. Nunc vulputate, sapien id auctor molestie, nisi diam tristique ante, non convallis tellus nibh at orci. Morbi a posuere purus, in ullamcorper ligula. Etiam elementum sit amet dui imperdiet iaculis. Proin vitae tincidunt ipsum, sit amet placerat lectus. Curabitur commodo sapien quam, et accumsan lectus fringilla non. Nullam eget accumsan enim, ac pharetra mauris. Sed quis tristique velit, vitae commodo nisi. Duis turpis dui, maximus ut risus at, finibus consequat nunc. Maecenas sed est accumsan, aliquet diam in, facilisis risus. Curabitur vehicula rutrum auctor. Nam iaculis risus pulvinar maximus viverra. Nulla vel augue et ex sagittis blandit. - -Ut sem nulla, porta ac ante ac, posuere laoreet eros. Donec sodales posuere justo a auctor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras mollis at orci hendrerit porta. Nullam sodales tortor tortor, non lacinia diam finibus id. Duis libero orci, suscipit ac odio et, dictum consequat ipsum. Pellentesque eu ligula sagittis, volutpat eros at, lacinia lorem. Cras euismod tellus in iaculis tempor. Quisque accumsan, magna a congue venenatis, ante ipsum aliquam lectus, at egestas enim nunc at justo. Quisque sem purus, viverra ut tristique ut, maximus id enim. Etiam quis placerat sem. In sollicitudin, lacus eu rutrum mollis, nulla eros luctus elit, vel dapibus urna purus nec urna. Phasellus egestas massa quam, ac molestie erat hendrerit a. Praesent ultrices neque ut turpis molestie auctor. Etiam molestie placerat purus, et euismod erat aliquam in. Morbi id suscipit justo. - -Proin est ante, consequat at varius a, mattis quis felis. Sed accumsan nibh sit amet ipsum elementum posuere. Vestibulum bibendum id diam sit amet gravida. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi nec dolor vel ipsum dignissim hendrerit vel non ipsum. Praesent facilisis orci quis elit auctor lobortis. Phasellus cursus risus lectus, vel lobortis libero dapibus in. Quisque tristique tempus leo a pulvinar. Pellentesque a magna tincidunt, pellentesque massa nec, laoreet orci. Morbi congue ornare dolor quis commodo. Phasellus massa nisi, tincidunt at eros dictum, hendrerit lobortis urna. Maecenas porta, magna id mattis molestie, nibh tellus lobortis sem, eget tincidunt ipsum quam eu turpis. - -Ut gravida orci risus, vel rutrum mauris vehicula id. Etiam bibendum, neque a placerat condimentum, ex orci imperdiet lectus, quis dapibus arcu lacus eget lectus. Sed consequat non mi sit amet venenatis. Fusce vestibulum erat libero, eget hendrerit risus vulputate sollicitudin. Integer sed eleifend felis. Donec commodo, sem eu mattis placerat, urna odio aliquam tellus, et laoreet justo tellus eget erat. Fusce sed suscipit tortor. Nam hendrerit nibh ac nunc auctor lacinia. Pellentesque placerat condimentum ipsum, eget semper tortor hendrerit vel. Nullam non urna eu lacus pellentesque congue ut id eros. - -Nunc finibus leo in rhoncus tristique. Sed eu ipsum nec nisl egestas faucibus eget a felis. Pellentesque vitae nisi in nulla accumsan fermentum. Sed venenatis feugiat eleifend. Fusce porttitor varius placerat. Aliquam aliquet lacus sit amet mattis mollis. Sed vel nulla quis dolor suscipit vehicula ac viverra lorem. Duis viverra ipsum eget nulla ullamcorper fermentum. Mauris tincidunt arcu quis quam fringilla ornare. Donec et iaculis tortor. Nam ultricies libero vel ipsum aliquet efficitur. Morbi eget dolor aliquam, tempus sapien eget, viverra ante. Donec varius mollis ex, sed efficitur purus euismod interdum. Quisque vel sapien non neque tincidunt semper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. - -Suspendisse sit amet purus leo. Fusce lectus lorem, aliquam ac nulla eget, imperdiet ornare eros. Nullam sem augue, varius in nisi non, sollicitudin pellentesque ante. Etiam eu odio condimentum, tempor libero et, egestas arcu. Cras pellentesque eleifend aliquet. Pellentesque non blandit ligula. Ut congue viverra rhoncus. Phasellus mattis mi ac eros placerat, eu feugiat tellus ultrices. Aenean mollis laoreet libero eu imperdiet. Cras sed pulvinar mi, ac vehicula ligula. Vestibulum sit amet ex massa. In a egestas eros. - -Mauris pretium ipsum risus, venenatis cursus ante imperdiet id. Praesent eu turpis nec risus feugiat maximus ullamcorper ac lectus. Integer placerat at mi vel dapibus. Vestibulum fermentum turpis sit amet turpis viverra, id aliquet diam suscipit. Nam nec ex sed ante ullamcorper pharetra quis sit amet risus. Sed ac faucibus velit, id feugiat nibh. Nullam eget ipsum ex. Vivamus tincidunt non nunc non faucibus. Quisque bibendum viverra facilisis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at nisi hendrerit quam suscipit egestas. Curabitur laoreet maximus ultricies. Duis ut tellus ac augue molestie dictum. - -Suspendisse rhoncus iaculis erat, ut ullamcorper est tristique eget. Donec auctor nec risus at gravida. Vivamus volutpat vulputate tellus, vel ultricies eros suscipit eget. Ut pulvinar id mi eu tempus. Morbi malesuada augue in dui varius, nec blandit neque vehicula. Donec ornare nec nisl in mollis. Morbi enim nisi, rhoncus nec est id, dapibus tempus urna. Ut id elit a felis vestibulum consectetur. Duis lectus quam, pharetra sit amet diam sed, posuere vestibulum erat. Fusce vitae maximus massa. Nullam id metus tempus, iaculis risus eu, lobortis urna. Quisque in congue urna. Pellentesque placerat neque in augue dapibus, non varius ex malesuada. Curabitur ut eleifend libero. Fusce vitae ligula luctus, fermentum enim vitae, ultrices erat. - -Sed viverra augue turpis, scelerisque egestas sapien mattis eu. Duis laoreet magna at ex pharetra dapibus. Praesent eget odio vel quam venenatis dictum. Nulla in sollicitudin dolor. Mauris lobortis nec eros vel rhoncus. Vestibulum porta viverra venenatis. Curabitur vel scelerisque quam, a egestas velit. Praesent volutpat tincidunt magna at laoreet. - -Cras nec lorem odio. Pellentesque quis dui urna. Praesent at tellus ac lectus scelerisque placerat nec eu risus. Vestibulum sit amet mattis ligula. Vivamus sed nisi at leo elementum accumsan at sit amet arcu. Aenean mattis tellus nec leo gravida, eget hendrerit nisl faucibus. Mauris pellentesque luctus condimentum. Maecenas pretium sapien nunc, eget commodo dolor maximus id. Mauris vestibulum accumsan massa a dictum. Phasellus interdum quam ligula, ut maximus diam blandit aliquam. Nunc vitae ex eu erat condimentum consectetur. Maecenas interdum condimentum volutpat. - -Donec et enim a libero rutrum laoreet. Praesent a condimentum sem, at tincidunt quam. In vel molestie risus. Sed urna dui, molestie vitae mollis laoreet, tempor quis lectus. Praesent vitae auctor est, et aliquet nunc. Curabitur vulputate blandit nulla, at gravida metus. Maecenas gravida dui eu iaculis tristique. Pellentesque posuere turpis nec auctor eleifend. Suspendisse bibendum diam eu tellus lobortis, et laoreet quam congue. In hac habitasse platea dictumst. Morbi dictum neque velit, eget rutrum eros ultrices sit amet. - -Phasellus fermentum risus pharetra consectetur bibendum. Donec magna tortor, lacinia vitae nibh quis, aliquet pretium lorem. Donec turpis nisi, pretium eu enim volutpat, mattis malesuada augue. Nullam vel tellus iaculis, sollicitudin elit eget, tincidunt lacus. Fusce elementum elementum felis et iaculis. Suspendisse porta eros nec neque malesuada, in malesuada ante sollicitudin. Vivamus bibendum viverra molestie. - -Integer feugiat, erat nec convallis aliquam, velit felis congue erat, molestie eleifend tellus erat in tellus. Nunc et justo purus. Donec egestas fermentum dui non feugiat. Quisque in sapien sagittis, gravida quam id, iaculis lectus. Cras sagittis rhoncus bibendum. Fusce quis metus in velit scelerisque tincidunt at non ipsum. Vivamus efficitur ante eu odio vulputate, vitae ultricies risus vehicula. Proin eget odio eu sem tincidunt feugiat vel id lorem. - -Vestibulum sit amet nulla dignissim, euismod mi in, fermentum tortor. Donec ut aliquet libero, lacinia accumsan velit. Donec et nulla quam. Nullam laoreet odio nec nunc imperdiet, a congue eros venenatis. Quisque nec tellus sit amet neque interdum posuere. Duis quis mi gravida, tincidunt diam convallis, ultricies augue. Mauris consequat risus non porttitor congue. Ut in ligula consequat, viverra nunc a, eleifend enim. Duis ligula urna, imperdiet nec facilisis et, ornare eu ex. Proin lobortis lectus a lobortis porttitor. Nulla leo metus, egestas eu libero sed, pretium faucibus felis. Vestibulum non sem tortor. Nam cursus est leo. Vivamus luctus enim odio, non interdum sem dapibus a. Aenean accumsan consequat lectus in imperdiet. - -Donec vehicula laoreet ipsum in posuere. Quisque vel quam imperdiet, sollicitudin nisi quis, suscipit velit. Morbi id sodales mauris. Curabitur tellus arcu, feugiat sed dui sit amet, sodales sagittis libero. Aenean vel suscipit metus, non placerat leo. Vestibulum quis nulla elit. Proin scelerisque non ante ut commodo. Interdum et malesuada fames ac ante ipsum primis in faucibus. - -Sed non urna dolor. Suspendisse convallis mi porta pulvinar ultrices. Suspendisse quam ipsum, hendrerit non scelerisque molestie, interdum dictum nunc. Morbi condimentum condimentum turpis eu luctus. Pellentesque sagittis sollicitudin odio, sed ultricies felis ornare sit amet. Sed ultrices ex leo, a tincidunt nisl gravida sed. Nullam ornare accumsan porta. Praesent consectetur id est nec sollicitudin. - -In hac habitasse platea dictumst. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sed ultrices nibh. Duis accumsan suscipit eros, a dictum odio tempus sit amet. Aenean imperdiet erat ac lacus finibus, scelerisque cursus massa imperdiet. Mauris molestie risus ut lacinia posuere. Nulla et sodales purus. Maecenas orci erat, placerat in tristique quis, placerat in mi. - -Donec sollicitudin pellentesque odio in feugiat. Morbi eu dolor ut mauris congue sollicitudin. Aliquam erat volutpat. Nulla id varius dui. Curabitur finibus urna ante, consectetur interdum nisi volutpat a. Quisque quis mi tristique, consequat tellus eget, rutrum sapien. Vivamus vitae tellus vulputate, rutrum ex eu, vulputate sem. Suspendisse viverra lorem tellus, vel interdum orci gravida quis. Ut laoreet arcu at mi ullamcorper finibus. Duis porta sagittis vestibulum. Sed commodo nisl vitae urna sollicitudin, nec lacinia est sodales. Curabitur imperdiet sodales dui sed iaculis. Sed ac tellus maximus, eleifend quam sit amet, feugiat elit. Aenean viverra, dui at mattis varius, est odio vestibulum sapien, sit amet mollis libero massa nec velit. Etiam quis sodales justo. - -Ut ultricies, sem eget sodales feugiat, nunc arcu congue elit, ac tempor justo massa nec purus. Maecenas enim nunc, pharetra eget dictum sit amet, tempus pellentesque velit. Suspendisse venenatis ligula in nulla mattis, et imperdiet ex tincidunt. Etiam vulputate, tellus et ultrices suscipit, enim velit laoreet massa, vitae congue odio enim ac urna. Morbi quam lorem, iaculis ac varius sagittis, euismod quis dolor. In ut dui eu purus feugiat consectetur. Vestibulum cursus velit quis lacus pellentesque iaculis. Cras in risus sed mauris porta rutrum. Nulla facilisi. Nullam eu bibendum est, non pellentesque lectus. Sed imperdiet feugiat lorem, quis convallis ante auctor in. Maecenas justo magna, scelerisque sit amet tellus eget, varius elementum risus. Duis placerat et quam sed varius. - -Duis nec nibh vitae nibh dignissim mollis quis sed felis. Curabitur vitae quam placerat, venenatis purus ut, euismod nisl. Curabitur porttitor nibh eu pulvinar ullamcorper. Suspendisse posuere nec ipsum ac dapibus. Cras convallis consectetur urna. Phasellus a nibh in dolor lacinia posuere id eget augue. In eu pharetra lorem, vitae cursus lacus. Aliquam tincidunt nibh lectus. Aenean facilisis ultricies posuere. Sed ut placerat orci. Curabitur scelerisque gravida blandit. Maecenas placerat ligula eget suscipit fringilla. Mauris a tortor justo. Aliquam hendrerit semper mollis. Phasellus et tincidunt libero. Etiam vel quam libero. - -Quisque aliquet tempor ex. Ut ante sem, vehicula at enim vel, gravida porta elit. Etiam vitae lacus a neque lobortis consectetur. Mauris sed interdum odio. Mauris elementum ex blandit tempor cursus. Integer in enim in leo viverra elementum. Fusce consectetur metus et sem rutrum, mattis euismod diam semper. Nunc sed ipsum vel urna consequat vehicula. Donec cursus pretium lorem, vestibulum pretium felis commodo sit amet. Nam blandit felis enim, eget gravida ex faucibus a. In nec neque massa. Etiam laoreet posuere ipsum. Praesent volutpat nunc dolor, ac vulputate magna facilisis non. Aenean congue turpis vel lectus sollicitudin tristique. Sed nec consequat purus, non vehicula quam. Etiam ultricies, est ac dictum tincidunt, turpis turpis pretium massa, a vulputate libero justo at nibh. - -Aliquam erat volutpat. Cras ultrices augue ac sollicitudin lobortis. Curabitur et aliquet purus. Duis feugiat semper facilisis. Phasellus lobortis cursus velit, a sollicitudin tortor. Nam feugiat sapien non dapibus condimentum. Morbi at mi bibendum, commodo quam at, laoreet enim. Integer eu ultrices enim. Sed vestibulum eu urna ut dictum. Curabitur at mattis leo, sed cursus massa. Aliquam porttitor, felis quis fermentum porttitor, justo velit feugiat nulla, eget condimentum sem dui ut sapien. - -In fringilla elit eu orci aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut eget fringilla tellus. Curabitur fermentum, mi et condimentum suscipit, elit neque bibendum dui, et hendrerit nunc metus id ipsum. Morbi placerat mi in hendrerit congue. Ut feugiat mauris eget scelerisque viverra. Vivamus sit amet erat dictum, sagittis lectus nec, pulvinar lorem. Sed non enim ac dui sollicitudin aliquet. Quisque ut lacus dolor. Fusce hendrerit malesuada euismod. Nulla faucibus vel mauris eu mollis. Mauris est diam, fringilla ac arcu feugiat, efficitur volutpat turpis. Aliquam venenatis cursus massa sed porttitor. Ut ac finibus enim, in tincidunt sapien. - -Nunc faucibus semper turpis a lacinia. Phasellus gravida, libero vel pulvinar ornare, ex sem tincidunt lectus, sit amet convallis augue risus at tortor. Quisque sit amet ipsum id nulla posuere vestibulum. Pellentesque scelerisque mauris vel leo viverra sodales. Nulla viverra aliquam ex, ut rutrum enim fermentum venenatis. Aenean eget dapibus ex, eget faucibus metus. Vestibulum volutpat leo in diam semper, eget porta magna suscipit. Sed sit amet nulla blandit, aliquam dolor ac, gravida velit. Sed vel velit viverra, maximus est id, convallis justo. - -Curabitur nulla ante, vulputate at libero vel, ullamcorper rutrum nibh. Pellentesque porttitor eu mauris id mattis. Duis vulputate augue elit, eget interdum justo pretium vel. Maecenas eu vulputate arcu, eget posuere purus. Suspendisse viverra a velit dictum eleifend. Suspendisse vitae dapibus diam. Donec vehicula justo in ante interdum, eu luctus diam placerat. Vivamus convallis ipsum eu orci suscipit, sed fermentum enim euismod. Maecenas faucibus elit vitae ex ornare tristique. Donec vestibulum nec elit sit amet porttitor. Aenean tempor lectus eget tortor hendrerit luctus. Nullam interdum vitae lectus vel feugiat. Cras in risus non magna consectetur lobortis. Sed faucibus enim quis gravida convallis. - -Phasellus eget massa sit amet libero ultrices suscipit. Vivamus at risus sapien. Nam mollis nunc eget velit dictum maximus. Sed pellentesque, nunc ac fringilla lacinia, quam enim mattis ex, sed euismod tortor metus eu neque. Ut mattis nisl ut lectus rhoncus, sodales bibendum eros porta. Nulla porttitor enim nec diam sagittis, eget porta velit efficitur. Vestibulum ultricies eros neque. Phasellus rutrum suscipit enim, in interdum ante gravida vitae. Sed in sagittis diam, non commodo velit. - -Morbi hendrerit odio orci, nec tincidunt odio rhoncus nec. Mauris neque velit, vehicula a lorem at, suscipit tristique dui. Sed finibus, nisl in mattis convallis, turpis neque sodales lacus, eu porta enim magna non diam. Nam commodo sodales risus consectetur malesuada. In eget elementum justo. Phasellus sit amet massa imperdiet, dapibus nunc sit amet, suscipit orci. Fusce condimentum laoreet feugiat. Ut ut viverra ante. Praesent bibendum interdum commodo. Nulla mollis nisi a est ornare volutpat. Sed at ligula eu nisi dapibus tempus. Proin cursus vestibulum justo, nec efficitur justo dignissim vel. Nunc quis maximus eros. - -Cras viverra, diam a tristique mattis, libero felis vulputate tellus, a ornare felis leo a dui. Nulla ante nulla, finibus ut tellus ut, blandit pharetra nibh. Proin eleifend fermentum ex, eget auctor libero vulputate in. Nullam ultricies, mauris placerat pretium placerat, leo urna lobortis leo, vel placerat arcu libero sed mauris. Aliquam mauris ligula, ornare at urna at, eleifend gravida ligula. Vestibulum consectetur ut nulla non scelerisque. Donec ornare, sem nec elementum aliquam, urna nulla bibendum metus, eu euismod dui ligula ac est. Fusce laoreet erat eu ex lobortis, quis bibendum ligula interdum. Sed vel mi erat. Vivamus id lacus ac enim mattis tempor. Nunc ultricies pellentesque enim sed euismod. Fusce tincidunt convallis elit quis aliquam. Mauris nulla ipsum, sollicitudin quis diam ac, feugiat volutpat tellus. In nibh nibh, vulputate quis tincidunt quis, pulvinar eget magna. Pellentesque quis finibus dolor. Suspendisse viverra vitae lectus non eleifend. - -Nunc ut orci et sapien maximus semper. Nulla dignissim sem urna, ac varius lectus ultricies id. Quisque aliquet pulvinar pretium. In ultricies molestie tellus vehicula porta. Nam enim lorem, aliquam eget ex et, hendrerit volutpat quam. Maecenas diam lacus, pellentesque eget tempus ac, pharetra eu elit. Donec vel eros a sem facilisis vulputate. Nullam ac nisi vulputate, laoreet nisl ac, eleifend sem. Nullam mi massa, rhoncus sed pharetra interdum, tincidunt eget nunc. Aliquam viverra mattis posuere. Mauris et dui sed nisl sollicitudin fermentum quis ut arcu. Nam placerat eget orci at tincidunt. Curabitur vel turpis metus. Phasellus nibh nulla, fermentum scelerisque sem vel, gravida tincidunt velit. Pellentesque vel quam tempor, finibus massa pellentesque, condimentum dui. - -Donec at mattis neque. Etiam velit diam, consequat auctor mauris id, hendrerit faucibus metus. Maecenas ullamcorper eros a est sodales, ac consectetur odio scelerisque. Donec leo metus, imperdiet at pellentesque vel, feugiat id erat. Suspendisse at magna enim. Vestibulum placerat sodales lorem id sollicitudin. Aenean at euismod ligula, eget mollis diam. Phasellus pulvinar, orci nec pretium condimentum, est erat facilisis purus, quis feugiat augue elit aliquam nulla. Aenean vitae tortor id risus congue tincidunt. Sed dolor enim, mattis a ullamcorper id, volutpat ac leo. - -Proin vehicula feugiat augue, id feugiat quam sodales quis. Donec et ultricies massa, a lacinia nulla. Duis aliquam augue ornare euismod viverra. Ut lectus risus, rutrum sit amet efficitur a, luctus nec nisl. Cras volutpat ullamcorper congue. Sed vitae odio metus. Phasellus aliquet euismod varius. - -Nullam sem ex, malesuada ut magna ut, pretium mollis arcu. Nam porttitor eros cursus mi lacinia faucibus. Suspendisse aliquet eleifend iaculis. Maecenas sit amet viverra tortor. Nunc a mollis risus. Etiam tempus dolor in tortor malesuada mattis. Ut tincidunt venenatis est sit amet dignissim. Vestibulum massa enim, tristique sed scelerisque eu, fringilla ac velit. Donec efficitur quis urna sit amet malesuada. Vestibulum consequat ac ligula in dapibus. Maecenas massa massa, molestie non posuere nec, elementum ut magna. In nisi erat, mollis non venenatis eu, faucibus in justo. Morbi gravida non ex non egestas. Pellentesque finibus laoreet diam, eu commodo augue congue vitae. - -Aenean sem mi, ullamcorper dapibus lobortis vitae, interdum tincidunt tortor. Vivamus eget vulputate libero. Ut bibendum posuere lectus, vel tincidunt tortor aliquet at. Phasellus malesuada orci et bibendum accumsan. Aliquam quis libero vel leo mollis porta. Sed sagittis leo ac lacus dictum, ac malesuada elit finibus. Suspendisse pharetra luctus commodo. Vivamus ultricies a odio non interdum. Vivamus scelerisque tincidunt turpis quis tempor. Pellentesque tortor ligula, varius non nunc eu, blandit sollicitudin neque. Nunc imperdiet, diam et tristique luctus, ipsum ex condimentum nunc, sit amet aliquam justo velit sed libero. Duis vel suscipit ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed tincidunt neque vel massa ultricies, id dictum leo consequat. Curabitur lobortis ultricies tellus, eget mattis nisl aliquam sit amet. - -Proin at suscipit justo. Vivamus ut vestibulum nisl. Pellentesque enim odio, pharetra non magna sed, efficitur auctor magna. Praesent tincidunt ante quis ante hendrerit viverra. Pellentesque vel ipsum id magna vulputate efficitur. Sed nec neque accumsan, pulvinar sapien quis, euismod mauris. Donec condimentum laoreet sapien quis gravida. Quisque sed mattis purus. Vestibulum placerat vel neque maximus scelerisque. - -Vestibulum mattis quam quis efficitur elementum. Duis dictum dolor ac scelerisque commodo. Fusce sollicitudin nisi sit amet dictum placerat. Suspendisse euismod pharetra eleifend. In eros nisl, porttitor sed mauris at, consectetur aliquet mauris. Donec euismod viverra neque sed fermentum. Phasellus libero magna, accumsan ut ultricies vitae, dignissim eget metus. Donec tellus turpis, interdum eget maximus nec, hendrerit eget massa. Curabitur auctor ligula in iaculis auctor. In ultrices quam suscipit cursus finibus. Aenean id mi at dolor interdum iaculis vitae ut lorem. Nullam sed nibh fringilla, lacinia odio nec, placerat erat. In dui libero, viverra ac viverra ac, pellentesque sit amet turpis. - -Nulla in enim ex. Sed feugiat est et consectetur venenatis. Cras varius facilisis dui vel convallis. Vestibulum et elit eget tellus feugiat pellentesque. In ut ante eu purus aliquet posuere. Nulla nec ornare sem, sed luctus lorem. Nam varius iaculis odio, eget faucibus nisl ullamcorper in. Sed eget cursus felis, nec efficitur nisi. - -Vivamus commodo et sem quis pulvinar. Pellentesque libero ante, venenatis vitae ligula sit amet, ornare sollicitudin nulla. Mauris eget tellus hendrerit, pulvinar metus quis, tempor nisi. Proin magna ex, laoreet sed tortor quis, varius fermentum enim. Integer eu dolor dictum, vulputate tortor et, aliquet ligula. Vestibulum vitae justo id mauris luctus sollicitudin. Suspendisse eget auctor neque, sodales egestas lorem. Vestibulum lacinia egestas metus vitae euismod. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus ex tellus, volutpat nec pulvinar sit amet, condimentum vitae dui. Curabitur vel felis sodales, lacinia nunc iaculis, ullamcorper augue. Pellentesque consequat dolor quis eros efficitur malesuada. Nulla ut malesuada lectus. - -Morbi et tristique ante. Aliquam erat volutpat. Vivamus vitae dui nec turpis pellentesque fermentum. Quisque eget velit massa. Pellentesque tristique aliquam nisl, eu sollicitudin justo venenatis sed. Duis eleifend sem eros, ut aliquam libero porttitor id. Sed non nunc consequat, rhoncus diam eu, commodo erat. Praesent fermentum in lectus id blandit. Donec quis ipsum at justo volutpat finibus. Nulla blandit justo nulla, at mollis lacus consequat eget. Aenean sollicitudin quis eros ut ullamcorper. - -Pellentesque venenatis nulla ut mi aliquet feugiat. Cras semper vel magna nec pharetra. Integer mattis felis et sapien commodo imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis quis luctus felis. Vestibulum justo nibh, aliquam non lectus vitae, molestie placerat justo. Donec lorem nibh, gravida sit amet hendrerit ac, maximus id ipsum. Nunc ac libero sodales risus eleifend sagittis. Phasellus est massa, lobortis elementum ex sed, scelerisque consectetur neque. Nunc faucibus neque id lorem malesuada, eget convallis ex mattis. - -Sed turpis tortor, fermentum non turpis id, posuere varius nibh. Donec iaculis lorem dui. Etiam eros ante, sodales eget venenatis at, consectetur eget risus. Curabitur non aliquam ante, a pretium justo. Maecenas tempor nisl tortor, vitae dictum nisi ultrices eu. Duis eget dui ultrices, porttitor lacus sed, lobortis purus. Quisque mattis elit nec neque sagittis, sed commodo leo blandit. Mauris sodales interdum eleifend. Vestibulum condimentum consectetur augue, id luctus diam convallis et. - -Nunc suscipit risus in justo accumsan, a placerat magna tincidunt. Proin a nisl ipsum. Sed libero dui, tristique in augue quis, auctor tristique risus. Sed porttitor ex augue, eu porta augue molestie a. Duis rhoncus purus libero, eu tempus turpis condimentum at. Sed mollis nisi id lectus placerat tincidunt. Maecenas non scelerisque elit, quis rutrum orci. Donec in tellus pharetra urna ornare lobortis. Phasellus id risus at nisi varius rutrum eu ut turpis. - -Duis dictum justo quis nisl porta, eget tincidunt magna suscipit. Sed velit massa, ullamcorper eu sodales ac, pretium a massa. Duis et rutrum tortor. Nulla accumsan hendrerit sapien, cursus volutpat eros egestas eget. Donec sollicitudin at ante quis sollicitudin. Aenean blandit feugiat diam, id feugiat eros faucibus eget. Donec viverra dolor vel justo scelerisque dignissim. Nulla semper sem nunc, rhoncus semper tellus ultricies sed. Duis in ornare diam. Donec vehicula feugiat varius. Maecenas ut suscipit est. Vivamus sem sem, finibus at dolor sit amet, euismod dapibus ligula. Vestibulum fringilla odio dapibus, congue massa eget, congue sem. Donec feugiat magna eget tortor lacinia scelerisque non et ipsum. - -Suspendisse potenti. Nunc convallis sollicitudin ex eget venenatis. Sed iaculis nibh ex, vel ornare ligula congue dignissim. Quisque sollicitudin dolor ac dui vestibulum, sit amet molestie nisi aliquet. Donec at risus felis. Aenean sollicitudin metus a feugiat porta. Aenean a tortor ut dolor cursus sagittis. Vivamus consectetur porttitor nunc in facilisis. Proin sit amet mi vel lectus consectetur ultrices. - -Sed cursus lectus vitae nunc tristique, nec commodo turpis dapibus. Pellentesque luctus ex id facilisis ornare. Morbi quis placerat dolor. Donec in lectus in arcu mattis porttitor ac sit amet metus. Cras congue mauris non risus sodales, vitae feugiat ipsum bibendum. Nulla venenatis urna sed libero elementum, a cursus lorem commodo. Mauris faucibus lobortis eros nec commodo. - -Nullam suscipit ligula ullamcorper lorem commodo blandit. Nulla porta nibh quis pulvinar placerat. Vivamus eu arcu justo. Vestibulum imperdiet est ut fermentum porttitor. Pellentesque consectetur libero in sapien efficitur scelerisque. Curabitur ac erat sit amet odio aliquet dignissim. Pellentesque mi sem, rhoncus et luctus at, porttitor rutrum lectus. Vestibulum sollicitudin sollicitudin suscipit. Aenean efficitur dolor non ultrices imperdiet. Donec vel sem ex. - -Sed convallis mauris aliquam rutrum cursus. Ut tempor porttitor sodales. Etiam eu risus ac augue gravida egestas et eu dolor. Proin id magna ex. Suspendisse quis lectus quis lorem ultricies tempus. Donec porttitor velit vitae tincidunt faucibus. Aliquam vitae semper nisi. Morbi ultrices, leo non pretium dapibus, dui libero pellentesque ex, vel placerat enim ante vitae dui. Nunc varius, sem sit amet sagittis lobortis, lectus odio scelerisque mauris, ut vestibulum orci magna quis neque. Sed id congue justo. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris congue nisi est, malesuada mollis elit tincidunt sed. Curabitur sed ex sit amet felis tristique elementum vitae vel nibh. - -Etiam mollis pretium lobortis. Mauris augue lacus, efficitur at lacus sed, mollis tincidunt lectus. Aliquam erat volutpat. Donec at euismod elit, et mattis felis. Sed id lobortis urna. Morbi imperdiet vestibulum leo, sed maximus leo blandit eu. Aliquam semper lorem neque, nec euismod turpis mattis mollis. Quisque lobortis urna ultrices odio pretium, ac venenatis orci faucibus. Suspendisse bibendum odio ligula, sed lobortis massa pharetra nec. Donec turpis justo, iaculis at dictum ac, finibus eu libero. Maecenas quis porttitor mi, sit amet aliquet neque. - -Vivamus auctor vulputate ante, at egestas lorem. Donec eu risus in nulla mollis ultricies at et urna. Duis accumsan porta egestas. Ut vel euismod augue. Fusce convallis nulla ante, nec fringilla velit aliquet at. Nam malesuada dapibus ligula, a aliquam nibh scelerisque ac. Praesent malesuada neque et pellentesque interdum. Curabitur volutpat at turpis vitae tristique. Vivamus porttitor semper congue. Quisque suscipit lacus mi, rhoncus ultrices tortor auctor quis. Maecenas neque neque, molestie ac facilisis eget, luctus ac lorem. In ut odio ut lacus suscipit pulvinar vitae sed elit. Nulla imperdiet, sem quis euismod sagittis, dui erat luctus dolor, faucibus faucibus erat sem eget nunc. Nam accumsan placerat malesuada. Maecenas convallis finibus pulvinar. - -Cras at placerat tortor. Morbi facilisis auctor felis sit amet molestie. Donec sodales sed lorem vitae suscipit. Etiam fermentum pharetra ipsum, nec luctus orci gravida eu. Pellentesque gravida, est non condimentum tempus, mauris ligula molestie est, in congue dolor nisl vel sapien. Duis congue tempor augue, id rutrum eros porta dapibus. Etiam rutrum eget est eget vestibulum. Aenean mollis arcu vel consequat varius. Praesent at condimentum felis. Duis nec interdum nisl. Donec commodo lorem sed sapien scelerisque malesuada non eu urna. In blandit non ipsum at porta. Nam lobortis leo vitae dui auctor, non feugiat quam bibendum. Donec auctor lectus sagittis laoreet maximus. Maecenas rhoncus laoreet porttitor. Vestibulum porttitor augue ut lectus hendrerit, eget posuere mi gravida. - -Sed mattis ex in erat pulvinar, eu imperdiet magna dapibus. Etiam nisi nibh, tempus non tellus sit amet, mattis tempor odio. Quisque nec lorem feugiat, lobortis odio et, commodo nunc. Maecenas semper purus nisi, nec vehicula nibh eleifend vitae. Nulla fermentum a lectus at maximus. Phasellus finibus metus non euismod ultrices. Etiam a pulvinar ante. Quisque convallis nec metus sit amet facilisis. Praesent laoreet massa et sollicitudin laoreet. Vestibulum in mauris aliquet, convallis mi ut, elementum purus. Nulla purus nulla, sodales at hendrerit quis, tempus sed lectus. - -Nam ut laoreet neque, ut maximus nibh. Maecenas quis justo pellentesque, sollicitudin elit at, venenatis velit. Aenean nunc velit, vehicula scelerisque odio at, consectetur laoreet purus. Duis dui purus, malesuada quis ipsum sit amet, tempor interdum libero. Curabitur porta scelerisque sapien, vitae cursus diam condimentum eu. Phasellus sed orci quam. Nullam vitae dui quis purus tincidunt vestibulum. Curabitur quis nulla porta, cursus arcu non, auctor enim. Etiam sollicitudin ex id sem vehicula mollis. Morbi viverra laoreet tincidunt. Praesent ut semper dui. Nam sit amet pretium neque. Mauris vitae luctus diam, in lacinia purus. Maecenas ut placerat justo, ut porta felis. Integer eu mauris ante. - -Aenean porttitor tellus diam, tempor consequat metus efficitur id. Suspendisse ut felis at erat tempor dictum at nec sapien. Sed vestibulum interdum felis, ac mattis mauris porta in. Nunc et condimentum massa. Sed cursus dictum justo et luctus. Integer convallis enim nisl, a rutrum lectus ultricies in. Donec dapibus lacus at nulla dapibus, id sollicitudin velit hendrerit. Fusce a magna at orci mollis rutrum ac a dolor. Aliquam erat volutpat. Morbi varius porta nunc, sit amet sodales ex hendrerit commodo. Donec tincidunt tortor sapien, vitae egestas sapien vehicula eget. - -Suspendisse potenti. Donec pulvinar felis nec leo malesuada interdum. Integer posuere placerat maximus. Donec nibh ipsum, tincidunt vitae luctus vitae, bibendum at leo. Sed cursus nisl ut ex faucibus aliquet sed nec eros. Curabitur molestie posuere felis. Integer faucibus velit eget consequat iaculis. Mauris sed vulputate odio. Phasellus maximus, elit a pharetra egestas, lorem magna semper tellus, vestibulum semper diam felis at sapien. Suspendisse facilisis, nisl sit amet euismod vehicula, libero nulla vehicula dolor, quis fermentum nibh elit sit amet diam. - -Morbi lorem enim, euismod eu varius ut, scelerisque quis odio. Nam tempus vitae eros id molestie. Nunc pretium in nulla eget accumsan. Quisque mattis est ut semper aliquet. Maecenas eget diam elementum, fermentum ipsum a, euismod sapien. Duis quam ligula, cursus et velit nec, ullamcorper tincidunt magna. Donec vulputate nisl est, et ullamcorper urna tempor sit amet. - -Proin lacinia dui non turpis congue pretium. Morbi posuere metus vel purus imperdiet interdum. Morbi venenatis vel eros non ultricies. Nulla vel semper elit. Ut quis purus tincidunt, auctor justo ut, faucibus turpis. Proin quis mattis erat, at faucibus ligula. Mauris in mauris enim. Donec facilisis enim at est feugiat hendrerit. Nam vel nisi lorem. Fusce ultricies convallis diam, in feugiat tortor luctus quis. Donec tempor, leo vitae volutpat aliquam, magna elit feugiat leo, quis placerat sapien felis eget arcu. Donec ornare fermentum eleifend. Integer a est orci. - -Proin rhoncus egestas leo. Nulla ultricies porta elit quis ornare. Nunc fermentum interdum vehicula. In in ligula lorem. Donec nec arcu sit amet orci lobortis iaculis. Mauris at mollis erat, sit amet mollis tortor. Mauris laoreet justo ullamcorper porttitor auctor. Aenean sit amet aliquam lectus, id fermentum eros. Praesent urna sem, vehicula ac fermentum id, dapibus ut purus. Vestibulum vitae tempus nunc. Donec at nunc ornare metus volutpat porta at eget magna. Donec varius aliquet metus, eu lobortis risus aliquam sed. Ut dapibus fermentum velit, ac tincidunt libero faucibus at. - -In in purus auctor, feugiat massa quis, facilisis nisi. Donec dolor purus, gravida eget dolor ac, porttitor imperdiet urna. Donec faucibus placerat erat, a sagittis ante finibus ac. Sed venenatis dignissim elit, in iaculis felis posuere faucibus. Praesent sed viverra dolor. Mauris sed nulla consectetur nunc laoreet molestie in ut metus. Proin ac ex sit amet magna vulputate hendrerit ac condimentum urna. Proin ligula metus, gravida et sollicitudin facilisis, iaculis ut odio. Cras tincidunt urna et augue varius, ut facilisis urna consequat. Aenean vehicula finibus quam. Ut iaculis eu diam ac mollis. Nam mi lorem, tristique eget varius at, sodales at urna. - -Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin vitae dictum erat, et auctor ipsum. Nullam nunc nunc, sollicitudin quis magna a, vestibulum fermentum mauris. Praesent at erat dolor. Proin laoreet tristique nulla vel efficitur. Nam sed ultrices nibh, id rutrum nunc. Curabitur eleifend a erat sit amet sollicitudin. Nullam metus quam, laoreet vitae dapibus id, placerat sed leo. Aliquam erat volutpat. Donec turpis nisl, cursus eu ex sit amet, lacinia pellentesque nisl. Sed id ipsum massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec interdum scelerisque lorem eu mattis. - -Vivamus ac tristique massa, nec facilisis nisl. Nam ipsum neque, tincidunt vel urna in, cursus imperdiet enim. Nam pellentesque egestas tempus. Morbi facilisis imperdiet libero vitae fringilla. Nam lacinia ligula at sapien facilisis malesuada. Nullam accumsan pulvinar sem, et cursus libero porta sit amet. Curabitur vulputate erat elit, ut pulvinar erat maximus vel. - -Cras aliquet metus ut purus sagittis, vel venenatis ante consectetur. Pellentesque nulla lacus, viverra viverra mattis non, placerat vitae nibh. Donec enim turpis, accumsan sit amet tincidunt eu, imperdiet non metus. Morbi ipsum eros, tincidunt vel est ac, tristique porttitor nibh. Praesent ut ullamcorper mauris. Sed laoreet sit amet diam congue venenatis. Integer porta purus nec orci sagittis posuere. - -Donec vehicula mauris eget lacus mollis venenatis et sed nibh. Nam sodales ligula ipsum, scelerisque lacinia ligula sagittis in. Nam sit amet ipsum at erat malesuada congue. Aenean ut sollicitudin sapien. Etiam at tempor odio. Mauris vitae purus ut magna suscipit consequat. Vivamus quis sapien neque. Nulla vulputate sem sit amet massa pellentesque, eleifend tristique ligula egestas. Suspendisse tincidunt gravida mi, in pulvinar lectus egestas non. Aenean imperdiet ex sit amet nunc sollicitudin porta. Integer justo odio, ultricies at interdum in, rhoncus vitae sem. Sed porttitor arcu quis purus aliquet hendrerit. Praesent tempor tortor at dolor dictum pulvinar. Nulla aliquet nunc non ligula scelerisque accumsan. Donec nulla justo, congue vitae massa in, faucibus hendrerit magna. Donec non egestas purus. - -öäüß Vivamus iaculis, lacus efficitur faucibus porta, dui nulla facilisis ligula, ut sodales odio nunc id sapien. Cras viverra auctor ipsum, dapibus mattis neque dictum sed. Sed convallis fermentum molestie. Nulla facilisi turpis duis. \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/small.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/small.txt deleted file mode 100644 index da2e8042fb4..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/small.txt +++ /dev/null @@ -1 +0,0 @@ -Small File \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/small_umlaut.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/small_umlaut.txt deleted file mode 100644 index a01c1626b30..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/small_umlaut.txt +++ /dev/null @@ -1 +0,0 @@ -Small File with Ümlaut \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some.utf16le b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some.utf16le deleted file mode 100644 index 41c12add670..00000000000 Binary files a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some.utf16le and /dev/null differ diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_big5.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_big5.txt deleted file mode 100644 index b9e2570fef9..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_big5.txt +++ /dev/null @@ -1 +0,0 @@ -¤¤¤åabc \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_cp1252.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_cp1252.txt deleted file mode 100644 index 2ea52dc709f..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_cp1252.txt +++ /dev/null @@ -1,3 +0,0 @@ -ObjectCount = LoadObjects("Öffentlicher Ordner"); - -Private = "Persönliche Information" diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_cyrillic.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_cyrillic.txt deleted file mode 100644 index f8ee3066712..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_cyrillic.txt +++ /dev/null @@ -1 +0,0 @@ -€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯àáâãäåæçèéêëìíîï \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_gbk.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_gbk.txt deleted file mode 100644 index eab73d1951b..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_gbk.txt +++ /dev/null @@ -1 +0,0 @@ -Öйúabc \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_shiftjis.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_shiftjis.txt deleted file mode 100644 index efa955b3ecb..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_shiftjis.txt +++ /dev/null @@ -1 +0,0 @@ -’†•¶abc \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_small_cp1252.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_small_cp1252.txt deleted file mode 100644 index 0ad555462f2..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_small_cp1252.txt +++ /dev/null @@ -1 +0,0 @@ -Private = "Persönlicheß Information" \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_utf16le.css b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_utf16le.css deleted file mode 100644 index aea04aa2cd1..00000000000 Binary files a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_utf16le.css and /dev/null differ diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_utf8_bom.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_utf8_bom.txt deleted file mode 100644 index 36cdec0c88f..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/some_utf8_bom.txt +++ /dev/null @@ -1 +0,0 @@ -This is some UTF 8 with BOM file. \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/utf16_be_nobom.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/utf16_be_nobom.txt deleted file mode 100644 index 63c29412093..00000000000 Binary files a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/utf16_be_nobom.txt and /dev/null differ diff --git a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/utf16_le_nobom.txt b/src/vs/workbench/services/textfile/test/electron-browser/fixtures/utf16_le_nobom.txt deleted file mode 100644 index 7b94ff215b0..00000000000 Binary files a/src/vs/workbench/services/textfile/test/electron-browser/fixtures/utf16_le_nobom.txt and /dev/null differ diff --git a/src/vs/workbench/services/textfile/test/electron-browser/nativeTextFileService.io.test.ts b/src/vs/workbench/services/textfile/test/electron-browser/nativeTextFileService.io.test.ts deleted file mode 100644 index 3592688acb8..00000000000 --- a/src/vs/workbench/services/textfile/test/electron-browser/nativeTextFileService.io.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { tmpdir } from 'os'; -import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { IFileService } from 'vs/platform/files/common/files'; -import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager'; -import { FileAccess, Schemas } from 'vs/base/common/network'; -import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { Promises } from 'vs/base/node/pfs'; -import { DisposableStore } from 'vs/base/common/lifecycle'; -import { FileService } from 'vs/platform/files/common/fileService'; -import { NullLogService } from 'vs/platform/log/common/log'; -import { flakySuite, getRandomTestPath } from 'vs/base/test/node/testUtils'; -import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; -import { detectEncodingByBOM } from 'vs/workbench/services/textfile/test/node/encoding/encoding.test'; -import { workbenchInstantiationService, TestNativeTextFileServiceWithEncodingOverrides } from 'vs/workbench/test/electron-browser/workbenchTestServices'; -import createSuite from 'vs/workbench/services/textfile/test/common/textFileService.io.test'; -import { IWorkingCopyFileService, WorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; -import { WorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; -import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; - -flakySuite('Files - NativeTextFileService i/o', function () { - const disposables = new DisposableStore(); - - let service: ITextFileService; - let testDir: string; - - function readFile(path: string): Promise; - function readFile(path: string, encoding: BufferEncoding): Promise; - function readFile(path: string, encoding?: BufferEncoding): Promise { - return Promises.readFile(path, encoding); - } - - createSuite({ - setup: async () => { - const instantiationService = workbenchInstantiationService(disposables); - - const logService = new NullLogService(); - const fileService = new FileService(logService); - - const fileProvider = new DiskFileSystemProvider(logService); - disposables.add(fileService.registerProvider(Schemas.file, fileProvider)); - disposables.add(fileProvider); - - const collection = new ServiceCollection(); - collection.set(IFileService, fileService); - - collection.set(IWorkingCopyFileService, new WorkingCopyFileService(fileService, new WorkingCopyService(), instantiationService, new UriIdentityService(fileService))); - - service = instantiationService.createChild(collection).createInstance(TestNativeTextFileServiceWithEncodingOverrides); - - testDir = getRandomTestPath(tmpdir(), 'vsctests', 'textfileservice'); - const sourceDir = FileAccess.asFileUri('vs/workbench/services/textfile/test/electron-browser/fixtures').fsPath; - - await Promises.copy(sourceDir, testDir, { preserveSymlinks: false }); - - return { service, testDir }; - }, - - teardown: () => { - (service.files).dispose(); - - disposables.clear(); - - return Promises.rm(testDir); - }, - - exists: Promises.exists, - stat: Promises.stat, - readFile, - detectEncodingByBOM - }); -}); diff --git a/src/vs/workbench/services/textfile/test/electron-sandbox/nativeTextFileService.io.test.ts b/src/vs/workbench/services/textfile/test/electron-sandbox/nativeTextFileService.io.test.ts new file mode 100644 index 00000000000..b1d9d93829f --- /dev/null +++ b/src/vs/workbench/services/textfile/test/electron-sandbox/nativeTextFileService.io.test.ts @@ -0,0 +1,110 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { NullLogService } from 'vs/platform/log/common/log'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { Schemas } from 'vs/base/common/network'; +import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import { IFileService, IStat } from 'vs/platform/files/common/files'; +import { URI } from 'vs/base/common/uri'; +import { join } from 'vs/base/common/path'; +import { UTF16le, detectEncodingByBOMFromBuffer, UTF8_with_bom, UTF16be, toCanonicalName } from 'vs/workbench/services/textfile/common/encoding'; +import { VSBuffer } from 'vs/base/common/buffer'; +import files from 'vs/workbench/services/textfile/test/common/fixtures/files'; +import createSuite from 'vs/workbench/services/textfile/test/common/textFileService.io.test'; +import { IWorkingCopyFileService, WorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; +import { WorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; +import { TestInMemoryFileSystemProvider } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestNativeTextFileServiceWithEncodingOverrides, workbenchInstantiationService } from 'vs/workbench/test/electron-sandbox/workbenchTestServices'; + +suite('Files - NativeTextFileService i/o', function () { + const disposables = new DisposableStore(); + + let service: ITextFileService; + let fileProvider: TestInMemoryFileSystemProvider; + const testDir = 'test'; + + createSuite({ + setup: async () => { + const instantiationService = workbenchInstantiationService(undefined, disposables); + + const logService = new NullLogService(); + const fileService = new FileService(logService); + + fileProvider = new TestInMemoryFileSystemProvider(); + disposables.add(fileService.registerProvider(Schemas.file, fileProvider)); + disposables.add(fileProvider); + + const collection = new ServiceCollection(); + collection.set(IFileService, fileService); + + collection.set(IWorkingCopyFileService, new WorkingCopyFileService(fileService, new WorkingCopyService(), instantiationService, new UriIdentityService(fileService))); + + service = instantiationService.createChild(collection).createInstance(TestNativeTextFileServiceWithEncodingOverrides); + + await fileProvider.mkdir(URI.file(testDir)); + for (const fileName in files) { + await fileProvider.writeFile( + URI.file(join(testDir, fileName)), + files[fileName], + { create: true, overwrite: false, unlock: false } + ); + } + + return { service, testDir }; + }, + + teardown: async () => { + (service.files).dispose(); + + disposables.clear(); + }, + + exists, + stat, + readFile, + detectEncodingByBOM + }); + + async function exists(fsPath: string): Promise { + try { + await fileProvider.readFile(URI.file(fsPath)); + return true; + } + catch (e) { + return false; + } + } + + async function readFile(fsPath: string): Promise; + async function readFile(fsPath: string, encoding: string): Promise; + async function readFile(fsPath: string, encoding?: string): Promise { + const file = await fileProvider.readFile(URI.file(fsPath)); + + if (!encoding) { + return VSBuffer.wrap(file); + } + + return new TextDecoder(toCanonicalName(encoding)).decode(file); + } + + async function stat(fsPath: string): Promise { + return fileProvider.stat(URI.file(fsPath)); + } + + async function detectEncodingByBOM(fsPath: string): Promise { + try { + const buffer = await readFile(fsPath); + + return detectEncodingByBOMFromBuffer(buffer.slice(0, 3), 3); + } catch (error) { + return null; // ignore errors (like file not found) + } + } +}); diff --git a/src/vs/workbench/services/textfile/test/electron-browser/nativeTextFileService.test.ts b/src/vs/workbench/services/textfile/test/electron-sandbox/nativeTextFileService.test.ts similarity index 92% rename from src/vs/workbench/services/textfile/test/electron-browser/nativeTextFileService.test.ts rename to src/vs/workbench/services/textfile/test/electron-sandbox/nativeTextFileService.test.ts index 58fab632f9f..1ac327fd20c 100644 --- a/src/vs/workbench/services/textfile/test/electron-browser/nativeTextFileService.test.ts +++ b/src/vs/workbench/services/textfile/test/electron-sandbox/nativeTextFileService.test.ts @@ -12,7 +12,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { DisposableStore } from 'vs/base/common/lifecycle'; import { FileService } from 'vs/platform/files/common/fileService'; import { NullLogService } from 'vs/platform/log/common/log'; -import { workbenchInstantiationService, TestNativeTextFileServiceWithEncodingOverrides, TestServiceAccessor } from 'vs/workbench/test/electron-browser/workbenchTestServices'; +import { TestNativeTextFileServiceWithEncodingOverrides, TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/electron-sandbox/workbenchTestServices'; import { IWorkingCopyFileService, WorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import { WorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; @@ -28,7 +28,7 @@ suite('Files - NativeTextFileService', function () { let instantiationService: IInstantiationService; setup(() => { - instantiationService = workbenchInstantiationService(disposables); + instantiationService = workbenchInstantiationService(undefined, disposables); const logService = new NullLogService(); const fileService = new FileService(logService); diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index 07950da24cc..41b75f7daf4 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -37,6 +37,7 @@ import { isWeb } from 'vs/base/common/platform'; import { ColorScheme } from 'vs/platform/theme/common/theme'; import { IHostColorSchemeService } from 'vs/workbench/services/themes/common/hostColorSchemeService'; import { RunOnceScheduler, Sequencer } from 'vs/base/common/async'; +import { IUserDataInitializationService } from 'vs/workbench/services/userData/browser/userDataInit'; import { getIconsStyleSheet } from 'vs/platform/theme/browser/iconsStyleSheet'; import { asCssVariableName, getColorRegistry } from 'vs/platform/theme/common/colorRegistry'; import { ILanguageService } from 'vs/editor/common/languages/language'; @@ -114,6 +115,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, @ILogService private readonly logService: ILogService, @IHostColorSchemeService private readonly hostColorService: IHostColorSchemeService, + @IUserDataInitializationService userDataInitializationService: IUserDataInitializationService, @ILanguageService languageService: ILanguageService ) { this.container = layoutService.container; @@ -175,7 +177,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { this.applyAndSetProductIconTheme(productIconData, true); } - Promise.all([extensionService.whenInstalledExtensionsRegistered()]).then(_ => { + Promise.all([extensionService.whenInstalledExtensionsRegistered(), userDataInitializationService.whenInitializationFinished()]).then(_ => { this.installConfigurationListener(); this.installPreferredSchemeListener(); this.installRegistryListeners(); diff --git a/src/vs/workbench/services/themes/electron-sandbox/nativeHostColorSchemeService.ts b/src/vs/workbench/services/themes/electron-sandbox/nativeHostColorSchemeService.ts index 10769a87465..aff2bd1cfa1 100644 --- a/src/vs/workbench/services/themes/electron-sandbox/nativeHostColorSchemeService.ts +++ b/src/vs/workbench/services/themes/electron-sandbox/nativeHostColorSchemeService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Emitter } from 'vs/base/common/event'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { Disposable } from 'vs/base/common/lifecycle'; import { IHostColorSchemeService } from 'vs/workbench/services/themes/common/hostColorSchemeService'; diff --git a/src/vs/workbench/services/timer/electron-sandbox/timerService.ts b/src/vs/workbench/services/timer/electron-sandbox/timerService.ts index 4048bbf17e3..f30a92552e3 100644 --- a/src/vs/workbench/services/timer/electron-sandbox/timerService.ts +++ b/src/vs/workbench/services/timer/electron-sandbox/timerService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; diff --git a/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.integrationTest.ts b/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.integrationTest.ts new file mode 100644 index 00000000000..828a72f1d0d --- /dev/null +++ b/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.integrationTest.ts @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; +import { workbenchInstantiationService, TestServiceAccessor } from 'vs/workbench/test/browser/workbenchTestServices'; +import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { DisposableStore } from 'vs/base/common/lifecycle'; + +suite('Untitled text editors', () => { + + let disposables: DisposableStore; + let instantiationService: IInstantiationService; + let accessor: TestServiceAccessor; + + setup(() => { + disposables = new DisposableStore(); + instantiationService = workbenchInstantiationService(undefined, disposables); + accessor = instantiationService.createInstance(TestServiceAccessor); + }); + + teardown(() => { + (accessor.untitledTextEditorService as UntitledTextEditorService).dispose(); + disposables.dispose(); + }); + + test('backup and restore (simple)', async function () { + return testBackupAndRestore('Some very small file text content.'); + }); + + test('backup and restore (large, #121347)', async function () { + const largeContent = '국어한\n'.repeat(100000); + return testBackupAndRestore(largeContent); + }); + + async function testBackupAndRestore(content: string) { + const service = accessor.untitledTextEditorService; + const originalInput = instantiationService.createInstance(UntitledTextEditorInput, service.create()); + const restoredInput = instantiationService.createInstance(UntitledTextEditorInput, service.create()); + + const originalModel = await originalInput.resolve(); + originalModel.textEditorModel?.setValue(content); + + const backup = await originalModel.backup(CancellationToken.None); + const modelRestoredIdentifier = { typeId: originalModel.typeId, resource: restoredInput.resource }; + await accessor.workingCopyBackupService.backup(modelRestoredIdentifier, backup.content); + + const restoredModel = await restoredInput.resolve(); + + assert.strictEqual(restoredModel.textEditorModel?.getValue(), content); + assert.strictEqual(restoredModel.isDirty(), true); + + originalInput.dispose(); + originalModel.dispose(); + restoredInput.dispose(); + restoredModel.dispose(); + } +}); 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 9aacd0a6493..22cf7a0a177 100644 --- a/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.test.ts +++ b/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.test.ts @@ -351,7 +351,7 @@ suite('Untitled text editors', () => { await input.resolve(); assert.ok(!input.model.hasLanguageSetExplicitly); - accessor.modelService.setMode(model.textEditorModel!, accessor.languageService.createById(language)); + model.textEditorModel!.setLanguage(accessor.languageService.createById(language)); assert.ok(input.model.hasLanguageSetExplicitly); assert.strictEqual(model.getLanguageId(), language); @@ -373,8 +373,7 @@ suite('Untitled text editors', () => { await input.resolve(); assert.ok(!input.model.hasLanguageSetExplicitly); - accessor.modelService.setMode( - model.textEditorModel!, + model.textEditorModel!.setLanguage( accessor.languageService.createById(language), // This is really what this is testing LanguageDetectionLanguageEventSource); @@ -615,36 +614,4 @@ suite('Untitled text editors', () => { input.dispose(); model.dispose(); }); - - test('backup and restore (simple)', async function () { - return testBackupAndRestore('Some very small file text content.'); - }); - - test('backup and restore (large, #121347)', async function () { - const largeContent = '국어한\n'.repeat(100000); - return testBackupAndRestore(largeContent); - }); - - async function testBackupAndRestore(content: string) { - const service = accessor.untitledTextEditorService; - const originalInput = instantiationService.createInstance(UntitledTextEditorInput, service.create()); - const restoredInput = instantiationService.createInstance(UntitledTextEditorInput, service.create()); - - const originalModel = await originalInput.resolve(); - originalModel.textEditorModel?.setValue(content); - - const backup = await originalModel.backup(CancellationToken.None); - const modelRestoredIdentifier = { typeId: originalModel.typeId, resource: restoredInput.resource }; - await accessor.workingCopyBackupService.backup(modelRestoredIdentifier, backup.content); - - const restoredModel = await restoredInput.resolve(); - - assert.strictEqual(restoredModel.textEditorModel?.getValue(), content); - assert.strictEqual(restoredModel.isDirty(), true); - - originalInput.dispose(); - originalModel.dispose(); - restoredInput.dispose(); - restoredModel.dispose(); - } }); diff --git a/src/vs/workbench/services/url/electron-sandbox/urlService.ts b/src/vs/workbench/services/url/electron-sandbox/urlService.ts index 840562f12b7..3b3000abce6 100644 --- a/src/vs/workbench/services/url/electron-sandbox/urlService.ts +++ b/src/vs/workbench/services/url/electron-sandbox/urlService.ts @@ -5,13 +5,13 @@ import { IURLService, IURLHandler, IOpenURLOptions } from 'vs/platform/url/common/url'; import { URI, UriComponents } from 'vs/base/common/uri'; -import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; +import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService'; import { URLHandlerChannel } from 'vs/platform/url/common/urlIpc'; import { IOpenerService, IOpener, matchesScheme } from 'vs/platform/opener/common/opener'; import { IProductService } from 'vs/platform/product/common/productService'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { NativeURLService } from 'vs/platform/url/common/urlService'; import { ILogService } from 'vs/platform/log/common/log'; diff --git a/src/vs/workbench/services/userData/browser/userDataInit.ts b/src/vs/workbench/services/userData/browser/userDataInit.ts new file mode 100644 index 00000000000..308deacf6a3 --- /dev/null +++ b/src/vs/workbench/services/userData/browser/userDataInit.ts @@ -0,0 +1,455 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { AbstractExtensionsInitializer, IExtensionsInitializerPreviewResult } from 'vs/platform/userDataSync/common/extensionsSync'; +import { GlobalStateInitializer, UserDataSyncStoreTypeSynchronizer } from 'vs/platform/userDataSync/common/globalStateSync'; +import { KeybindingsInitializer } from 'vs/platform/userDataSync/common/keybindingsSync'; +import { SettingsInitializer } from 'vs/platform/userDataSync/common/settingsSync'; +import { SnippetsInitializer } from 'vs/platform/userDataSync/common/snippetsSync'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { IFileService } from 'vs/platform/files/common/files'; +import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ILogService } from 'vs/platform/log/common/log'; +import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { IRequestService } from 'vs/platform/request/common/request'; +import { IRemoteUserData, IUserData, IUserDataInitializer, IUserDataSyncLogService, IUserDataSyncStoreManagementService, SyncResource } from 'vs/platform/userDataSync/common/userDataSync'; +import { AuthenticationSessionInfo, getCurrentAuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService'; +import { getSyncAreaLabel } from 'vs/workbench/services/userDataSync/common/userDataSync'; +import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions } from 'vs/workbench/common/contributions'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; +import { isWeb } from 'vs/base/common/platform'; +import { Barrier, Promises } from 'vs/base/common/async'; +import { IExtensionGalleryService, IExtensionManagementService, IGlobalExtensionEnablementService, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IExtensionService, toExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; +import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; +import { mark } from 'vs/base/common/performance'; +import { IIgnoredExtensionsManagementService } from 'vs/platform/userDataSync/common/ignoredExtensions'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { isEqual } from 'vs/base/common/resources'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage'; +import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; +import { TasksInitializer } from 'vs/platform/userDataSync/common/tasksSync'; +import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; + +export const IUserDataInitializationService = createDecorator('IUserDataInitializationService'); +export interface IUserDataInitializationService { + _serviceBrand: any; + + requiresInitialization(): Promise; + whenInitializationFinished(): Promise; + initializeRequiredResources(): Promise; + initializeInstalledExtensions(instantiationService: IInstantiationService): Promise; + initializeOtherResources(instantiationService: IInstantiationService): Promise; +} + +export class UserDataInitializationService implements IUserDataInitializationService { + + _serviceBrand: any; + + private readonly initialized: SyncResource[] = []; + private readonly initializationFinished = new Barrier(); + private globalStateUserData: IUserData | null = null; + + constructor( + @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, + @ICredentialsService private readonly credentialsService: ICredentialsService, + @IUserDataSyncStoreManagementService private readonly userDataSyncStoreManagementService: IUserDataSyncStoreManagementService, + @IFileService private readonly fileService: IFileService, + @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, + @IStorageService private readonly storageService: IStorageService, + @IProductService private readonly productService: IProductService, + @IRequestService private readonly requestService: IRequestService, + @ILogService private readonly logService: ILogService, + @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, + ) { + this.createUserDataSyncStoreClient().then(userDataSyncStoreClient => { + if (!userDataSyncStoreClient) { + this.initializationFinished.open(); + } + }); + } + + private _userDataSyncStoreClientPromise: Promise | undefined; + private createUserDataSyncStoreClient(): Promise { + if (!this._userDataSyncStoreClientPromise) { + this._userDataSyncStoreClientPromise = (async (): Promise => { + try { + if (!isWeb) { + this.logService.trace(`Skipping initializing user data in desktop`); + return; + } + + if (!this.storageService.isNew(StorageScope.APPLICATION)) { + this.logService.trace(`Skipping initializing user data as application was opened before`); + return; + } + + if (!this.storageService.isNew(StorageScope.WORKSPACE)) { + this.logService.trace(`Skipping initializing user data as workspace was opened before`); + return; + } + + let authenticationSession; + try { + authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.productService); + } catch (error) { + this.logService.error(error); + } + if (!authenticationSession) { + this.logService.trace(`Skipping initializing user data as authentication session is not set`); + return; + } + + await this.initializeUserDataSyncStore(authenticationSession); + + const userDataSyncStore = this.userDataSyncStoreManagementService.userDataSyncStore; + if (!userDataSyncStore) { + this.logService.trace(`Skipping initializing user data as sync service is not provided`); + return; + } + + const userDataSyncStoreClient = new UserDataSyncStoreClient(userDataSyncStore.url, this.productService, this.requestService, this.logService, this.environmentService, this.fileService, this.storageService); + userDataSyncStoreClient.setAuthToken(authenticationSession.accessToken, authenticationSession.providerId); + + const manifest = await userDataSyncStoreClient.manifest(null); + if (manifest === null) { + userDataSyncStoreClient.dispose(); + this.logService.trace(`Skipping initializing user data as there is no data`); + return; + } + + this.logService.info(`Using settings sync service ${userDataSyncStore.url.toString()} for initialization`); + return userDataSyncStoreClient; + + } catch (error) { + this.logService.error(error); + return; + } + })(); + } + + return this._userDataSyncStoreClientPromise; + } + + private async initializeUserDataSyncStore(authenticationSession: AuthenticationSessionInfo): Promise { + const userDataSyncStore = this.userDataSyncStoreManagementService.userDataSyncStore; + if (!userDataSyncStore?.canSwitch) { + return; + } + + const disposables = new DisposableStore(); + try { + const userDataSyncStoreClient = disposables.add(new UserDataSyncStoreClient(userDataSyncStore.url, this.productService, this.requestService, this.logService, this.environmentService, this.fileService, this.storageService)); + userDataSyncStoreClient.setAuthToken(authenticationSession.accessToken, authenticationSession.providerId); + + // Cache global state data for global state initialization + this.globalStateUserData = await userDataSyncStoreClient.readResource(SyncResource.GlobalState, null); + + if (this.globalStateUserData) { + const userDataSyncStoreType = new UserDataSyncStoreTypeSynchronizer(userDataSyncStoreClient, this.storageService, this.environmentService, this.fileService, this.logService).getSyncStoreType(this.globalStateUserData); + if (userDataSyncStoreType) { + await this.userDataSyncStoreManagementService.switch(userDataSyncStoreType); + + // Unset cached global state data if urls are changed + if (!isEqual(userDataSyncStore.url, this.userDataSyncStoreManagementService.userDataSyncStore?.url)) { + this.logService.info('Switched settings sync store'); + this.globalStateUserData = null; + } + } + } + } finally { + disposables.dispose(); + } + } + + async whenInitializationFinished(): Promise { + await this.initializationFinished.wait(); + } + + async requiresInitialization(): Promise { + this.logService.trace(`UserDataInitializationService#requiresInitialization`); + const userDataSyncStoreClient = await this.createUserDataSyncStoreClient(); + return !!userDataSyncStoreClient; + } + + async initializeRequiredResources(): Promise { + this.logService.trace(`UserDataInitializationService#initializeRequiredResources`); + return this.initialize([SyncResource.Settings, SyncResource.GlobalState]); + } + + async initializeOtherResources(instantiationService: IInstantiationService): Promise { + try { + this.logService.trace(`UserDataInitializationService#initializeOtherResources`); + await Promise.allSettled([this.initialize([SyncResource.Keybindings, SyncResource.Snippets, SyncResource.Tasks]), this.initializeExtensions(instantiationService)]); + } finally { + this.initializationFinished.open(); + } + } + + private async initializeExtensions(instantiationService: IInstantiationService): Promise { + try { + await Promise.all([this.initializeInstalledExtensions(instantiationService), this.initializeNewExtensions(instantiationService)]); + } finally { + this.initialized.push(SyncResource.Extensions); + } + } + + private initializeInstalledExtensionsPromise: Promise | undefined; + async initializeInstalledExtensions(instantiationService: IInstantiationService): Promise { + if (!this.initializeInstalledExtensionsPromise) { + this.initializeInstalledExtensionsPromise = (async () => { + this.logService.trace(`UserDataInitializationService#initializeInstalledExtensions`); + const extensionsPreviewInitializer = await this.getExtensionsPreviewInitializer(instantiationService); + if (extensionsPreviewInitializer) { + await instantiationService.createInstance(InstalledExtensionsInitializer, extensionsPreviewInitializer).initialize(); + } + })(); + } + return this.initializeInstalledExtensionsPromise; + } + + private initializeNewExtensionsPromise: Promise | undefined; + private async initializeNewExtensions(instantiationService: IInstantiationService): Promise { + if (!this.initializeNewExtensionsPromise) { + this.initializeNewExtensionsPromise = (async () => { + this.logService.trace(`UserDataInitializationService#initializeNewExtensions`); + const extensionsPreviewInitializer = await this.getExtensionsPreviewInitializer(instantiationService); + if (extensionsPreviewInitializer) { + await instantiationService.createInstance(NewExtensionsInitializer, extensionsPreviewInitializer).initialize(); + } + })(); + } + return this.initializeNewExtensionsPromise; + } + + private extensionsPreviewInitializerPromise: Promise | undefined; + private getExtensionsPreviewInitializer(instantiationService: IInstantiationService): Promise { + if (!this.extensionsPreviewInitializerPromise) { + this.extensionsPreviewInitializerPromise = (async () => { + const userDataSyncStoreClient = await this.createUserDataSyncStoreClient(); + if (!userDataSyncStoreClient) { + return null; + } + const userData = await userDataSyncStoreClient.readResource(SyncResource.Extensions, null); + return instantiationService.createInstance(ExtensionsPreviewInitializer, userData); + })(); + } + return this.extensionsPreviewInitializerPromise; + } + + private async initialize(syncResources: SyncResource[]): Promise { + const userDataSyncStoreClient = await this.createUserDataSyncStoreClient(); + if (!userDataSyncStoreClient) { + return; + } + + await Promises.settled(syncResources.map(async syncResource => { + try { + if (this.initialized.includes(syncResource)) { + this.logService.info(`${getSyncAreaLabel(syncResource)} initialized already.`); + return; + } + this.initialized.push(syncResource); + this.logService.trace(`Initializing ${getSyncAreaLabel(syncResource)}`); + const initializer = this.createSyncResourceInitializer(syncResource); + const userData = await userDataSyncStoreClient.readResource(syncResource, syncResource === SyncResource.GlobalState ? this.globalStateUserData : null); + await initializer.initialize(userData); + this.logService.info(`Initialized ${getSyncAreaLabel(syncResource)}`); + } catch (error) { + this.logService.info(`Error while initializing ${getSyncAreaLabel(syncResource)}`); + this.logService.error(error); + } + })); + } + + private createSyncResourceInitializer(syncResource: SyncResource): IUserDataInitializer { + switch (syncResource) { + case SyncResource.Settings: return new SettingsInitializer(this.fileService, this.userDataProfilesService, this.environmentService, this.logService, this.storageService, this.uriIdentityService); + case SyncResource.Keybindings: return new KeybindingsInitializer(this.fileService, this.userDataProfilesService, this.environmentService, this.logService, this.storageService, this.uriIdentityService); + case SyncResource.Tasks: return new TasksInitializer(this.fileService, this.userDataProfilesService, this.environmentService, this.logService, this.storageService, this.uriIdentityService); + case SyncResource.Snippets: return new SnippetsInitializer(this.fileService, this.userDataProfilesService, this.environmentService, this.logService, this.storageService, this.uriIdentityService); + case SyncResource.GlobalState: return new GlobalStateInitializer(this.storageService, this.fileService, this.userDataProfilesService, this.environmentService, this.logService, this.uriIdentityService); + } + throw new Error(`Cannot create initializer for ${syncResource}`); + } + +} + +class ExtensionsPreviewInitializer extends AbstractExtensionsInitializer { + + private previewPromise: Promise | undefined; + private preview: IExtensionsInitializerPreviewResult | null = null; + + constructor( + private readonly extensionsData: IUserData, + @IExtensionManagementService extensionManagementService: IExtensionManagementService, + @IIgnoredExtensionsManagementService ignoredExtensionsManagementService: IIgnoredExtensionsManagementService, + @IFileService fileService: IFileService, + @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService, + @IEnvironmentService environmentService: IEnvironmentService, + @IUserDataSyncLogService logService: IUserDataSyncLogService, + @IStorageService storageService: IStorageService, + @IUriIdentityService uriIdentityService: IUriIdentityService, + ) { + super(extensionManagementService, ignoredExtensionsManagementService, fileService, userDataProfilesService, environmentService, logService, storageService, uriIdentityService); + } + + getPreview(): Promise { + if (!this.previewPromise) { + this.previewPromise = super.initialize(this.extensionsData).then(() => this.preview); + } + return this.previewPromise; + } + + override initialize(): Promise { + throw new Error('should not be called directly'); + } + + protected override async doInitialize(remoteUserData: IRemoteUserData): Promise { + const remoteExtensions = await this.parseExtensions(remoteUserData); + if (!remoteExtensions) { + this.logService.info('Skipping initializing extensions because remote extensions does not exist.'); + return; + } + const installedExtensions = await this.extensionManagementService.getInstalled(); + this.preview = this.generatePreview(remoteExtensions, installedExtensions); + } +} + +class InstalledExtensionsInitializer implements IUserDataInitializer { + + constructor( + private readonly extensionsPreviewInitializer: ExtensionsPreviewInitializer, + @IGlobalExtensionEnablementService private readonly extensionEnablementService: IGlobalExtensionEnablementService, + @IExtensionStorageService private readonly extensionStorageService: IExtensionStorageService, + @IUserDataSyncLogService private readonly logService: IUserDataSyncLogService, + ) { + } + + async initialize(): Promise { + const preview = await this.extensionsPreviewInitializer.getPreview(); + if (!preview) { + return; + } + + // 1. Initialise already installed extensions state + for (const installedExtension of preview.installedExtensions) { + const syncExtension = preview.remoteExtensions.find(({ identifier }) => areSameExtensions(identifier, installedExtension.identifier)); + if (syncExtension?.state) { + const extensionState = this.extensionStorageService.getExtensionState(installedExtension, true) || {}; + Object.keys(syncExtension.state).forEach(key => extensionState[key] = syncExtension.state![key]); + this.extensionStorageService.setExtensionState(installedExtension, extensionState, true); + } + } + + // 2. Initialise extensions enablement + if (preview.disabledExtensions.length) { + for (const identifier of preview.disabledExtensions) { + this.logService.trace(`Disabling extension...`, identifier.id); + await this.extensionEnablementService.disableExtension(identifier); + this.logService.info(`Disabling extension`, identifier.id); + } + } + } +} + +class NewExtensionsInitializer implements IUserDataInitializer { + + constructor( + private readonly extensionsPreviewInitializer: ExtensionsPreviewInitializer, + @IExtensionService private readonly extensionService: IExtensionService, + @IExtensionStorageService private readonly extensionStorageService: IExtensionStorageService, + @IExtensionGalleryService private readonly galleryService: IExtensionGalleryService, + @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, + @IUserDataSyncLogService private readonly logService: IUserDataSyncLogService, + ) { + } + + async initialize(): Promise { + const preview = await this.extensionsPreviewInitializer.getPreview(); + if (!preview) { + return; + } + + const newlyEnabledExtensions: ILocalExtension[] = []; + const targetPlatform = await this.extensionManagementService.getTargetPlatform(); + const galleryExtensions = await this.galleryService.getExtensions(preview.newExtensions, { targetPlatform, compatible: true }, CancellationToken.None); + for (const galleryExtension of galleryExtensions) { + try { + const extensionToSync = preview.remoteExtensions.find(({ identifier }) => areSameExtensions(identifier, galleryExtension.identifier)); + if (!extensionToSync) { + continue; + } + if (extensionToSync.state) { + this.extensionStorageService.setExtensionState(galleryExtension, extensionToSync.state, true); + } + this.logService.trace(`Installing extension...`, galleryExtension.identifier.id); + const local = await this.extensionManagementService.installFromGallery(galleryExtension, { + isMachineScoped: false, /* set isMachineScoped to prevent install and sync dialog in web */ + donotIncludePackAndDependencies: true, + installGivenVersion: !!extensionToSync.version, + installPreReleaseVersion: extensionToSync.preRelease + }); + if (!preview.disabledExtensions.some(identifier => areSameExtensions(identifier, galleryExtension.identifier))) { + newlyEnabledExtensions.push(local); + } + this.logService.info(`Installed extension.`, galleryExtension.identifier.id); + } catch (error) { + this.logService.error(error); + } + } + + const canEnabledExtensions = newlyEnabledExtensions.filter(e => this.extensionService.canAddExtension(toExtensionDescription(e))); + if (!(await this.areExtensionsRunning(canEnabledExtensions))) { + await new Promise((c, e) => { + const disposable = this.extensionService.onDidChangeExtensions(async () => { + try { + if (await this.areExtensionsRunning(canEnabledExtensions)) { + disposable.dispose(); + c(); + } + } catch (error) { + e(error); + } + }); + }); + } + } + + private async areExtensionsRunning(extensions: ILocalExtension[]): Promise { + await this.extensionService.whenInstalledExtensionsRegistered(); + const runningExtensions = this.extensionService.extensions; + return extensions.every(e => runningExtensions.some(r => areSameExtensions({ id: r.identifier.value }, e.identifier))); + } +} + +class InitializeOtherResourcesContribution implements IWorkbenchContribution { + constructor( + @IUserDataInitializationService userDataInitializeService: IUserDataInitializationService, + @IInstantiationService instantiationService: IInstantiationService, + @IExtensionService extensionService: IExtensionService + ) { + extensionService.whenInstalledExtensionsRegistered().then(() => this.initializeOtherResource(userDataInitializeService, instantiationService)); + } + + private async initializeOtherResource(userDataInitializeService: IUserDataInitializationService, instantiationService: IInstantiationService): Promise { + if (await userDataInitializeService.requiresInitialization()) { + mark('code/willInitOtherUserData'); + await userDataInitializeService.initializeOtherResources(instantiationService); + mark('code/didInitOtherUserData'); + } + } +} + +if (isWeb) { + const workbenchRegistry = Registry.as(Extensions.Workbench); + workbenchRegistry.registerWorkbenchContribution(InitializeOtherResourcesContribution, LifecyclePhase.Restored); +} diff --git a/src/vs/workbench/services/userDataProfile/browser/extensionsResource.ts b/src/vs/workbench/services/userDataProfile/browser/extensionsResource.ts index c93123c8847..62dfa467698 100644 --- a/src/vs/workbench/services/userDataProfile/browser/extensionsResource.ts +++ b/src/vs/workbench/services/userDataProfile/browser/extensionsResource.ts @@ -50,7 +50,7 @@ export class ExtensionsResource implements IProfileResource { return this.withProfileScopedServices(profile, async (extensionEnablementService) => { const profileExtensions: IProfileExtension[] = await this.getProfileExtensions(content); const installedExtensions = await this.extensionManagementService.getInstalled(undefined, profile.extensionsResource); - const extensionsToEnableOrDisable: { extension: ILocalExtension; enable: boolean }[] = []; + const extensionsToEnableOrDisable: { extension: IExtensionIdentifier; enable: boolean }[] = []; const extensionsToInstall: IProfileExtension[] = []; for (const e of profileExtensions) { const isDisabled = extensionEnablementService.getDisabledExtensions().some(disabledExtension => areSameExtensions(disabledExtension, e.identifier)); @@ -58,20 +58,20 @@ export class ExtensionsResource implements IProfileResource { if (!installedExtension || (!installedExtension.isBuiltin && installedExtension.preRelease !== e.preRelease)) { extensionsToInstall.push(e); } - if (installedExtension && isDisabled !== !!e.disabled) { - extensionsToEnableOrDisable.push({ extension: installedExtension, enable: !e.disabled }); + if (isDisabled !== !!e.disabled) { + extensionsToEnableOrDisable.push({ extension: e.identifier, enable: !e.disabled }); } } const extensionsToUninstall: ILocalExtension[] = installedExtensions.filter(extension => !extension.isBuiltin && !profileExtensions.some(({ identifier }) => areSameExtensions(identifier, extension.identifier))); for (const { extension, enable } of extensionsToEnableOrDisable) { if (enable) { - this.logService.trace(`Importing Profile (${profile.name}): Enabling extension...`, extension.identifier.id); - await extensionEnablementService.enableExtension(extension.identifier); - this.logService.info(`Importing Profile (${profile.name}): Enabled extension...`, extension.identifier.id); + this.logService.trace(`Importing Profile (${profile.name}): Enabling extension...`, extension.id); + await extensionEnablementService.enableExtension(extension); + this.logService.info(`Importing Profile (${profile.name}): Enabled extension...`, extension.id); } else { - this.logService.trace(`Importing Profile (${profile.name}): Disabling extension...`, extension.identifier.id); - await extensionEnablementService.disableExtension(extension.identifier); - this.logService.info(`Importing Profile (${profile.name}): Disabled extension...`, extension.identifier.id); + this.logService.trace(`Importing Profile (${profile.name}): Disabling extension...`, extension.id); + await extensionEnablementService.disableExtension(extension); + this.logService.info(`Importing Profile (${profile.name}): Disabled extension...`, extension.id); } } if (extensionsToInstall.length) { @@ -120,10 +120,6 @@ export class ExtensionsResource implements IProfileResource { // skip user extensions without uuid continue; } - if (disabled && !extension.isBuiltin) { - // skip user disabled extensions - continue; - } } const profileExtension: IProfileExtension = { identifier, displayName: extension.manifest.displayName }; if (disabled) { @@ -188,7 +184,8 @@ export abstract class ExtensionsResourceTreeItem implements IProfileResourceTree } else { that.excludedExtensions.add(e.identifier.id.toLowerCase()); } - } + }, + tooltip: localize('exclude', "Select {0} Extension", e.displayName || e.identifier.id) } : undefined, command: { id: 'extension.open', diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts index bf0ff614dd8..43a0d25efa1 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts @@ -10,7 +10,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { INotificationService } from 'vs/platform/notification/common/notification'; import { Emitter, Event } from 'vs/base/common/event'; import * as DOM from 'vs/base/browser/dom'; -import { IUserDataProfileImportExportService, PROFILE_FILTER, PROFILE_EXTENSION, IUserDataProfileContentHandler, IS_PROFILE_IMPORT_IN_PROGRESS_CONTEXT, PROFILES_TTILE, defaultUserDataProfileIcon, IUserDataProfileService, IProfileResourceTreeItem, IProfileResourceChildTreeItem, PROFILES_CATEGORY, IUserDataProfileManagementService, ProfileResourceType, IS_PROFILE_EXPORT_IN_PROGRESS_CONTEXT, ISaveProfileResult, IProfileImportOptions, PROFILE_URL_AUTHORITY, toUserDataProfileUri } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { IUserDataProfileImportExportService, PROFILE_FILTER, PROFILE_EXTENSION, IUserDataProfileContentHandler, IS_PROFILE_IMPORT_IN_PROGRESS_CONTEXT, PROFILES_TITLE, defaultUserDataProfileIcon, IUserDataProfileService, IProfileResourceTreeItem, IProfileResourceChildTreeItem, PROFILES_CATEGORY, IUserDataProfileManagementService, ProfileResourceType, IS_PROFILE_EXPORT_IN_PROGRESS_CONTEXT, ISaveProfileResult, IProfileImportOptions, PROFILE_URL_AUTHORITY, toUserDataProfileUri } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { IDialogService, IFileDialogService, IPromptButton } from 'vs/platform/dialogs/common/dialogs'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; @@ -107,7 +107,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU private readonly isProfileImportInProgressContextKey: IContextKey; private readonly viewContainer: ViewContainer; - private readonly fileUserDataProfileContentHandler: IUserDataProfileContentHandler; + private readonly fileUserDataProfileContentHandler: FileUserDataProfileContentHandler; constructor( @IInstantiationService private readonly instantiationService: IInstantiationService, @@ -115,7 +115,6 @@ export class UserDataProfileImportExportService extends Disposable implements IU @IViewsService private readonly viewsService: IViewsService, @IEditorService private readonly editorService: IEditorService, @IContextKeyService contextKeyService: IContextKeyService, - @IFileService private readonly fileService: IFileService, @IUserDataProfileManagementService private readonly userDataProfileManagementService: IUserDataProfileManagementService, @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, @IExtensionService private readonly extensionService: IExtensionService, @@ -140,7 +139,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU this.viewContainer = Registry.as(Extensions.ViewContainersRegistry).registerViewContainer( { id: 'userDataProfiles', - title: PROFILES_TTILE, + title: PROFILES_TITLE, ctorDescriptor: new SyncDescriptor( ViewPaneContainer, ['userDataProfiles', { mergeViewWithContainerWhenSingleView: true }] @@ -228,11 +227,16 @@ export class UserDataProfileImportExportService extends Disposable implements IU try { const userDataProfilesExportState = disposables.add(this.instantiationService.createInstance(UserDataProfileExportState, this.userDataProfileService.currentProfile)); const barrier = new Barrier(); - const exportAction = new BarrierAction(barrier, new Action('export', localize('export', "Export"), undefined, true, () => { + const exportAction = new BarrierAction(barrier, new Action('export', localize('export', "Export"), undefined, true, async () => { exportAction.enabled = false; - return this.doExportProfile(userDataProfilesExportState); - })); - const closeAction = new BarrierAction(barrier, new Action('close', localize('close', "Close"))); + try { + await this.doExportProfile(userDataProfilesExportState); + } catch (error) { + this.notificationService.error(error); + throw error; + } + }), this.notificationService); + const closeAction = new BarrierAction(barrier, new Action('close', localize('close', "Close")), this.notificationService); await this.showProfilePreviewView(EXPORT_PROFILE_PREVIEW_VIEW, userDataProfilesExportState.profile.name, exportAction, closeAction, true, userDataProfilesExportState); disposables.add(this.userDataProfileService.onDidChangeCurrentProfile(e => barrier.open())); await barrier.wait(); @@ -265,7 +269,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU if (!profileContentHandler) { return; } - const saveResult = await profileContentHandler.saveProfile(profile.name, JSON.stringify(profile), CancellationToken.None); + const saveResult = await profileContentHandler.saveProfile(profile.name.replace('/', '-'), JSON.stringify(profile), CancellationToken.None); if (!saveResult) { return; } @@ -336,11 +340,14 @@ export class UserDataProfileImportExportService extends Disposable implements IU const barrier = new Barrier(); const importAction = this.getImportAction(barrier, userDataProfileImportState); - const secondaryAction = isWeb + const primaryAction = isWeb ? new Action('importInDesktop', localize('import in desktop', "Import Profile in {1}", importedProfile.name, this.productService.nameLong), undefined, true, async () => this.openerService.open(uri, { openExternal: true })) - : new BarrierAction(barrier, new Action('close', localize('close', "Close"))); + : importAction; + const secondaryAction = isWeb + ? importAction + : new BarrierAction(barrier, new Action('close', localize('close', "Close")), this.notificationService); - const view = await this.showProfilePreviewView(IMPORT_PROFILE_PREVIEW_VIEW, importedProfile.name, importAction, secondaryAction, false, userDataProfileImportState); + const view = await this.showProfilePreviewView(IMPORT_PROFILE_PREVIEW_VIEW, importedProfile.name, primaryAction, secondaryAction, false, userDataProfileImportState); const message = new MarkdownString(); message.appendMarkdown(localize('preview profile message', "By default, extensions aren't installed when previewing a profile on the web. You can still install them manually before importing the profile. ")); message.appendMarkdown(`[${localize('learn more', "Learn more")}](https://aka.ms/vscode-extension-marketplace#_can-i-trust-extensions-from-the-marketplace).`); @@ -401,7 +408,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU if (userDataProfileImportState.isEmpty()) { await importAction.run(); } else { - await this.showProfilePreviewView(IMPORT_PROFILE_PREVIEW_VIEW, profileTemplate.name, importAction, new BarrierAction(barrier, new Action('cancel', localize('cancel', "Cancel"))), false, userDataProfileImportState); + await this.showProfilePreviewView(IMPORT_PROFILE_PREVIEW_VIEW, profileTemplate.name, importAction, new BarrierAction(barrier, new Action('cancel', localize('cancel', "Cancel")), this.notificationService), false, userDataProfileImportState); } await barrier.wait(); await this.hideProfilePreviewView(IMPORT_PROFILE_PREVIEW_VIEW); @@ -435,7 +442,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU location: IMPORT_PROFILE_PREVIEW_VIEW, }, () => importProfileFn()); } - })); + }), this.notificationService); return importAction; } @@ -482,7 +489,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU } private async resolveProfileContent(resource: URI): Promise { - if (await this.fileService.canHandleResource(resource)) { + if (await this.fileUserDataProfileContentHandler.canHandle(resource)) { return this.fileUserDataProfileContentHandler.readProfile(resource, CancellationToken.None); } @@ -537,10 +544,11 @@ export class UserDataProfileImportExportService extends Disposable implements IU } private async getProfileToImport(profileTemplate: IUserDataProfileTemplate, temp?: boolean): Promise { - const profile = this.userDataProfilesService.profiles.find(p => p.name === profileTemplate.name); + const profileName = temp ? `${profileTemplate.name} (${localize('preview', "Preview")})` : profileTemplate.name; + const profile = this.userDataProfilesService.profiles.find(p => p.name === profileName); if (profile) { if (temp) { - return this.userDataProfilesService.createNamedProfile(`${profileTemplate.name} ${this.getProfileNameIndex(profileTemplate.name)}`, { shortName: profileTemplate.shortName, transient: temp }); + return this.userDataProfilesService.createNamedProfile(`${profileName} ${this.getProfileNameIndex(profileName)}`, { shortName: profileTemplate.shortName, transient: temp }); } enum ImportProfileChoice { @@ -550,7 +558,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU } const { result } = await this.dialogService.prompt({ type: Severity.Info, - message: localize('profile already exists', "Profile with name '{0}' already exists. Do you want to overwrite it?", profileTemplate.name), + message: localize('profile already exists', "Profile with name '{0}' already exists. Do you want to overwrite it?", profileName), buttons: [ { label: localize({ key: 'overwrite', comment: ['&& denotes a mnemonic'] }, "&&Overwrite"), @@ -578,7 +586,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU const name = await this.quickInputService.input({ placeHolder: localize('name', "Profile name"), title: localize('create new title', "Create New Profile"), - value: `${profileTemplate.name} ${this.getProfileNameIndex(profileTemplate.name)}`, + value: `${profileName} ${this.getProfileNameIndex(profileName)}`, validateInput: async (value: string) => { if (this.userDataProfilesService.profiles.some(p => p.name === value)) { return localize('profileExists', "Profile with name {0} already exists.", value); @@ -591,7 +599,7 @@ export class UserDataProfileImportExportService extends Disposable implements IU } return this.userDataProfilesService.createNamedProfile(name); } else { - return this.userDataProfilesService.createNamedProfile(profileTemplate.name, { shortName: profileTemplate.shortName, transient: temp }); + return this.userDataProfilesService.createNamedProfile(profileName, { shortName: profileTemplate.shortName, transient: temp }); } } @@ -689,8 +697,12 @@ class FileUserDataProfileContentHandler implements IUserDataProfileContentHandle return { link, id: link.toString() }; } + async canHandle(uri: URI): Promise { + return uri.scheme !== Schemas.http && uri.scheme !== Schemas.https && await this.fileService.canHandleResource(uri); + } + async readProfile(uri: URI, token: CancellationToken): Promise { - if (await this.fileService.canHandleResource(uri)) { + if (await this.canHandle(uri)) { return (await this.fileService.readFile(uri, undefined, token)).value.toString(); } return null; @@ -873,7 +885,7 @@ abstract class UserDataProfileImportExportState extends Disposable implements IT } } - onDidChangeCheckboxState(items: ITreeItem[]): ITreeItem[] { + onDidChangeCheckboxState(items: readonly ITreeItem[]): readonly ITreeItem[] { const toRefresh: ITreeItem[] = []; for (const item of items) { if (item.children) { @@ -912,7 +924,7 @@ abstract class UserDataProfileImportExportState extends Disposable implements IT this.roots = await this.fetchRoots(); for (const root of this.roots) { if (this.canSelect) { - root.checkbox = { isChecked: true }; + root.checkbox = { isChecked: true, tooltip: localize('select', "Select {0}", root.label.label) }; } else { root.checkbox = undefined; } @@ -1061,6 +1073,7 @@ class UserDataProfileExportState extends UserDataProfileImportExportState { tasksResource: profile.tasksResource.with({ scheme: USER_DATA_PROFILE_EXPORT_SCHEME }), snippetsHome: profile.snippetsHome.with({ scheme: USER_DATA_PROFILE_EXPORT_SCHEME }), extensionsResource: profile.extensionsResource, + cacheHome: profile.cacheHome, useDefaultFlags: profile.useDefaultFlags, isTransient: profile.isTransient }; @@ -1108,7 +1121,7 @@ class UserDataProfileImportState extends UserDataProfileImportExportState { const inMemoryProvider = this._register(new InMemoryFileSystemProvider()); this.disposables.add(this.fileService.registerProvider(USER_DATA_PROFILE_IMPORT_PREVIEW_SCHEME, inMemoryProvider)); const roots: IProfileResourceTreeItem[] = []; - const importPreviewProfle = toUserDataProfile(generateUuid(), this.profile.name, URI.file('/root').with({ scheme: USER_DATA_PROFILE_IMPORT_PREVIEW_SCHEME })); + const importPreviewProfle = toUserDataProfile(generateUuid(), this.profile.name, URI.file('/root').with({ scheme: USER_DATA_PROFILE_IMPORT_PREVIEW_SCHEME }), URI.file('/cache').with({ scheme: USER_DATA_PROFILE_IMPORT_PREVIEW_SCHEME })); if (this.profile.settings) { const settingsResource = this.instantiationService.createInstance(SettingsResource); @@ -1178,9 +1191,15 @@ class UserDataProfileImportState extends UserDataProfileImportExportState { } class BarrierAction extends Action { - constructor(barrier: Barrier, action: Action) { + constructor(barrier: Barrier, action: Action, + notificationService: INotificationService) { super(action.id, action.label, action.class, action.enabled, async () => { - await action.run(); + try { + await action.run(); + } catch (error) { + notificationService.error(error); + throw error; + } barrier.open(); }); } diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts index 904deb8d5cf..9ac17c00d3b 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts @@ -133,8 +133,8 @@ export const defaultUserDataProfileIcon = registerIcon('defaultProfile-icon', Co export const ProfilesMenu = new MenuId('Profiles'); export const MANAGE_PROFILES_ACTION_ID = 'workbench.profiles.actions.manage'; -export const PROFILES_TTILE = { value: localize('profiles', "Profiles"), original: 'Profiles' }; -export const PROFILES_CATEGORY = { ...PROFILES_TTILE }; +export const PROFILES_TITLE = { value: localize('profiles', "Profiles"), original: 'Profiles' }; +export const PROFILES_CATEGORY = { ...PROFILES_TITLE }; export const PROFILE_EXTENSION = 'code-profile'; export const PROFILE_FILTER = [{ name: localize('profile', "Profile"), extensions: [PROFILE_EXTENSION] }]; export const PROFILES_ENABLEMENT_CONTEXT = new RawContextKey('profiles.enabled', true); diff --git a/src/vs/workbench/services/utilityProcess/electron-sandbox/utilityProcessWorkerWorkbenchService.ts b/src/vs/workbench/services/utilityProcess/electron-sandbox/utilityProcessWorkerWorkbenchService.ts index 801b5d805fc..5ff45dbcffc 100644 --- a/src/vs/workbench/services/utilityProcess/electron-sandbox/utilityProcessWorkerWorkbenchService.ts +++ b/src/vs/workbench/services/utilityProcess/electron-sandbox/utilityProcessWorkerWorkbenchService.ts @@ -5,7 +5,8 @@ import { ILogService } from 'vs/platform/log/common/log'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IMainProcessService, ISharedProcessService } from 'vs/platform/ipc/electron-sandbox/services'; +import { ISharedProcessService } from 'vs/platform/ipc/electron-sandbox/services'; +import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService'; import { Client as MessagePortClient } from 'vs/base/parts/ipc/common/ipc.mp'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IPCClient, ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; @@ -132,6 +133,14 @@ export class UtilityProcessWorkerWorkbenchService extends Disposable implements const client = disposables.add(new MessagePortClient(port, `window:${this.windowId},module:${process.moduleId}`)); this.logService.trace('Renderer->UtilityProcess#createWorkerChannel: connection established'); + onDidTerminate.then(({ reason }) => { + if (reason?.code === 0) { + this.logService.trace(`[UtilityProcessWorker]: terminated normally with code ${reason.code}, signal: ${reason.signal}`); + } else { + this.logService.error(`[UtilityProcessWorker]: terminated unexpectedly with code ${reason?.code}, signal: ${reason?.signal}`); + } + }); + return { client, onDidTerminate, dispose: () => disposables.dispose() }; } diff --git a/src/vs/workbench/services/views/browser/treeViewsService.ts b/src/vs/workbench/services/views/browser/treeViewsService.ts index 2ea49fe806d..77f421f1829 100644 --- a/src/vs/workbench/services/views/browser/treeViewsService.ts +++ b/src/vs/workbench/services/views/browser/treeViewsService.ts @@ -5,10 +5,9 @@ import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { VSDataTransfer } from 'vs/base/common/dataTransfer'; import { ITreeItem } from 'vs/workbench/common/views'; import { ITreeViewsService as ITreeViewsServiceCommon, TreeviewsService } from 'vs/workbench/services/views/common/treeViewsService'; -export interface ITreeViewsService extends ITreeViewsServiceCommon { } +export interface ITreeViewsService extends ITreeViewsServiceCommon { } export const ITreeViewsService = createDecorator('treeViewsService'); registerSingleton(ITreeViewsService, TreeviewsService, InstantiationType.Delayed); diff --git a/src/vs/workbench/services/views/browser/viewDescriptorService.ts b/src/vs/workbench/services/views/browser/viewDescriptorService.ts index 3fd473bd5c6..906e48e5b12 100644 --- a/src/vs/workbench/services/views/browser/viewDescriptorService.ts +++ b/src/vs/workbench/services/views/browser/viewDescriptorService.ts @@ -24,6 +24,7 @@ import { IStringDictionary } from 'vs/base/common/collections'; interface IViewsCustomizations { viewContainerLocations: IStringDictionary; viewLocations: IStringDictionary; + viewContainerBadgeEnablementStates: IStringDictionary; } function getViewContainerStorageId(viewContainerId: string): string { return `${viewContainerId}.state`; } @@ -56,6 +57,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor private viewContainersCustomLocations: Map; private viewDescriptorsCustomLocations: Map; + private viewContainerBadgeEnablementStates: Map; private readonly _onDidChangeViewContainers = this._register(new Emitter<{ added: ReadonlyArray<{ container: ViewContainer; location: ViewContainerLocation }>; removed: ReadonlyArray<{ container: ViewContainer; location: ViewContainerLocation }> }>()); readonly onDidChangeViewContainers = this._onDidChangeViewContainers.event; @@ -81,6 +83,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor this.migrateToViewsCustomizationsStorage(); this.viewContainersCustomLocations = new Map(Object.entries(this.viewCustomizations.viewContainerLocations)); this.viewDescriptorsCustomLocations = new Map(Object.entries(this.viewCustomizations.viewLocations)); + this.viewContainerBadgeEnablementStates = new Map(Object.entries(this.viewCustomizations.viewContainerBadgeEnablementStates)); // Register all containers that were registered before this ctor this.viewContainers.forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer)); @@ -122,6 +125,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor const viewsCustomizations: IViewsCustomizations = { viewContainerLocations: viewContainerLocations.reduce>((result, [id, location]) => { result[id] = location; return result; }, {}), viewLocations: viewDescriptorLocations.reduce>((result, [id, { containerId }]) => { result[id] = containerId; return result; }, {}), + viewContainerBadgeEnablementStates: {} }; this.storageService.store(ViewDescriptorService.VIEWS_CUSTOMIZATIONS, JSON.stringify(viewsCustomizations), StorageScope.PROFILE, StorageTarget.USER); this.storageService.remove('views.cachedViewContainerLocations', StorageScope.PROFILE); @@ -299,6 +303,15 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor this.saveViewCustomizations(); } + getViewContainerBadgeEnablementState(id: string): boolean { + return this.viewContainerBadgeEnablementStates.get(id) ?? true; + } + + setViewContainerBadgeEnablementState(id: string, badgesEnabled: boolean): void { + this.viewContainerBadgeEnablementStates.set(id, badgesEnabled); + this.saveViewCustomizations(); + } + moveViewToLocation(view: IViewDescriptor, location: ViewContainerLocation): void { const container = this.registerGeneratedViewContainer(location); this.moveViewsToContainer([view], container); @@ -465,6 +478,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor } this.viewContainersCustomLocations.delete(viewContainerId); + this.viewContainerBadgeEnablementStates.delete(viewContainerId); // Clean up caches of container this.storageService.remove(getViewsStateStorageId(viewContainer?.storageId || getViewContainerStorageId(viewContainerId)), StorageScope.PROFILE); @@ -560,7 +574,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor } // Execute View Movements for (const { views, from, to } of viewsToMove) { - this.moveViewsWithoutSaving(views, from, to); + this.moveViewsWithoutSaving(views, from, to, ViewVisibilityState.Default); } this.viewContainersCustomLocations = newViewContainerCustomizations; @@ -576,7 +590,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor } private saveViewCustomizations(): void { - const viewCustomizations: IViewsCustomizations = { viewContainerLocations: {}, viewLocations: {} }; + const viewCustomizations: IViewsCustomizations = { viewContainerLocations: {}, viewLocations: {}, viewContainerBadgeEnablementStates: {} }; for (const [containerId, location] of this.viewContainersCustomLocations) { const container = this.getViewContainerById(containerId); @@ -600,6 +614,12 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor viewCustomizations.viewLocations[viewId] = viewContainerId; } + // Loop through viewContainerBadgeEnablementStates and save only the ones that are disabled + for (const [viewContainerId, badgeEnablementState] of this.viewContainerBadgeEnablementStates) { + if (badgeEnablementState === false) { + viewCustomizations.viewContainerBadgeEnablementStates[viewContainerId] = badgeEnablementState; + } + } this.viewCustomizations = viewCustomizations; } @@ -609,6 +629,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor this._viewCustomizations = JSON.parse(this.getStoredViewCustomizationsValue()) as IViewsCustomizations; this._viewCustomizations.viewContainerLocations = this._viewCustomizations.viewContainerLocations ?? {}; this._viewCustomizations.viewLocations = this._viewCustomizations.viewLocations ?? {}; + this._viewCustomizations.viewContainerBadgeEnablementStates = this._viewCustomizations.viewContainerBadgeEnablementStates ?? {}; } return this._viewCustomizations; } diff --git a/src/vs/workbench/services/views/common/treeViewsService.ts b/src/vs/workbench/services/views/common/treeViewsService.ts index 5e141cddd4e..ac1631c2d5f 100644 --- a/src/vs/workbench/services/views/common/treeViewsService.ts +++ b/src/vs/workbench/services/views/common/treeViewsService.ts @@ -3,36 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export interface ITreeViewsService { +export interface ITreeViewsService { readonly _serviceBrand: undefined; - removeDragOperationTransfer(uuid: string | undefined): Promise | undefined; - addDragOperationTransfer(uuid: string, transferPromise: Promise): void; - getRenderedTreeElement(node: U): V | undefined; addRenderedTreeItemElement(node: U, element: V): void; removeRenderedTreeItemElement(node: U): void; } -export class TreeviewsService implements ITreeViewsService { +export class TreeviewsService implements ITreeViewsService { _serviceBrand: undefined; - private _dragOperations: Map> = new Map(); private _renderedElements: Map = new Map(); - removeDragOperationTransfer(uuid: string | undefined): Promise | undefined { - if ((uuid && this._dragOperations.has(uuid))) { - const operation = this._dragOperations.get(uuid); - this._dragOperations.delete(uuid); - return operation; - } - return undefined; - } - - addDragOperationTransfer(uuid: string, transferPromise: Promise): void { - this._dragOperations.set(uuid, transferPromise); - } - - getRenderedTreeElement(node: U): V | undefined { if (this._renderedElements.has(node)) { return this._renderedElements.get(node); diff --git a/src/vs/workbench/services/views/common/viewContainerModel.ts b/src/vs/workbench/services/views/common/viewContainerModel.ts index dd0c4bc4be5..5849cf9b862 100644 --- a/src/vs/workbench/services/views/common/viewContainerModel.ts +++ b/src/vs/workbench/services/views/common/viewContainerModel.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ViewContainer, IViewsRegistry, IViewDescriptor, Extensions as ViewExtensions, IViewContainerModel, IAddedViewDescriptorRef, IViewDescriptorRef, IAddedViewDescriptorState, defaultViewIcon } from 'vs/workbench/common/views'; -import { IContextKeyService, IReadableSet } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage'; import { Registry } from 'vs/platform/registry/common/platform'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -22,6 +22,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; import { Categories } from 'vs/platform/action/common/actionCommonCategories'; import { IOutputService } from 'vs/workbench/services/output/common/output'; +import { CounterSet } from 'vs/base/common/map'; const VIEWS_LOG_ID = 'viewsLog'; const VIEWS_LOG_NAME = localize('views log', "Views"); @@ -48,38 +49,6 @@ registerAction2(class extends Action2 { export function getViewsStateStorageId(viewContainerStorageId: string): string { return `${viewContainerStorageId}.hidden`; } -class CounterSet implements IReadableSet { - - private map = new Map(); - - add(value: T): CounterSet { - this.map.set(value, (this.map.get(value) || 0) + 1); - return this; - } - - delete(value: T): boolean { - let counter = this.map.get(value) || 0; - - if (counter === 0) { - return false; - } - - counter--; - - if (counter === 0) { - this.map.delete(value); - } else { - this.map.set(value, counter); - } - - return true; - } - - has(value: T): boolean { - return this.map.has(value); - } -} - interface IStoredWorkspaceViewState { collapsed: boolean; isHidden: boolean; @@ -400,16 +369,6 @@ export class ViewContainerModel extends Disposable implements IViewContainerMode this.viewDescriptorsState = this._register(instantiationService.createInstance(ViewDescriptorsState, viewContainer.storageId || `${viewContainer.id}.state`, typeof viewContainer.title === 'string' ? viewContainer.title : viewContainer.title.original)); this._register(this.viewDescriptorsState.onDidChangeStoredState(items => this.updateVisibility(items))); - this._register(Event.any( - Event.map(this.onDidAddVisibleViewDescriptors, added => `Added views:${added.map(v => v.viewDescriptor.id).join(',')} in ${this.viewContainer.id}`), - Event.map(this.onDidRemoveVisibleViewDescriptors, removed => `Removed views:${removed.map(v => v.viewDescriptor.id).join(',')} from ${this.viewContainer.id}`), - Event.map(this.onDidMoveVisibleViewDescriptors, ({ from, to }) => `Moved view ${from.viewDescriptor.id} to ${to.viewDescriptor.id} in ${this.viewContainer.id}`)) - (message => { - this.logger.info(message); - this.viewDescriptorsState.updateState(this.allViewDescriptors); - this.updateContainerInfo(); - })); - this.updateContainerInfo(); } @@ -558,10 +517,7 @@ export class ViewContainerModel extends Disposable implements IViewContainerMode this.viewDescriptorItems[index].state.order = index; } - this._onDidMoveVisibleViewDescriptors.fire({ - from: { index: fromIndex, viewDescriptor: fromViewDescriptor.viewDescriptor }, - to: { index: toIndex, viewDescriptor: toViewDescriptor.viewDescriptor } - }); + this.broadCastMovedViewDescriptors({ index: fromIndex, viewDescriptor: fromViewDescriptor.viewDescriptor }, { index: toIndex, viewDescriptor: toViewDescriptor.viewDescriptor }); } add(addedViewDescriptorStates: IAddedViewDescriptorState[]): void { @@ -710,15 +666,28 @@ export class ViewContainerModel extends Disposable implements IViewContainerMode private broadCastAddedVisibleViewDescriptors(added: IAddedViewDescriptorRef[]): void { if (added.length) { this._onDidAddVisibleViewDescriptors.fire(added.sort((a, b) => a.index - b.index)); + this.updateState(`Added views:${added.map(v => v.viewDescriptor.id).join(',')} in ${this.viewContainer.id}`); } } private broadCastRemovedVisibleViewDescriptors(removed: IViewDescriptorRef[]): void { if (removed.length) { this._onDidRemoveVisibleViewDescriptors.fire(removed.sort((a, b) => b.index - a.index)); + this.updateState(`Removed views:${removed.map(v => v.viewDescriptor.id).join(',')} from ${this.viewContainer.id}`); } } + private broadCastMovedViewDescriptors(from: IViewDescriptorRef, to: IViewDescriptorRef): void { + this._onDidMoveVisibleViewDescriptors.fire({ from, to }); + this.updateState(`Moved view ${from.viewDescriptor.id} to ${to.viewDescriptor.id} in ${this.viewContainer.id}`); + } + + private updateState(reason: string): void { + this.logger.info(reason); + this.viewDescriptorsState.updateState(this.allViewDescriptors); + this.updateContainerInfo(); + } + private isViewDescriptorVisible(viewDescriptorItem: IViewDescriptorItem): boolean { if (!viewDescriptorItem.state.active) { return false; diff --git a/src/vs/workbench/services/views/test/browser/viewDescriptorService.test.ts b/src/vs/workbench/services/views/test/browser/viewDescriptorService.test.ts index 351df21dfb1..c873bc6800e 100644 --- a/src/vs/workbench/services/views/test/browser/viewDescriptorService.test.ts +++ b/src/vs/workbench/services/views/test/browser/viewDescriptorService.test.ts @@ -16,6 +16,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { generateUuid } from 'vs/base/common/uuid'; +import { compare } from 'vs/base/common/strings'; const ViewsRegistry = Registry.as(ViewContainerExtensions.ViewsRegistry); const ViewContainersRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); @@ -322,7 +323,7 @@ suite('ViewDescriptorService', () => { assert.deepStrictEqual(panelViews.allViewDescriptors.map(v => v.id), ['view3']); const actual = JSON.parse(instantiationService.get(IStorageService).get('views.customizations', StorageScope.PROFILE)!); - assert.deepStrictEqual(actual, { viewContainerLocations: {}, viewLocations: {} }); + assert.deepStrictEqual(actual, { viewContainerLocations: {}, viewLocations: {}, viewContainerBadgeEnablementStates: {} }); assert.deepStrictEqual(testObject.getViewContainerById(generatedPanel.id), null); assert.deepStrictEqual(testObject.getViewContainerById(generatedSidebar.id), null); @@ -519,7 +520,7 @@ suite('ViewDescriptorService', () => { assert.deepStrictEqual(testObject.isViewContainerRemovedPermanently(generatedViewContainerId), true); const actual = JSON.parse(storageService.get('views.customizations', StorageScope.PROFILE)!); - assert.deepStrictEqual(actual, { viewContainerLocations: {}, viewLocations: {} }); + assert.deepStrictEqual(actual, { viewContainerLocations: {}, viewLocations: {}, viewContainerBadgeEnablementStates: {} }); }); test('custom locations take precedence when default view container of views change', async function () { @@ -664,4 +665,56 @@ suite('ViewDescriptorService', () => { assert.deepStrictEqual(generatedViewContainerModel.allViewDescriptors.map(v => v.id), ['view1']); }); + test('storage change move views and retain visibility state', async function () { + const storageService = instantiationService.get(IStorageService); + const testObject = aViewDescriptorService(); + + const viewContainer = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + const viewDescriptors: IViewDescriptor[] = [ + { + id: 'view1', + ctorDescriptor: null!, + name: 'Test View 1', + canMoveView: true, + canToggleVisibility: true + }, + { + id: 'view2', + ctorDescriptor: null!, + name: 'Test View 2', + canMoveView: true + } + ]; + ViewsRegistry.registerViews(viewDescriptors, viewContainer); + + testObject.whenExtensionsRegistered(); + + const viewContainer1Views = testObject.getViewContainerModel(viewContainer); + viewContainer1Views.setVisible('view1', false); + + const generateViewContainerId = `workbench.views.service.${ViewContainerLocationToString(ViewContainerLocation.AuxiliaryBar)}.${generateUuid()}`; + const viewsCustomizations = { + viewContainerLocations: { + [generateViewContainerId]: ViewContainerLocation.AuxiliaryBar, + }, + viewLocations: { + 'view1': generateViewContainerId + } + }; + storageService.store('views.customizations', JSON.stringify(viewsCustomizations), StorageScope.PROFILE, StorageTarget.USER); + + const generateViewContainer = testObject.getViewContainerById(generateViewContainerId)!; + const generatedViewContainerModel = testObject.getViewContainerModel(generateViewContainer); + + assert.deepStrictEqual(viewContainer1Views.allViewDescriptors.map(v => v.id), ['view2']); + assert.deepStrictEqual(testObject.getViewContainerLocation(generateViewContainer), ViewContainerLocation.AuxiliaryBar); + assert.deepStrictEqual(generatedViewContainerModel.allViewDescriptors.map(v => v.id), ['view1']); + + storageService.store('views.customizations', JSON.stringify({}), StorageScope.PROFILE, StorageTarget.USER); + + assert.deepStrictEqual(viewContainer1Views.allViewDescriptors.map(v => v.id).sort((a, b) => compare(a, b)), ['view1', 'view2']); + assert.deepStrictEqual(viewContainer1Views.visibleViewDescriptors.map(v => v.id), ['view2']); + assert.deepStrictEqual(generatedViewContainerModel.allViewDescriptors.map(v => v.id), []); + }); + }); diff --git a/src/vs/workbench/services/workingCopy/common/workingCopyHistoryService.ts b/src/vs/workbench/services/workingCopy/common/workingCopyHistoryService.ts index 1e299593f87..a689d217c5e 100644 --- a/src/vs/workbench/services/workingCopy/common/workingCopyHistoryService.ts +++ b/src/vs/workbench/services/workingCopy/common/workingCopyHistoryService.ts @@ -4,23 +4,23 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { Emitter } from 'vs/base/common/event'; +import { Event, Emitter } from 'vs/base/common/event'; import { assertIsDefined } from 'vs/base/common/types'; 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 { ILifecycleService, LifecyclePhase, WillShutdownEvent } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { WorkingCopyHistoryTracker } from 'vs/workbench/services/workingCopy/common/workingCopyHistoryTracker'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWorkingCopyHistoryEntry, IWorkingCopyHistoryEntryDescriptor, IWorkingCopyHistoryEvent, IWorkingCopyHistoryService, MAX_PARALLEL_HISTORY_IO_OPS } from 'vs/workbench/services/workingCopy/common/workingCopyHistory'; import { FileOperationError, FileOperationResult, IFileService, IFileStatWithMetadata } from 'vs/platform/files/common/files'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { URI } from 'vs/base/common/uri'; -import { DeferredPromise, Limiter } from 'vs/base/common/async'; +import { DeferredPromise, Limiter, RunOnceScheduler } from 'vs/base/common/async'; import { dirname, extname, isEqual, joinPath } from 'vs/base/common/resources'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { hash } from 'vs/base/common/hash'; import { indexOfPath, randomPath } from 'vs/base/common/extpath'; -import { CancellationToken } from 'vs/base/common/cancellation'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { ResourceMap } from 'vs/base/common/map'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { ILabelService } from 'vs/platform/label/common/label'; @@ -786,5 +786,83 @@ export abstract class WorkingCopyHistoryService extends Disposable implements IW } +export class NativeWorkingCopyHistoryService extends WorkingCopyHistoryService { + + private static readonly STORE_ALL_INTERVAL = 5 * 60 * 1000; // 5min + + private readonly isRemotelyStored = typeof this.environmentService.remoteAuthority === 'string'; + + private readonly storeAllCts = this._register(new CancellationTokenSource()); + private readonly storeAllScheduler = this._register(new RunOnceScheduler(() => this.storeAll(this.storeAllCts.token), NativeWorkingCopyHistoryService.STORE_ALL_INTERVAL)); + + constructor( + @IFileService fileService: IFileService, + @IRemoteAgentService remoteAgentService: IRemoteAgentService, + @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, + @IUriIdentityService uriIdentityService: IUriIdentityService, + @ILabelService labelService: ILabelService, + @ILifecycleService private readonly lifecycleService: ILifecycleService, + @ILogService logService: ILogService, + @IConfigurationService configurationService: IConfigurationService + ) { + super(fileService, remoteAgentService, environmentService, uriIdentityService, labelService, logService, configurationService); + + this.registerListeners(); + } + + private registerListeners(): void { + if (!this.isRemotelyStored) { + + // Local: persist all on shutdown + this.lifecycleService.onWillShutdown(e => this.onWillShutdown(e)); + + // Local: schedule persist on change + this._register(Event.any(this.onDidAddEntry, this.onDidChangeEntry, this.onDidReplaceEntry, this.onDidRemoveEntry)(() => this.onDidChangeModels())); + } + } + + protected getModelOptions(): IWorkingCopyHistoryModelOptions { + return { flushOnChange: this.isRemotelyStored /* because the connection might drop anytime */ }; + } + + private onWillShutdown(e: WillShutdownEvent): void { + + // Dispose the scheduler... + this.storeAllScheduler.dispose(); + this.storeAllCts.dispose(true); + + // ...because we now explicitly store all models + e.join(this.storeAll(e.token), { id: 'join.workingCopyHistory', label: localize('join.workingCopyHistory', "Saving local history") }); + } + + private onDidChangeModels(): void { + if (!this.storeAllScheduler.isScheduled()) { + this.storeAllScheduler.schedule(); + } + } + + private async storeAll(token: CancellationToken): Promise { + const limiter = new Limiter(MAX_PARALLEL_HISTORY_IO_OPS); + const promises = []; + + const models = Array.from(this.models.values()); + for (const model of models) { + promises.push(limiter.queue(async () => { + if (token.isCancellationRequested) { + return; + } + + try { + await model.store(token); + } catch (error) { + this.logService.trace(error); + } + })); + } + + await Promise.all(promises); + } +} + // Register History Tracker Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(WorkingCopyHistoryTracker, LifecyclePhase.Restored); diff --git a/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupTracker.ts b/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupTracker.ts index 75929084dd7..6994989e01d 100644 --- a/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupTracker.ts +++ b/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupTracker.ts @@ -14,7 +14,7 @@ import { ConfirmResult, IFileDialogService, IDialogService, getFileNamesMessage import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { isMacintosh } from 'vs/base/common/platform'; import { HotExitConfiguration } from 'vs/platform/files/common/files'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { WorkingCopyBackupTracker } from 'vs/workbench/services/workingCopy/common/workingCopyBackupTracker'; import { ILogService } from 'vs/platform/log/common/log'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; diff --git a/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyHistoryService.ts b/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyHistoryService.ts index 173e036770e..adb216e83d3 100644 --- a/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyHistoryService.ts +++ b/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyHistoryService.ts @@ -3,99 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { localize } from 'vs/nls'; -import { Event } from 'vs/base/common/event'; -import { Limiter, RunOnceScheduler } from 'vs/base/common/async'; -import { ILifecycleService, WillShutdownEvent } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import { IFileService } from 'vs/platform/files/common/files'; -import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; -import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { ILabelService } from 'vs/platform/label/common/label'; -import { ILogService } from 'vs/platform/log/common/log'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IWorkingCopyHistoryModelOptions, WorkingCopyHistoryService } from 'vs/workbench/services/workingCopy/common/workingCopyHistoryService'; +import { NativeWorkingCopyHistoryService } from 'vs/workbench/services/workingCopy/common/workingCopyHistoryService'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IWorkingCopyHistoryService, MAX_PARALLEL_HISTORY_IO_OPS } from 'vs/workbench/services/workingCopy/common/workingCopyHistory'; -import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; - -export class NativeWorkingCopyHistoryService extends WorkingCopyHistoryService { - - private static readonly STORE_ALL_INTERVAL = 5 * 60 * 1000; // 5min - - private readonly isRemotelyStored = typeof this.environmentService.remoteAuthority === 'string'; - - private readonly storeAllCts = this._register(new CancellationTokenSource()); - private readonly storeAllScheduler = this._register(new RunOnceScheduler(() => this.storeAll(this.storeAllCts.token), NativeWorkingCopyHistoryService.STORE_ALL_INTERVAL)); - - constructor( - @IFileService fileService: IFileService, - @IRemoteAgentService remoteAgentService: IRemoteAgentService, - @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, - @IUriIdentityService uriIdentityService: IUriIdentityService, - @ILabelService labelService: ILabelService, - @ILifecycleService private readonly lifecycleService: ILifecycleService, - @ILogService logService: ILogService, - @IConfigurationService configurationService: IConfigurationService - ) { - super(fileService, remoteAgentService, environmentService, uriIdentityService, labelService, logService, configurationService); - - this.registerListeners(); - } - - private registerListeners(): void { - if (!this.isRemotelyStored) { - - // Local: persist all on shutdown - this.lifecycleService.onWillShutdown(e => this.onWillShutdown(e)); - - // Local: schedule persist on change - this._register(Event.any(this.onDidAddEntry, this.onDidChangeEntry, this.onDidReplaceEntry, this.onDidRemoveEntry)(() => this.onDidChangeModels())); - } - } - - protected getModelOptions(): IWorkingCopyHistoryModelOptions { - return { flushOnChange: this.isRemotelyStored /* because the connection might drop anytime */ }; - } - - private onWillShutdown(e: WillShutdownEvent): void { - - // Dispose the scheduler... - this.storeAllScheduler.dispose(); - this.storeAllCts.dispose(true); - - // ...because we now explicitly store all models - e.join(this.storeAll(e.token), { id: 'join.workingCopyHistory', label: localize('join.workingCopyHistory', "Saving local history") }); - } - - private onDidChangeModels(): void { - if (!this.storeAllScheduler.isScheduled()) { - this.storeAllScheduler.schedule(); - } - } - - private async storeAll(token: CancellationToken): Promise { - const limiter = new Limiter(MAX_PARALLEL_HISTORY_IO_OPS); - const promises = []; - - const models = Array.from(this.models.values()); - for (const model of models) { - promises.push(limiter.queue(async () => { - if (token.isCancellationRequested) { - return; - } - - try { - await model.store(token); - } catch (error) { - this.logService.trace(error); - } - })); - } - - await Promise.all(promises); - } -} +import { IWorkingCopyHistoryService } from 'vs/workbench/services/workingCopy/common/workingCopyHistory'; // Register Service registerSingleton(IWorkingCopyHistoryService, NativeWorkingCopyHistoryService, InstantiationType.Delayed); diff --git a/src/vs/workbench/services/workingCopy/test/electron-browser/fixtures/binary.txt b/src/vs/workbench/services/workingCopy/test/electron-browser/fixtures/binary.txt deleted file mode 100644 index fc30693d792..00000000000 Binary files a/src/vs/workbench/services/workingCopy/test/electron-browser/fixtures/binary.txt and /dev/null differ diff --git a/src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyBackupService.test.ts b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupService.test.ts similarity index 64% rename from src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyBackupService.test.ts rename to src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupService.test.ts index 5244db22ad4..d489f2d702b 100644 --- a/src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyBackupService.test.ts +++ b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupService.test.ts @@ -5,39 +5,74 @@ import * as assert from 'assert'; import { isWindows } from 'vs/base/common/platform'; -import { tmpdir } from 'os'; -import { createHash } from 'crypto'; import { insert } from 'vs/base/common/arrays'; import { hash } from 'vs/base/common/hash'; -import { isEqual } from 'vs/base/common/resources'; -import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs'; -import { dirname, join } from 'vs/base/common/path'; -import { Promises, readdirSync } from 'vs/base/node/pfs'; +import { isEqual, joinPath, dirname } from 'vs/base/common/resources'; +import { join } from 'vs/base/common/path'; import { URI } from 'vs/base/common/uri'; import { WorkingCopyBackupsModel, hashIdentifier } from 'vs/workbench/services/workingCopy/common/workingCopyBackupService'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; -import { flakySuite, getRandomTestPath } from 'vs/base/test/node/testUtils'; -import { FileAccess, Schemas } from 'vs/base/common/network'; +import { Schemas } from 'vs/base/common/network'; import { FileService } from 'vs/platform/files/common/fileService'; -import { NullLogService } from 'vs/platform/log/common/log'; -import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; +import { LogLevel, NullLogService } from 'vs/platform/log/common/log'; import { NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService'; import { toBufferOrReadable } from 'vs/workbench/services/textfile/common/textfiles'; import { IFileService } from 'vs/platform/files/common/files'; import { NativeWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupService'; import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider'; import { bufferToReadable, bufferToStream, streamToBuffer, VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer'; -import { TestNativeWindowConfiguration } from 'vs/workbench/test/electron-browser/workbenchTestServices'; import { TestLifecycleService, toTypedWorkingCopyId, toUntypedWorkingCopyId } from 'vs/workbench/test/browser/workbenchTestServices'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { IWorkingCopyBackupMeta, IWorkingCopyIdentifier } from 'vs/workbench/services/workingCopy/common/workingCopy'; import { consumeStream } from 'vs/base/common/stream'; import { TestProductService } from 'vs/workbench/test/common/workbenchTestServices'; +import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; +import { generateUuid } from 'vs/base/common/uuid'; +import { INativeWindowConfiguration } from 'vs/platform/window/common/window'; +import product from 'vs/platform/product/common/product'; -class TestWorkbenchEnvironmentService extends NativeWorkbenchEnvironmentService { +const homeDir = URI.file('home').with({ scheme: Schemas.inMemory }); +const tmpDir = URI.file('tmp').with({ scheme: Schemas.inMemory }); +const NULL_PROFILE = { + name: '', + id: '', + shortName: '', + isDefault: false, + location: homeDir, + settingsResource: joinPath(homeDir, 'settings.json'), + globalStorageHome: joinPath(homeDir, 'globalStorage'), + keybindingsResource: joinPath(homeDir, 'keybindings.json'), + tasksResource: joinPath(homeDir, 'tasks.json'), + snippetsHome: joinPath(homeDir, 'snippets'), + extensionsResource: joinPath(homeDir, 'extensions.json'), + cacheHome: joinPath(homeDir, 'cache') +}; - constructor(testDir: string, backupPath: string) { - super({ ...TestNativeWindowConfiguration, backupPath, 'user-data-dir': testDir }, TestProductService); +const TestNativeWindowConfiguration: INativeWindowConfiguration = { + windowId: 0, + machineId: 'testMachineId', + logLevel: LogLevel.Error, + loggers: { global: [], window: [] }, + mainPid: 0, + appRoot: '', + userEnv: {}, + execPath: process.execPath, + perfMarks: [], + colorScheme: { dark: true, highContrast: false }, + os: { release: 'unknown', hostname: 'unknown' }, + product, + homeDir: homeDir.fsPath, + tmpDir: tmpDir.fsPath, + userDataDir: joinPath(homeDir, product.nameShort).fsPath, + profiles: { profile: NULL_PROFILE, all: [NULL_PROFILE], home: homeDir }, + preferUtilityProcess: false, + _: [] +}; + +export class TestNativeWorkbenchEnvironmentService extends NativeWorkbenchEnvironmentService { + + constructor(testDir: URI, backupPath: URI) { + super({ ...TestNativeWindowConfiguration, backupPath: backupPath.fsPath, 'user-data-dir': testDir.fsPath }, TestProductService); } } @@ -48,18 +83,21 @@ export class NodeTestWorkingCopyBackupService extends NativeWorkingCopyBackupSer discardedBackups: IWorkingCopyIdentifier[]; discardedAllBackups: boolean; private pendingBackupsArr: Promise[]; - private diskFileSystemProvider: DiskFileSystemProvider; - constructor(testDir: string, workspaceBackupPath: string) { - const environmentService = new TestWorkbenchEnvironmentService(testDir, workspaceBackupPath); + readonly _fileService: IFileService; + + constructor(testDir: URI, workspaceBackupPath: URI) { + const environmentService = new TestNativeWorkbenchEnvironmentService(testDir, workspaceBackupPath); const logService = new NullLogService(); const fileService = new FileService(logService); const lifecycleService = new TestLifecycleService(); super(environmentService, fileService, logService, lifecycleService); - this.diskFileSystemProvider = new DiskFileSystemProvider(logService); - fileService.registerProvider(Schemas.file, this.diskFileSystemProvider); - fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, this.diskFileSystemProvider, Schemas.vscodeUserData, logService)); + const fsp = new InMemoryFileSystemProvider(); + fileService.registerProvider(Schemas.inMemory, fsp); + fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, fsp, Schemas.vscodeUserData, logService)); + + this._fileService = fileService; this.backupResourceJoiners = []; this.discardBackupJoiners = []; @@ -121,20 +159,17 @@ export class NodeTestWorkingCopyBackupService extends NativeWorkingCopyBackupSer return fileContents.value.toString(); } - - dispose() { - this.diskFileSystemProvider.dispose(); - } } -flakySuite('WorkingCopyBackupService', () => { +suite('WorkingCopyBackupService', () => { - let testDir: string; - let backupHome: string; - let workspacesJsonPath: string; - let workspaceBackupPath: string; + let testDir: URI; + let backupHome: URI; + let workspacesJsonPath: URI; + let workspaceBackupPath: URI; let service: NodeTestWorkingCopyBackupService; + let fileService: IFileService; const workspaceResource = URI.file(isWindows ? 'c:\\workspace' : '/workspace'); const fooFile = URI.file(isWindows ? 'c:\\Foo' : '/Foo'); @@ -145,21 +180,17 @@ flakySuite('WorkingCopyBackupService', () => { const untitledFile = URI.from({ scheme: Schemas.untitled, path: 'Untitled-1' }); setup(async () => { - testDir = getRandomTestPath(tmpdir(), 'vsctests', 'workingcopybackupservice'); - backupHome = join(testDir, 'Backups'); - workspacesJsonPath = join(backupHome, 'workspaces.json'); - workspaceBackupPath = join(backupHome, hash(workspaceResource.fsPath).toString(16)); + testDir = URI.file(join(generateUuid(), 'vsctests', 'workingcopybackupservice')).with({ scheme: Schemas.inMemory }); + backupHome = joinPath(testDir, 'Backups'); + workspacesJsonPath = joinPath(backupHome, 'workspaces.json'); + workspaceBackupPath = joinPath(backupHome, hash(workspaceResource.fsPath).toString(16)); service = new NodeTestWorkingCopyBackupService(testDir, workspaceBackupPath); + fileService = service._fileService; - await Promises.mkdir(backupHome, { recursive: true }); + await fileService.createFolder(backupHome); - return Promises.writeFile(workspacesJsonPath, ''); - }); - - teardown(() => { - service.dispose(); - return Promises.rm(testDir); + return fileService.writeFile(workspacesJsonPath, VSBuffer.fromString('')); }); suite('hashIdentifier', () => { @@ -276,13 +307,13 @@ flakySuite('WorkingCopyBackupService', () => { // No Type ID let backupId = toUntypedWorkingCopyId(backupResource); let filePathHash = hashIdentifier(backupId); - let expectedPath = URI.file(join(backupHome, workspaceHash, Schemas.file, filePathHash)).with({ scheme: Schemas.vscodeUserData }).toString(); + let expectedPath = joinPath(backupHome, workspaceHash, Schemas.file, filePathHash).with({ scheme: Schemas.vscodeUserData }).toString(); assert.strictEqual(service.toBackupResource(backupId).toString(), expectedPath); // With Type ID backupId = toTypedWorkingCopyId(backupResource); filePathHash = hashIdentifier(backupId); - expectedPath = URI.file(join(backupHome, workspaceHash, Schemas.file, filePathHash)).with({ scheme: Schemas.vscodeUserData }).toString(); + expectedPath = joinPath(backupHome, workspaceHash, Schemas.file, filePathHash).with({ scheme: Schemas.vscodeUserData }).toString(); assert.strictEqual(service.toBackupResource(backupId).toString(), expectedPath); }); @@ -295,13 +326,13 @@ flakySuite('WorkingCopyBackupService', () => { // No Type ID let backupId = toUntypedWorkingCopyId(backupResource); let filePathHash = hashIdentifier(backupId); - let expectedPath = URI.file(join(backupHome, workspaceHash, Schemas.untitled, filePathHash)).with({ scheme: Schemas.vscodeUserData }).toString(); + let expectedPath = joinPath(backupHome, workspaceHash, Schemas.untitled, filePathHash).with({ scheme: Schemas.vscodeUserData }).toString(); assert.strictEqual(service.toBackupResource(backupId).toString(), expectedPath); // With Type ID backupId = toTypedWorkingCopyId(backupResource); filePathHash = hashIdentifier(backupId); - expectedPath = URI.file(join(backupHome, workspaceHash, Schemas.untitled, filePathHash)).with({ scheme: Schemas.vscodeUserData }).toString(); + expectedPath = joinPath(backupHome, workspaceHash, Schemas.untitled, filePathHash).with({ scheme: Schemas.vscodeUserData }).toString(); assert.strictEqual(service.toBackupResource(backupId).toString(), expectedPath); }); @@ -314,13 +345,13 @@ flakySuite('WorkingCopyBackupService', () => { // No Type ID let backupId = toUntypedWorkingCopyId(backupResource); let filePathHash = hashIdentifier(backupId); - let expectedPath = URI.file(join(backupHome, workspaceHash, 'custom', filePathHash)).with({ scheme: Schemas.vscodeUserData }).toString(); + let expectedPath = joinPath(backupHome, workspaceHash, 'custom', filePathHash).with({ scheme: Schemas.vscodeUserData }).toString(); assert.strictEqual(service.toBackupResource(backupId).toString(), expectedPath); // With Type ID backupId = toTypedWorkingCopyId(backupResource); filePathHash = hashIdentifier(backupId); - expectedPath = URI.file(join(backupHome, workspaceHash, 'custom', filePathHash)).with({ scheme: Schemas.vscodeUserData }).toString(); + expectedPath = joinPath(backupHome, workspaceHash, 'custom', filePathHash).with({ scheme: Schemas.vscodeUserData }).toString(); assert.strictEqual(service.toBackupResource(backupId).toString(), expectedPath); }); }); @@ -342,111 +373,111 @@ flakySuite('WorkingCopyBackupService', () => { service.joinBackups().then(() => backupJoined = true); const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); const backupPromise = service.backup(identifier); assert.strictEqual(backupJoined, false); await backupPromise; assert.strictEqual(backupJoined, true); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier)); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier)); assert.ok(service.hasBackupSync(identifier)); }); test('no text', async () => { const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); await service.backup(identifier); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier)); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier)); assert.ok(service.hasBackupSync(identifier)); }); test('text file', async () => { const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); await service.backup(identifier, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier, 'test')); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier, 'test')); assert.ok(service.hasBackupSync(identifier)); }); test('text file (with version)', async () => { const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); await service.backup(identifier, bufferToReadable(VSBuffer.fromString('test')), 666); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier, 'test')); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier, 'test')); assert.ok(!service.hasBackupSync(identifier, 555)); assert.ok(service.hasBackupSync(identifier, 666)); }); test('text file (with meta)', async () => { const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); const meta = { etag: '678', orphaned: true }; await service.backup(identifier, bufferToReadable(VSBuffer.fromString('test')), undefined, meta); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier, 'test', meta)); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier, 'test', meta)); assert.ok(service.hasBackupSync(identifier)); }); test('text file with whitespace in name and type (with meta)', async () => { const fileWithSpace = URI.file(isWindows ? 'c:\\Foo \n Bar' : '/Foo \n Bar'); const identifier = toTypedWorkingCopyId(fileWithSpace, ' test id \n'); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); const meta = { etag: '678 \n k', orphaned: true }; await service.backup(identifier, bufferToReadable(VSBuffer.fromString('test')), undefined, meta); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier, 'test', meta)); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier, 'test', meta)); assert.ok(service.hasBackupSync(identifier)); }); test('text file with unicode character in name and type (with meta)', async () => { const fileWithUnicode = URI.file(isWindows ? 'c:\\soð’€…meà „' : '/soð’€…meà „'); const identifier = toTypedWorkingCopyId(fileWithUnicode, ' test soð’€…meà „ id \n'); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); const meta = { etag: '678soð’€…meà „', orphaned: true }; await service.backup(identifier, bufferToReadable(VSBuffer.fromString('test')), undefined, meta); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier, 'test', meta)); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier, 'test', meta)); assert.ok(service.hasBackupSync(identifier)); }); test('untitled file', async () => { const identifier = toUntypedWorkingCopyId(untitledFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); await service.backup(identifier, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier, 'test')); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'untitled'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier, 'test')); assert.ok(service.hasBackupSync(identifier)); }); test('text file (readable)', async () => { const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); const model = createTextModel('test'); await service.backup(identifier, toBufferOrReadable(model.createSnapshot())); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier, 'test')); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier, 'test')); assert.ok(service.hasBackupSync(identifier)); model.dispose(); @@ -454,13 +485,13 @@ flakySuite('WorkingCopyBackupService', () => { test('untitled file (readable)', async () => { const identifier = toUntypedWorkingCopyId(untitledFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); const model = createTextModel('test'); await service.backup(identifier, toBufferOrReadable(model.createSnapshot())); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier, 'test')); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'untitled'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier, 'test')); model.dispose(); }); @@ -482,25 +513,25 @@ flakySuite('WorkingCopyBackupService', () => { async function testLargeTextFile(largeString: string, buffer: VSBufferReadable | VSBufferReadableStream) { const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); await service.backup(identifier, buffer, undefined, { largeTest: true }); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier, largeString, { largeTest: true })); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier, largeString, { largeTest: true })); assert.ok(service.hasBackupSync(identifier)); } test('untitled file (large file, readable)', async () => { const identifier = toUntypedWorkingCopyId(untitledFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); const largeString = (new Array(30 * 1024)).join('Large String\n'); const model = createTextModel(largeString); await service.backup(identifier, toBufferOrReadable(model.createSnapshot())); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier, largeString)); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'untitled'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier, largeString)); assert.ok(service.hasBackupSync(identifier)); model.dispose(); @@ -508,20 +539,20 @@ flakySuite('WorkingCopyBackupService', () => { test('cancellation', async () => { const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); const cts = new CancellationTokenSource(); const promise = service.backup(identifier, undefined, undefined, undefined, cts.token); cts.cancel(); await promise; - assert.strictEqual(existsSync(backupPath), false); + assert.strictEqual((await fileService.exists(backupPath)), false); assert.ok(!service.hasBackupSync(identifier)); }); test('multiple', async () => { const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); await Promise.all([ service.backup(identifier), @@ -530,9 +561,9 @@ flakySuite('WorkingCopyBackupService', () => { service.backup(identifier) ]); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readFileSync(backupPath).toString(), toExpectedPreamble(identifier)); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.readFile(backupPath)).value.toString(), toExpectedPreamble(identifier)); assert.ok(service.hasBackupSync(identifier)); }); @@ -547,12 +578,12 @@ flakySuite('WorkingCopyBackupService', () => { service.backup(backupId3) ]); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 3); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 3); for (const backupId of [backupId1, backupId2, backupId3]) { - const fooBackupPath = join(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); - assert.strictEqual(existsSync(fooBackupPath), true); - assert.strictEqual(readFileSync(fooBackupPath).toString(), toExpectedPreamble(backupId)); + const fooBackupPath = joinPath(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); + assert.strictEqual((await fileService.exists(fooBackupPath)), true); + assert.strictEqual((await fileService.readFile(fooBackupPath)).value.toString(), toExpectedPreamble(backupId)); assert.ok(service.hasBackupSync(backupId)); } }); @@ -562,10 +593,10 @@ flakySuite('WorkingCopyBackupService', () => { test('joining', async () => { const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); await service.backup(identifier, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); assert.ok(service.hasBackupSync(identifier)); let backupJoined = false; @@ -576,35 +607,35 @@ flakySuite('WorkingCopyBackupService', () => { await discardBackupPromise; assert.strictEqual(backupJoined, true); - assert.strictEqual(existsSync(backupPath), false); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 0); + assert.strictEqual((await fileService.exists(backupPath)), false); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 0); assert.ok(!service.hasBackupSync(identifier)); }); test('text file', async () => { const identifier = toUntypedWorkingCopyId(fooFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); await service.backup(identifier, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); assert.ok(service.hasBackupSync(identifier)); await service.discardBackup(identifier); - assert.strictEqual(existsSync(backupPath), false); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 0); + assert.strictEqual((await fileService.exists(backupPath)), false); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 0); assert.ok(!service.hasBackupSync(identifier)); }); test('untitled file', async () => { const identifier = toUntypedWorkingCopyId(untitledFile); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); await service.backup(identifier, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'untitled'))).children?.length, 1); await service.discardBackup(identifier); - assert.strictEqual(existsSync(backupPath), false); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 0); + assert.strictEqual((await fileService.exists(backupPath)), false); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'untitled'))).children?.length, 0); }); test('multiple same resource, different type id', async () => { @@ -618,14 +649,14 @@ flakySuite('WorkingCopyBackupService', () => { service.backup(backupId3) ]); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 3); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 3); for (const backupId of [backupId1, backupId2, backupId3]) { - const backupPath = join(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); + const backupPath = joinPath(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); await service.discardBackup(backupId); - assert.strictEqual(existsSync(backupPath), false); + assert.strictEqual((await fileService.exists(backupPath)), false); } - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 0); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 0); }); }); @@ -636,39 +667,39 @@ flakySuite('WorkingCopyBackupService', () => { const backupId3 = toTypedWorkingCopyId(barFile); await service.backup(backupId1, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); await service.backup(backupId2, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 2); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 2); await service.backup(backupId3, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 3); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 3); await service.discardBackups(); for (const backupId of [backupId1, backupId2, backupId3]) { - const backupPath = join(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); - assert.strictEqual(existsSync(backupPath), false); + const backupPath = joinPath(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); + assert.strictEqual((await fileService.exists(backupPath)), false); } - assert.strictEqual(existsSync(join(workspaceBackupPath, 'file')), false); + assert.strictEqual((await fileService.exists(joinPath(workspaceBackupPath, 'file'))), false); }); test('untitled file', async () => { const backupId = toUntypedWorkingCopyId(untitledFile); - const backupPath = join(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); + const backupPath = joinPath(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); await service.backup(backupId, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'untitled'))).children?.length, 1); await service.discardBackups(); - assert.strictEqual(existsSync(backupPath), false); - assert.strictEqual(existsSync(join(workspaceBackupPath, 'untitled')), false); + assert.strictEqual((await fileService.exists(backupPath)), false); + assert.strictEqual((await fileService.exists(joinPath(workspaceBackupPath, 'untitled'))), false); }); test('can backup after discarding all', async () => { await service.discardBackups(); await service.backup(toUntypedWorkingCopyId(untitledFile), bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(existsSync(workspaceBackupPath), true); + assert.strictEqual((await fileService.exists(workspaceBackupPath)), true); }); }); @@ -679,43 +710,43 @@ flakySuite('WorkingCopyBackupService', () => { const backupId3 = toTypedWorkingCopyId(barFile); await service.backup(backupId1, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 1); await service.backup(backupId2, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 2); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 2); await service.backup(backupId3, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 3); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'file'))).children?.length, 3); await service.discardBackups({ except: [backupId2, backupId3] }); - let backupPath = join(workspaceBackupPath, backupId1.resource.scheme, hashIdentifier(backupId1)); - assert.strictEqual(existsSync(backupPath), false); + let backupPath = joinPath(workspaceBackupPath, backupId1.resource.scheme, hashIdentifier(backupId1)); + assert.strictEqual((await fileService.exists(backupPath)), false); - backupPath = join(workspaceBackupPath, backupId2.resource.scheme, hashIdentifier(backupId2)); - assert.strictEqual(existsSync(backupPath), true); + backupPath = joinPath(workspaceBackupPath, backupId2.resource.scheme, hashIdentifier(backupId2)); + assert.strictEqual((await fileService.exists(backupPath)), true); - backupPath = join(workspaceBackupPath, backupId3.resource.scheme, hashIdentifier(backupId3)); - assert.strictEqual(existsSync(backupPath), true); + backupPath = joinPath(workspaceBackupPath, backupId3.resource.scheme, hashIdentifier(backupId3)); + assert.strictEqual((await fileService.exists(backupPath)), true); await service.discardBackups({ except: [backupId1] }); for (const backupId of [backupId1, backupId2, backupId3]) { - const backupPath = join(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); - assert.strictEqual(existsSync(backupPath), false); + const backupPath = joinPath(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); + assert.strictEqual((await fileService.exists(backupPath)), false); } }); test('untitled file', async () => { const backupId = toUntypedWorkingCopyId(untitledFile); - const backupPath = join(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); + const backupPath = joinPath(workspaceBackupPath, backupId.resource.scheme, hashIdentifier(backupId)); await service.backup(backupId, bufferToReadable(VSBuffer.fromString('test'))); - assert.strictEqual(existsSync(backupPath), true); - assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1); + assert.strictEqual((await fileService.exists(backupPath)), true); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, 'untitled'))).children?.length, 1); await service.discardBackups({ except: [backupId] }); - assert.strictEqual(existsSync(backupPath), true); + assert.strictEqual((await fileService.exists(backupPath)), true); }); }); @@ -1015,14 +1046,14 @@ flakySuite('WorkingCopyBackupService', () => { await service.backup(identifier, bufferToReadable(VSBuffer.fromString(contents)), 1, meta); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); - const fileContents = readFileSync(backupPath).toString(); + const fileContents = (await fileService.readFile(backupPath)).value.toString(); assert.strictEqual(fileContents.indexOf(identifier.resource.toString()), 0); const metaIndex = fileContents.indexOf('{'); const newFileContents = fileContents.substring(0, metaIndex) + '{{' + fileContents.substr(metaIndex); - writeFileSync(backupPath, newFileContents); + await fileService.writeFile(backupPath, VSBuffer.fromString(newFileContents)); const backup = await service.resolve(identifier); assert.ok(backup); @@ -1052,7 +1083,7 @@ flakySuite('WorkingCopyBackupService', () => { await service.backup(identifier, bufferToReadable(VSBuffer.fromString(contents)), 1, meta); - const backupPath = join(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); + const backupPath = joinPath(workspaceBackupPath, identifier.resource.scheme, hashIdentifier(identifier)); // Simulate the condition of the backups model loading initially without // meta data information and then getting the meta data updated on the @@ -1062,15 +1093,15 @@ flakySuite('WorkingCopyBackupService', () => { // This is not really something that would happen in real life because any // backup that is made via backup service will update the model accordingly. - const originalFileContents = readFileSync(backupPath).toString(); - writeFileSync(backupPath, originalFileContents.replace(meta.etag, updatedMeta.etag)); + const originalFileContents = (await fileService.readFile(backupPath)).value.toString(); + await fileService.writeFile(backupPath, VSBuffer.fromString(originalFileContents.replace(meta.etag, updatedMeta.etag))); await service.resolve(identifier); assert.strictEqual(service.hasBackupSync(identifier, undefined, meta), false); assert.strictEqual(service.hasBackupSync(identifier, undefined, updatedMeta), true); - writeFileSync(backupPath, originalFileContents); + await fileService.writeFile(backupPath, VSBuffer.fromString(originalFileContents)); await service.getBackups(); @@ -1109,10 +1140,9 @@ flakySuite('WorkingCopyBackupService', () => { test('file with binary data', async () => { const identifier = toUntypedWorkingCopyId(fooFile); - const sourceDir = FileAccess.asFileUri('vs/workbench/services/workingCopy/test/electron-browser/fixtures').fsPath; - - const buffer = await Promises.readFile(join(sourceDir, 'binary.txt')); - const hash = createHash('md5').update(buffer).digest('base64'); + const buffer = Uint8Array.from([ + 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 73, 0, 0, 0, 67, 8, 2, 0, 0, 0, 95, 138, 191, 237, 0, 0, 0, 1, 115, 82, 71, 66, 0, 174, 206, 28, 233, 0, 0, 0, 4, 103, 65, 77, 65, 0, 0, 177, 143, 11, 252, 97, 5, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 14, 195, 0, 0, 14, 195, 1, 199, 111, 168, 100, 0, 0, 0, 71, 116, 69, 88, 116, 83, 111, 117, 114, 99, 101, 0, 83, 104, 111, 116, 116, 121, 32, 118, 50, 46, 48, 46, 50, 46, 50, 49, 54, 32, 40, 67, 41, 32, 84, 104, 111, 109, 97, 115, 32, 66, 97, 117, 109, 97, 110, 110, 32, 45, 32, 104, 116, 116, 112, 58, 47, 47, 115, 104, 111, 116, 116, 121, 46, 100, 101, 118, 115, 45, 111, 110, 46, 110, 101, 116, 44, 132, 21, 213, 0, 0, 0, 84, 73, 68, 65, 84, 120, 218, 237, 207, 65, 17, 0, 0, 12, 2, 32, 211, 217, 63, 146, 37, 246, 218, 65, 3, 210, 191, 226, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 118, 100, 169, 4, 173, 8, 44, 248, 184, 40, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 + ]); await service.backup(identifier, bufferToReadable(VSBuffer.wrap(buffer)), undefined, { binaryTest: 'true' }); @@ -1121,17 +1151,13 @@ flakySuite('WorkingCopyBackupService', () => { const backupBuffer = await consumeStream(backup.value, chunks => VSBuffer.concat(chunks)); assert.strictEqual(backupBuffer.buffer.byteLength, buffer.byteLength); - - const backupHash = createHash('md5').update(backupBuffer.buffer).digest('base64'); - - assert.strictEqual(hash, backupHash); }); }); suite('WorkingCopyBackupsModel', () => { test('simple', async () => { - const model = await WorkingCopyBackupsModel.create(URI.file(workspaceBackupPath), service.testGetFileService()); + const model = await WorkingCopyBackupsModel.create(workspaceBackupPath, service.testGetFileService()); const resource1 = URI.file('test.html'); @@ -1195,16 +1221,16 @@ flakySuite('WorkingCopyBackupService', () => { }); test('create', async () => { - const fooBackupPath = join(workspaceBackupPath, fooFile.scheme, hashIdentifier(toUntypedWorkingCopyId(fooFile))); - await Promises.mkdir(dirname(fooBackupPath), { recursive: true }); - writeFileSync(fooBackupPath, 'foo'); - const model = await WorkingCopyBackupsModel.create(URI.file(workspaceBackupPath), service.testGetFileService()); + const fooBackupPath = joinPath(workspaceBackupPath, fooFile.scheme, hashIdentifier(toUntypedWorkingCopyId(fooFile))); + await fileService.createFolder(dirname(fooBackupPath)); + await fileService.writeFile(fooBackupPath, VSBuffer.fromString('foo')); + const model = await WorkingCopyBackupsModel.create(workspaceBackupPath, service.testGetFileService()); - assert.strictEqual(model.has(URI.file(fooBackupPath)), true); + assert.strictEqual(model.has(fooBackupPath), true); }); test('get', async () => { - const model = await WorkingCopyBackupsModel.create(URI.file(workspaceBackupPath), service.testGetFileService()); + const model = await WorkingCopyBackupsModel.create(workspaceBackupPath, service.testGetFileService()); assert.deepStrictEqual(model.get(), []); @@ -1227,19 +1253,19 @@ flakySuite('WorkingCopyBackupService', () => { const untitledBackupId = toUntypedWorkingCopyId(untitledFile); const customBackupId = toUntypedWorkingCopyId(customFile); - const fooBackupPath = join(workspaceBackupPath, fooFile.scheme, hashIdentifier(fooBackupId)); - const untitledBackupPath = join(workspaceBackupPath, untitledFile.scheme, hashIdentifier(untitledBackupId)); - const customFileBackupPath = join(workspaceBackupPath, customFile.scheme, hashIdentifier(customBackupId)); + const fooBackupPath = joinPath(workspaceBackupPath, fooFile.scheme, hashIdentifier(fooBackupId)); + const untitledBackupPath = joinPath(workspaceBackupPath, untitledFile.scheme, hashIdentifier(untitledBackupId)); + const customFileBackupPath = joinPath(workspaceBackupPath, customFile.scheme, hashIdentifier(customBackupId)); // Prepare backups of the old MD5 hash format - mkdirSync(join(workspaceBackupPath, fooFile.scheme), { recursive: true }); - mkdirSync(join(workspaceBackupPath, untitledFile.scheme), { recursive: true }); - mkdirSync(join(workspaceBackupPath, customFile.scheme), { recursive: true }); - writeFileSync(join(workspaceBackupPath, fooFile.scheme, '8a8589a2f1c9444b89add38166f50229'), `${fooFile.toString()}\ntest file`); - writeFileSync(join(workspaceBackupPath, untitledFile.scheme, '13264068d108c6901b3592ea654fcd57'), `${untitledFile.toString()}\ntest untitled`); - writeFileSync(join(workspaceBackupPath, customFile.scheme, 'bf018572af7b38746b502893bd0adf6c'), `${customFile.toString()}\ntest custom`); + await fileService.createFolder(joinPath(workspaceBackupPath, fooFile.scheme)); + await fileService.createFolder(joinPath(workspaceBackupPath, untitledFile.scheme)); + await fileService.createFolder(joinPath(workspaceBackupPath, customFile.scheme)); + await fileService.writeFile(joinPath(workspaceBackupPath, fooFile.scheme, '8a8589a2f1c9444b89add38166f50229'), VSBuffer.fromString(`${fooFile.toString()}\ntest file`)); + await fileService.writeFile(joinPath(workspaceBackupPath, untitledFile.scheme, '13264068d108c6901b3592ea654fcd57'), VSBuffer.fromString(`${untitledFile.toString()}\ntest untitled`)); + await fileService.writeFile(joinPath(workspaceBackupPath, customFile.scheme, 'bf018572af7b38746b502893bd0adf6c'), VSBuffer.fromString(`${customFile.toString()}\ntest custom`)); - service.reinitialize(URI.file(workspaceBackupPath)); + service.reinitialize(workspaceBackupPath); const backups = await service.getBackups(); assert.strictEqual(backups.length, 3); @@ -1247,19 +1273,19 @@ flakySuite('WorkingCopyBackupService', () => { assert.ok(backups.some(backup => isEqual(backup.resource, untitledFile))); assert.ok(backups.some(backup => isEqual(backup.resource, customFile))); - assert.strictEqual(readdirSync(join(workspaceBackupPath, fooFile.scheme)).length, 1); - assert.strictEqual(existsSync(fooBackupPath), true); - assert.strictEqual(readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\ntest file`); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, fooFile.scheme))).children?.length, 1); + assert.strictEqual((await fileService.exists(fooBackupPath)), true); + assert.strictEqual((await fileService.readFile(fooBackupPath)).value.toString(), `${fooFile.toString()}\ntest file`); assert.ok(service.hasBackupSync(fooBackupId)); - assert.strictEqual(readdirSync(join(workspaceBackupPath, untitledFile.scheme)).length, 1); - assert.strictEqual(existsSync(untitledBackupPath), true); - assert.strictEqual(readFileSync(untitledBackupPath).toString(), `${untitledFile.toString()}\ntest untitled`); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, untitledFile.scheme))).children?.length, 1); + assert.strictEqual((await fileService.exists(untitledBackupPath)), true); + assert.strictEqual((await fileService.readFile(untitledBackupPath)).value.toString(), `${untitledFile.toString()}\ntest untitled`); assert.ok(service.hasBackupSync(untitledBackupId)); - assert.strictEqual(readdirSync(join(workspaceBackupPath, customFile.scheme)).length, 1); - assert.strictEqual(existsSync(customFileBackupPath), true); - assert.strictEqual(readFileSync(customFileBackupPath).toString(), `${customFile.toString()}\ntest custom`); + assert.strictEqual((await fileService.resolve(joinPath(workspaceBackupPath, customFile.scheme))).children?.length, 1); + assert.strictEqual((await fileService.exists(customFileBackupPath)), true); + assert.strictEqual((await fileService.readFile(customFileBackupPath)).value.toString(), `${customFile.toString()}\ntest custom`); assert.ok(service.hasBackupSync(customBackupId)); }); }); @@ -1271,19 +1297,19 @@ flakySuite('WorkingCopyBackupService', () => { const untitledBackupId = toUntypedWorkingCopyId(untitledFile); const customBackupId = toUntypedWorkingCopyId(customFile); - const fooBackupPath = join(workspaceBackupPath, fooFile.scheme, hashIdentifier(fooBackupId)); - const untitledBackupPath = join(workspaceBackupPath, untitledFile.scheme, hashIdentifier(untitledBackupId)); - const customFileBackupPath = join(workspaceBackupPath, customFile.scheme, hashIdentifier(customBackupId)); + const fooBackupPath = joinPath(workspaceBackupPath, fooFile.scheme, hashIdentifier(fooBackupId)); + const untitledBackupPath = joinPath(workspaceBackupPath, untitledFile.scheme, hashIdentifier(untitledBackupId)); + const customFileBackupPath = joinPath(workspaceBackupPath, customFile.scheme, hashIdentifier(customBackupId)); // Prepare backups of the old format without meta - mkdirSync(join(workspaceBackupPath, fooFile.scheme), { recursive: true }); - mkdirSync(join(workspaceBackupPath, untitledFile.scheme), { recursive: true }); - mkdirSync(join(workspaceBackupPath, customFile.scheme), { recursive: true }); - writeFileSync(fooBackupPath, `${fooFile.toString()}\ntest file`); - writeFileSync(untitledBackupPath, `${untitledFile.toString()}\ntest untitled`); - writeFileSync(customFileBackupPath, `${customFile.toString()}\ntest custom`); + await fileService.createFolder(joinPath(workspaceBackupPath, fooFile.scheme)); + await fileService.createFolder(joinPath(workspaceBackupPath, untitledFile.scheme)); + await fileService.createFolder(joinPath(workspaceBackupPath, customFile.scheme)); + await fileService.writeFile(fooBackupPath, VSBuffer.fromString(`${fooFile.toString()}\ntest file`)); + await fileService.writeFile(untitledBackupPath, VSBuffer.fromString(`${untitledFile.toString()}\ntest untitled`)); + await fileService.writeFile(customFileBackupPath, VSBuffer.fromString(`${customFile.toString()}\ntest custom`)); - service.reinitialize(URI.file(workspaceBackupPath)); + service.reinitialize(workspaceBackupPath); const backups = await service.getBackups(); assert.strictEqual(backups.length, 3); @@ -1298,19 +1324,19 @@ flakySuite('WorkingCopyBackupService', () => { const untitledBackupId = toUntypedWorkingCopyId(untitledFile); const customBackupId = toUntypedWorkingCopyId(customFile); - const fooBackupPath = join(workspaceBackupPath, fooFile.scheme, hashIdentifier(fooBackupId)); - const untitledBackupPath = join(workspaceBackupPath, untitledFile.scheme, hashIdentifier(untitledBackupId)); - const customFileBackupPath = join(workspaceBackupPath, customFile.scheme, hashIdentifier(customBackupId)); + const fooBackupPath = joinPath(workspaceBackupPath, fooFile.scheme, hashIdentifier(fooBackupId)); + const untitledBackupPath = joinPath(workspaceBackupPath, untitledFile.scheme, hashIdentifier(untitledBackupId)); + const customFileBackupPath = joinPath(workspaceBackupPath, customFile.scheme, hashIdentifier(customBackupId)); // Prepare backups of the old format without meta - mkdirSync(join(workspaceBackupPath, fooFile.scheme), { recursive: true }); - mkdirSync(join(workspaceBackupPath, untitledFile.scheme), { recursive: true }); - mkdirSync(join(workspaceBackupPath, customFile.scheme), { recursive: true }); - writeFileSync(fooBackupPath, `${fooFile.toString()} ${JSON.stringify({ foo: 'bar' })}\ntest file`); - writeFileSync(untitledBackupPath, `${untitledFile.toString()} ${JSON.stringify({ foo: 'bar' })}\ntest untitled`); - writeFileSync(customFileBackupPath, `${customFile.toString()} ${JSON.stringify({ foo: 'bar' })}\ntest custom`); + await fileService.createFolder(joinPath(workspaceBackupPath, fooFile.scheme)); + await fileService.createFolder(joinPath(workspaceBackupPath, untitledFile.scheme)); + await fileService.createFolder(joinPath(workspaceBackupPath, customFile.scheme)); + await fileService.writeFile(fooBackupPath, VSBuffer.fromString(`${fooFile.toString()} ${JSON.stringify({ foo: 'bar' })}\ntest file`)); + await fileService.writeFile(untitledBackupPath, VSBuffer.fromString(`${untitledFile.toString()} ${JSON.stringify({ foo: 'bar' })}\ntest untitled`)); + await fileService.writeFile(customFileBackupPath, VSBuffer.fromString(`${customFile.toString()} ${JSON.stringify({ foo: 'bar' })}\ntest custom`)); - service.reinitialize(URI.file(workspaceBackupPath)); + service.reinitialize(workspaceBackupPath); const backups = await service.getBackups(); assert.strictEqual(backups.length, 3); diff --git a/src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyBackupTracker.test.ts b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts similarity index 93% rename from src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyBackupTracker.test.ts rename to src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts index 69e18ce3ace..cc06170e83e 100644 --- a/src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyBackupTracker.test.ts +++ b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyBackupTracker.test.ts @@ -5,11 +5,8 @@ import * as assert from 'assert'; import { isMacintosh, isWindows } from 'vs/base/common/platform'; -import { tmpdir } from 'os'; import { join } from 'vs/base/common/path'; -import { Promises } from 'vs/base/node/pfs'; import { URI } from 'vs/base/common/uri'; -import { flakySuite, getRandomTestPath } from 'vs/base/test/node/testUtils'; import { hash } from 'vs/base/common/hash'; import { NativeWorkingCopyBackupTracker } from 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupTracker'; import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager'; @@ -18,7 +15,6 @@ import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { EditorService } from 'vs/workbench/services/editor/browser/editorService'; import { IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackup'; -import { NodeTestWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/test/electron-browser/workingCopyBackupService.test'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { toResource } from 'vs/base/test/common/utils'; import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; @@ -28,8 +24,7 @@ import { HotExitConfiguration } from 'vs/platform/files/common/files'; import { ShutdownReason, ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { IFileDialogService, ConfirmResult, IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; -import { workbenchInstantiationService, TestServiceAccessor } from 'vs/workbench/test/electron-browser/workbenchTestServices'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -44,8 +39,13 @@ import { TestContextService, TestWorkingCopy } from 'vs/workbench/test/common/wo import { CancellationToken } from 'vs/base/common/cancellation'; import { IWorkingCopyBackup } from 'vs/workbench/services/workingCopy/common/workingCopy'; import { Event, Emitter } from 'vs/base/common/event'; +import { generateUuid } from 'vs/base/common/uuid'; +import { Schemas } from 'vs/base/common/network'; +import { joinPath } from 'vs/base/common/resources'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/electron-sandbox/workbenchTestServices'; -flakySuite('WorkingCopyBackupTracker (native)', function () { +suite('WorkingCopyBackupTracker (native)', function () { class TestWorkingCopyBackupTracker extends NativeWorkingCopyBackupTracker { @@ -107,9 +107,9 @@ flakySuite('WorkingCopyBackupTracker (native)', function () { } } - let testDir: string; - let backupHome: string; - let workspaceBackupPath: string; + let testDir: URI; + let backupHome: URI; + let workspaceBackupPath: URI; let accessor: TestServiceAccessor; let disposables: DisposableStore; @@ -117,35 +117,31 @@ flakySuite('WorkingCopyBackupTracker (native)', function () { setup(async () => { disposables = new DisposableStore(); - testDir = getRandomTestPath(tmpdir(), 'vsctests', 'backuprestorer'); - backupHome = join(testDir, 'Backups'); - const workspacesJsonPath = join(backupHome, 'workspaces.json'); + testDir = URI.file(join(generateUuid(), 'vsctests', 'workingcopybackuptracker')).with({ scheme: Schemas.inMemory }); + backupHome = joinPath(testDir, 'Backups'); + const workspacesJsonPath = joinPath(backupHome, 'workspaces.json'); - const workspaceResource = URI.file(isWindows ? 'c:\\workspace' : '/workspace'); - workspaceBackupPath = join(backupHome, hash(workspaceResource.fsPath).toString(16)); + const workspaceResource = URI.file(isWindows ? 'c:\\workspace' : '/workspace').with({ scheme: Schemas.inMemory }); + workspaceBackupPath = joinPath(backupHome, hash(workspaceResource.toString()).toString(16)); - const instantiationService = workbenchInstantiationService(disposables); + const instantiationService = workbenchInstantiationService(undefined, disposables); accessor = instantiationService.createInstance(TestServiceAccessor); disposables.add((accessor.textFileService.files)); disposables.add(registerTestFileEditor()); - await Promises.mkdir(backupHome, { recursive: true }); - await Promises.mkdir(workspaceBackupPath, { recursive: true }); + await accessor.fileService.createFolder(backupHome); + await accessor.fileService.createFolder(workspaceBackupPath); - return Promises.writeFile(workspacesJsonPath, ''); + return accessor.fileService.writeFile(workspacesJsonPath, VSBuffer.fromString('')); }); teardown(async () => { disposables.dispose(); - - return Promises.rm(testDir); }); async function createTracker(autoSaveEnabled = false): Promise<{ accessor: TestServiceAccessor; part: EditorPart; tracker: TestWorkingCopyBackupTracker; instantiationService: IInstantiationService; cleanup: () => Promise }> { - const workingCopyBackupService = new NodeTestWorkingCopyBackupService(testDir, workspaceBackupPath); - const instantiationService = workbenchInstantiationService(disposables); - instantiationService.stub(IWorkingCopyBackupService, workingCopyBackupService); + const instantiationService = workbenchInstantiationService(undefined, disposables); const configurationService = new TestConfigurationService(); if (autoSaveEnabled) { @@ -319,7 +315,7 @@ flakySuite('WorkingCopyBackupTracker (native)', function () { const veto = await event.value; assert.ok(!veto); - assert.ok(!accessor.workingCopyBackupService.discardedAllBackups); + assert.ok(accessor.workingCopyBackupService.discardedAllBackups); await cleanup(); }); diff --git a/src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyHistoryService.test.ts b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryService.test.ts similarity index 79% rename from src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyHistoryService.test.ts rename to src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryService.test.ts index 169bbdfc8bf..9d9094116bc 100644 --- a/src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyHistoryService.test.ts +++ b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryService.test.ts @@ -4,40 +4,25 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService'; -import { TestNativePathService, TestNativeWindowConfiguration } from 'vs/workbench/test/electron-browser/workbenchTestServices'; -import { TestContextService, TestProductService, TestStorageService, TestWorkingCopy } from 'vs/workbench/test/common/workbenchTestServices'; +import { TestContextService, TestStorageService, TestWorkingCopy } from 'vs/workbench/test/common/workbenchTestServices'; import { NullLogService } from 'vs/platform/log/common/log'; import { FileService } from 'vs/platform/files/common/fileService'; -import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; import { Schemas } from 'vs/base/common/network'; -import { flakySuite, getRandomTestPath } from 'vs/base/test/node/testUtils'; -import { tmpdir } from 'os'; -import { dirname, join } from 'vs/base/common/path'; -import { Promises } from 'vs/base/node/pfs'; import { URI } from 'vs/base/common/uri'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; -import { existsSync, readFileSync, unlinkSync } from 'fs'; import { IWorkingCopyHistoryEntry, IWorkingCopyHistoryEntryDescriptor, IWorkingCopyHistoryEvent } from 'vs/workbench/services/workingCopy/common/workingCopyHistory'; import { IFileService } from 'vs/platform/files/common/files'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { LabelService } from 'vs/workbench/services/label/common/labelService'; -import { TestLifecycleService, TestRemoteAgentService, TestWillShutdownEvent } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEnvironmentService, TestLifecycleService, TestPathService, TestRemoteAgentService, TestWillShutdownEvent } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; -import { NativeWorkingCopyHistoryService } from 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyHistoryService'; -import { joinPath, dirname as resourcesDirname, basename } from 'vs/base/common/resources'; +import { NativeWorkingCopyHistoryService } from 'vs/workbench/services/workingCopy/common/workingCopyHistoryService'; +import { joinPath, dirname, basename } from 'vs/base/common/resources'; import { firstOrDefault } from 'vs/base/common/arrays'; - -class TestWorkbenchEnvironmentService extends NativeWorkbenchEnvironmentService { - - constructor(private readonly testDir: URI | string) { - super({ ...TestNativeWindowConfiguration, 'user-data-dir': URI.isUri(testDir) ? testDir.fsPath : testDir }, TestProductService); - } - - override get localHistoryHome() { - return joinPath(URI.isUri(this.testDir) ? this.testDir : URI.file(this.testDir), 'History'); - } -} +import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; +import { generateUuid } from 'vs/base/common/uuid'; +import { join } from 'vs/base/common/path'; +import { VSBuffer } from 'vs/base/common/buffer'; export class TestWorkingCopyHistoryService extends NativeWorkingCopyHistoryService { @@ -45,19 +30,21 @@ export class TestWorkingCopyHistoryService extends NativeWorkingCopyHistoryServi readonly _configurationService: TestConfigurationService; readonly _lifecycleService: TestLifecycleService; - constructor(testDir: URI | string) { - const environmentService = new TestWorkbenchEnvironmentService(testDir); + constructor(fileService?: IFileService) { + const environmentService = TestEnvironmentService; const logService = new NullLogService(); - const fileService = new FileService(logService); - const diskFileSystemProvider = new DiskFileSystemProvider(logService); - fileService.registerProvider(Schemas.file, diskFileSystemProvider); + if (!fileService) { + fileService = new FileService(logService); + fileService.registerProvider(Schemas.inMemory, new InMemoryFileSystemProvider()); + fileService.registerProvider(Schemas.vscodeUserData, new InMemoryFileSystemProvider()); + } const remoteAgentService = new TestRemoteAgentService(); const uriIdentityService = new UriIdentityService(fileService); - const labelService = new LabelService(environmentService, new TestContextService(), new TestNativePathService(), new TestRemoteAgentService(), new TestStorageService(), new TestLifecycleService()); + const labelService = new LabelService(environmentService, new TestContextService(), new TestPathService(), new TestRemoteAgentService(), new TestStorageService(), new TestLifecycleService()); const lifecycleService = new TestLifecycleService(); @@ -71,16 +58,17 @@ export class TestWorkingCopyHistoryService extends NativeWorkingCopyHistoryServi } } -flakySuite('WorkingCopyHistoryService', () => { +suite('WorkingCopyHistoryService', () => { - let testDir: string; - let historyHome: string; - let workHome: string; + let testDir: URI; + let historyHome: URI; + let workHome: URI; let service: TestWorkingCopyHistoryService; + let fileService: IFileService; - let testFile1Path: string; - let testFile2Path: string; - let testFile3Path: string; + let testFile1Path: URI; + let testFile2Path: URI; + let testFile3Path: URI; const testFile1PathContents = 'Hello Foo'; const testFile2PathContents = [ @@ -92,22 +80,23 @@ flakySuite('WorkingCopyHistoryService', () => { const testFile3PathContents = 'Hello Bar'; setup(async () => { - testDir = getRandomTestPath(tmpdir(), 'vsctests', 'workingcopyhistoryservice'); - historyHome = join(testDir, 'User', 'History'); - workHome = join(testDir, 'work'); + testDir = URI.file(join(generateUuid(), 'vsctests', 'workingcopyhistoryservice')).with({ scheme: Schemas.inMemory }); + historyHome = joinPath(testDir, 'User', 'History'); + workHome = joinPath(testDir, 'work'); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(); + fileService = service._fileService; - await Promises.mkdir(historyHome, { recursive: true }); - await Promises.mkdir(workHome, { recursive: true }); + await fileService.createFolder(historyHome); + await fileService.createFolder(workHome); - testFile1Path = join(workHome, 'foo.txt'); - testFile2Path = join(workHome, 'bar.txt'); - testFile3Path = join(workHome, 'foo-bar.txt'); + testFile1Path = joinPath(workHome, 'foo.txt'); + testFile2Path = joinPath(workHome, 'bar.txt'); + testFile3Path = joinPath(workHome, 'foo-bar.txt'); - await Promises.writeFile(testFile1Path, testFile1PathContents); - await Promises.writeFile(testFile2Path, testFile2PathContents); - await Promises.writeFile(testFile3Path, testFile3PathContents); + await fileService.writeFile(testFile1Path, VSBuffer.fromString(testFile1PathContents)); + await fileService.writeFile(testFile2Path, VSBuffer.fromString(testFile2PathContents)); + await fileService.writeFile(testFile3Path, VSBuffer.fromString(testFile3PathContents)); }); let increasingTimestampCounter = 1; @@ -122,7 +111,7 @@ flakySuite('WorkingCopyHistoryService', () => { if (expectEntryAdded) { assert.ok(entry, 'Unexpected undefined local history entry'); - assert.strictEqual(existsSync(entry.location.fsPath), true, 'Unexpected local history not stored on disk'); + assert.strictEqual((await fileService.exists(entry.location)), true, 'Unexpected local history not stored'); } return entry; @@ -130,24 +119,22 @@ flakySuite('WorkingCopyHistoryService', () => { teardown(() => { service.dispose(); - - return Promises.rm(testDir); }); test('addEntry', async () => { const addEvents: IWorkingCopyHistoryEvent[] = []; service.onDidAddEntry(e => addEvents.push(e)); - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); - const workingCopy2 = new TestWorkingCopy(URI.file(testFile2Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); + const workingCopy2 = new TestWorkingCopy(testFile2Path); // Add Entry works const entry1A = await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); const entry2A = await addEntry({ resource: workingCopy2.resource, source: 'My Source' }, CancellationToken.None); - assert.strictEqual(readFileSync(entry1A.location.fsPath).toString(), testFile1PathContents); - assert.strictEqual(readFileSync(entry2A.location.fsPath).toString(), testFile2PathContents); + assert.strictEqual((await fileService.readFile(entry1A.location)).value.toString(), testFile1PathContents); + assert.strictEqual((await fileService.readFile(entry2A.location)).value.toString(), testFile2PathContents); assert.strictEqual(addEvents.length, 2); assert.strictEqual(addEvents[0].entry.workingCopy.resource.toString(), workingCopy1.resource.toString()); @@ -157,8 +144,8 @@ flakySuite('WorkingCopyHistoryService', () => { const entry1B = await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); const entry2B = await addEntry({ resource: workingCopy2.resource }, CancellationToken.None); - assert.strictEqual(readFileSync(entry1B.location.fsPath).toString(), testFile1PathContents); - assert.strictEqual(readFileSync(entry2B.location.fsPath).toString(), testFile2PathContents); + assert.strictEqual((await fileService.readFile(entry1B.location)).value.toString(), testFile1PathContents); + assert.strictEqual((await fileService.readFile(entry2B.location)).value.toString(), testFile2PathContents); assert.strictEqual(addEvents.length, 4); assert.strictEqual(addEvents[2].entry.workingCopy.resource.toString(), workingCopy1.resource.toString()); @@ -177,7 +164,7 @@ flakySuite('WorkingCopyHistoryService', () => { // Invalid working copies are ignored - const workingCopy3 = new TestWorkingCopy(URI.file(testFile2Path).with({ scheme: 'unsupported' })); + const workingCopy3 = new TestWorkingCopy(testFile2Path.with({ scheme: 'unsupported' })); const entry3A = await addEntry({ resource: workingCopy3.resource }, CancellationToken.None, false); assert.ok(!entry3A); @@ -188,7 +175,7 @@ flakySuite('WorkingCopyHistoryService', () => { const changeEvents: IWorkingCopyHistoryEvent[] = []; service.onDidChangeEntry(e => changeEvents.push(e)); - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); const entry = await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); @@ -210,10 +197,10 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); entries = await service.getEntries(workingCopy1.resource, CancellationToken.None); assert.strictEqual(entries.length, 3); @@ -224,7 +211,7 @@ flakySuite('WorkingCopyHistoryService', () => { const removeEvents: IWorkingCopyHistoryEvent[] = []; service.onDidRemoveEntry(e => removeEvents.push(e)); - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); const entry2 = await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); @@ -252,17 +239,17 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); entries = await service.getEntries(workingCopy1.resource, CancellationToken.None); assert.strictEqual(entries.length, 3); }); test('removeEntry - deletes history entries folder when last entry removed', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); let entry = await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); @@ -271,12 +258,12 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); - assert.strictEqual(existsSync(dirname(entry.location.fsPath)), true); + assert.strictEqual((await fileService.exists(dirname(entry.location))), true); entry = firstOrDefault(await service.getEntries(workingCopy1.resource, CancellationToken.None))!; assert.ok(entry); @@ -288,20 +275,20 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); - assert.strictEqual(existsSync(dirname(entry.location.fsPath)), false); + assert.strictEqual((await fileService.exists(dirname(entry.location))), false); }); test('removeAll', async () => { let removed = false; service.onDidRemoveEntries(() => removed = true); - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); - const workingCopy2 = new TestWorkingCopy(URI.file(testFile2Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); + const workingCopy2 = new TestWorkingCopy(testFile2Path); await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); @@ -327,10 +314,10 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); entries = await service.getEntries(workingCopy1.resource, CancellationToken.None); assert.strictEqual(entries.length, 0); @@ -339,8 +326,8 @@ flakySuite('WorkingCopyHistoryService', () => { }); test('getEntries - simple', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); - const workingCopy2 = new TestWorkingCopy(URI.file(testFile2Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); + const workingCopy2 = new TestWorkingCopy(testFile2Path); let entries = await service.getEntries(workingCopy1.resource, CancellationToken.None); assert.strictEqual(entries.length, 0); @@ -368,8 +355,8 @@ flakySuite('WorkingCopyHistoryService', () => { }); test('getEntries - metadata preserved when stored', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); - const workingCopy2 = new TestWorkingCopy(URI.file(testFile2Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); + const workingCopy2 = new TestWorkingCopy(testFile2Path); const entry1 = await addEntry({ resource: workingCopy1.resource, source: 'test-source' }, CancellationToken.None); const entry2 = await addEntry({ resource: workingCopy2.resource }, CancellationToken.None); @@ -380,10 +367,10 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); let entries = await service.getEntries(workingCopy1.resource, CancellationToken.None); assert.strictEqual(entries.length, 1); @@ -396,7 +383,7 @@ flakySuite('WorkingCopyHistoryService', () => { }); test('getEntries - corrupt meta.json is no problem', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); const entry1 = await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); @@ -405,14 +392,14 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); - const metaFile = join(dirname(entry1.location.fsPath), 'entries.json'); - assert.ok(existsSync(metaFile)); - unlinkSync(metaFile); + const metaFile = joinPath(dirname(entry1.location), 'entries.json'); + assert.ok((await fileService.exists(metaFile))); + await fileService.del(metaFile); const entries = await service.getEntries(workingCopy1.resource, CancellationToken.None); assert.strictEqual(entries.length, 1); @@ -420,7 +407,7 @@ flakySuite('WorkingCopyHistoryService', () => { }); test('getEntries - missing entries from meta.json is no problem', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); const entry1 = await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); const entry2 = await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); @@ -430,12 +417,12 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); - unlinkSync(entry1.location.fsPath); + await fileService.del(entry1.location); const entries = await service.getEntries(workingCopy1.resource, CancellationToken.None); assert.strictEqual(entries.length, 1); @@ -443,7 +430,7 @@ flakySuite('WorkingCopyHistoryService', () => { }); test('getEntries - in-memory and on-disk entries are merged', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); const entry1 = await addEntry({ resource: workingCopy1.resource, source: 'test-source' }, CancellationToken.None); const entry2 = await addEntry({ resource: workingCopy1.resource, source: 'other-source' }, CancellationToken.None); @@ -453,10 +440,10 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); const entry3 = await addEntry({ resource: workingCopy1.resource, source: 'test-source' }, CancellationToken.None); const entry4 = await addEntry({ resource: workingCopy1.resource, source: 'other-source' }, CancellationToken.None); @@ -470,7 +457,7 @@ flakySuite('WorkingCopyHistoryService', () => { }); test('getEntries - configured max entries respected', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); await addEntry({ resource: workingCopy1.resource }, CancellationToken.None); @@ -496,8 +483,8 @@ flakySuite('WorkingCopyHistoryService', () => { }); test('getAll', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); - const workingCopy2 = new TestWorkingCopy(URI.file(testFile2Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); + const workingCopy2 = new TestWorkingCopy(testFile2Path); let resources = await service.getAll(CancellationToken.None); assert.strictEqual(resources.length, 0); @@ -520,12 +507,12 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); - const workingCopy3 = new TestWorkingCopy(URI.file(testFile3Path)); + const workingCopy3 = new TestWorkingCopy(testFile3Path); await addEntry({ resource: workingCopy3.resource, source: 'test-source' }, CancellationToken.None); resources = await service.getAll(CancellationToken.None); @@ -538,7 +525,7 @@ flakySuite('WorkingCopyHistoryService', () => { }); test('getAll - ignores resource when no entries exist', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); const entry = await addEntry({ resource: workingCopy1.resource, source: 'test-source' }, CancellationToken.None); @@ -555,10 +542,10 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); resources = await service.getAll(CancellationToken.None); assert.strictEqual(resources.length, 0); @@ -576,7 +563,7 @@ flakySuite('WorkingCopyHistoryService', () => { } test('entries cleaned up on shutdown', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); const entry1 = await addEntry({ resource: workingCopy1.resource, source: 'test-source' }, CancellationToken.None); const entry2 = await addEntry({ resource: workingCopy1.resource, source: 'other-source' }, CancellationToken.None); @@ -590,15 +577,15 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - assert.ok(!existsSync(entry1.location.fsPath)); - assert.ok(!existsSync(entry2.location.fsPath)); - assert.ok(existsSync(entry3.location.fsPath)); - assert.ok(existsSync(entry4.location.fsPath)); + assert.ok(!(await fileService.exists(entry1.location))); + assert.ok(!(await fileService.exists(entry2.location))); + assert.ok((await fileService.exists(entry3.location))); + assert.ok((await fileService.exists(entry4.location))); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); let entries = await service.getEntries(workingCopy1.resource, CancellationToken.None); assert.strictEqual(entries.length, 2); @@ -614,14 +601,14 @@ flakySuite('WorkingCopyHistoryService', () => { service._lifecycleService.fireWillShutdown(event); await Promise.allSettled(event.value); - assert.ok(existsSync(entry3.location.fsPath)); - assert.ok(existsSync(entry4.location.fsPath)); - assert.ok(existsSync(entry5.location.fsPath)); + assert.ok((await fileService.exists(entry3.location))); + assert.ok((await fileService.exists(entry4.location))); + assert.ok((await fileService.exists(entry5.location))); - // Resolve from disk fresh and verify again + // Resolve from file service fresh and verify again service.dispose(); - service = new TestWorkingCopyHistoryService(testDir); + service = new TestWorkingCopyHistoryService(fileService); entries = await service.getEntries(workingCopy1.resource, CancellationToken.None); assert.strictEqual(entries.length, 3); @@ -634,7 +621,7 @@ flakySuite('WorkingCopyHistoryService', () => { let replaced: IWorkingCopyHistoryEntry | undefined = undefined; service.onDidReplaceEntry(e => replaced = e.entry); - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); service._configurationService.setUserConfiguration('workbench.localHistory.mergeWindow', 1); @@ -661,7 +648,7 @@ flakySuite('WorkingCopyHistoryService', () => { }); test('move entries (file rename)', async () => { - const workingCopy = new TestWorkingCopy(URI.file(testFile1Path)); + const workingCopy = new TestWorkingCopy(testFile1Path); const entry1 = await addEntry({ resource: workingCopy.resource, source: 'test-source' }, CancellationToken.None); const entry2 = await addEntry({ resource: workingCopy.resource, source: 'test-source' }, CancellationToken.None); @@ -670,8 +657,8 @@ flakySuite('WorkingCopyHistoryService', () => { let entries = await service.getEntries(workingCopy.resource, CancellationToken.None); assert.strictEqual(entries.length, 3); - const renamedWorkingCopyResource = joinPath(resourcesDirname(workingCopy.resource), 'renamed.txt'); - await service._fileService.move(workingCopy.resource, renamedWorkingCopyResource); + const renamedWorkingCopyResource = joinPath(dirname(workingCopy.resource), 'renamed.txt'); + await fileService.move(workingCopy.resource, renamedWorkingCopyResource); const result = await service.moveEntries(workingCopy.resource, renamedWorkingCopyResource); @@ -708,8 +695,8 @@ flakySuite('WorkingCopyHistoryService', () => { }); test('entries moved (folder rename)', async () => { - const workingCopy1 = new TestWorkingCopy(URI.file(testFile1Path)); - const workingCopy2 = new TestWorkingCopy(URI.file(testFile2Path)); + const workingCopy1 = new TestWorkingCopy(testFile1Path); + const workingCopy2 = new TestWorkingCopy(testFile2Path); const entry1A = await addEntry({ resource: workingCopy1.resource, source: 'test-source' }, CancellationToken.None); const entry2A = await addEntry({ resource: workingCopy1.resource, source: 'test-source' }, CancellationToken.None); @@ -725,10 +712,10 @@ flakySuite('WorkingCopyHistoryService', () => { entries = await service.getEntries(workingCopy2.resource, CancellationToken.None); assert.strictEqual(entries.length, 3); - const renamedWorkHome = joinPath(resourcesDirname(URI.file(workHome)), 'renamed'); - await service._fileService.move(URI.file(workHome), renamedWorkHome); + const renamedWorkHome = joinPath(dirname(workHome), 'renamed'); + await fileService.move(workHome, renamedWorkHome); - const resources = await service.moveEntries(URI.file(workHome), renamedWorkHome); + const resources = await service.moveEntries(workHome, renamedWorkHome); const renamedWorkingCopy1Resource = joinPath(renamedWorkHome, basename(workingCopy1.resource)); const renamedWorkingCopy2Resource = joinPath(renamedWorkHome, basename(workingCopy2.resource)); diff --git a/src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyHistoryTracker.test.ts b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts similarity index 87% rename from src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyHistoryTracker.test.ts rename to src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts index 931ac6cbaef..5bbe9b30267 100644 --- a/src/vs/workbench/services/workingCopy/test/electron-browser/workingCopyHistoryTracker.test.ts +++ b/src/vs/workbench/services/workingCopy/test/electron-sandbox/workingCopyHistoryTracker.test.ts @@ -5,16 +5,14 @@ import * as assert from 'assert'; import { Event } from 'vs/base/common/event'; -import { TestContextService, TestWorkingCopy } from 'vs/workbench/test/common/workbenchTestServices'; +import { TestContextService, TestStorageService, TestWorkingCopy } from 'vs/workbench/test/common/workbenchTestServices'; import { randomPath } from 'vs/base/common/extpath'; -import { tmpdir } from 'os'; import { join } from 'vs/base/common/path'; import { URI } from 'vs/base/common/uri'; -import { TestWorkingCopyHistoryService } from 'vs/workbench/services/workingCopy/test/electron-browser/workingCopyHistoryService.test'; import { WorkingCopyHistoryTracker } from 'vs/workbench/services/workingCopy/common/workingCopyHistoryTracker'; import { WorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; -import { TestFileService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEnvironmentService, TestFileService, TestLifecycleService, TestPathService, TestRemoteAgentService } from 'vs/workbench/test/browser/workbenchTestServices'; import { DeferredPromise } from 'vs/base/common/async'; import { IFileService } from 'vs/platform/files/common/files'; import { Schemas } from 'vs/base/common/network'; @@ -29,6 +27,41 @@ import { assertIsDefined } from 'vs/base/common/types'; import { VSBuffer } from 'vs/base/common/buffer'; import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { NativeWorkingCopyHistoryService } from 'vs/workbench/services/workingCopy/common/workingCopyHistoryService'; +import { NullLogService } from 'vs/platform/log/common/log'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { LabelService } from 'vs/workbench/services/label/common/labelService'; + +class TestWorkingCopyHistoryService extends NativeWorkingCopyHistoryService { + + readonly _fileService: IFileService; + readonly _configurationService: TestConfigurationService; + readonly _lifecycleService: TestLifecycleService; + + constructor(testDir: URI | string) { + const environmentService = TestEnvironmentService; + const logService = new NullLogService(); + const fileService = new FileService(logService); + + fileService.registerProvider(Schemas.vscodeUserData, new InMemoryFileSystemProvider()); + + const remoteAgentService = new TestRemoteAgentService(); + + const uriIdentityService = new UriIdentityService(fileService); + + const labelService = new LabelService(environmentService, new TestContextService(), new TestPathService(), new TestRemoteAgentService(), new TestStorageService(), new TestLifecycleService()); + + const lifecycleService = new TestLifecycleService(); + + const configurationService = new TestConfigurationService(); + + super(fileService, remoteAgentService, environmentService, uriIdentityService, labelService, lifecycleService, logService, configurationService); + + this._fileService = fileService; + this._configurationService = configurationService; + this._lifecycleService = lifecycleService; + } +} suite('WorkingCopyHistoryTracker', () => { @@ -67,7 +100,7 @@ suite('WorkingCopyHistoryTracker', () => { } setup(async () => { - testDir = URI.file(randomPath(join(tmpdir(), 'vsctests', 'workingcopyhistorytracker'))).with({ scheme: Schemas.inMemory }); + testDir = URI.file(randomPath(join('vsctests', 'workingcopyhistorytracker'))).with({ scheme: Schemas.inMemory }); historyHome = joinPath(testDir, 'User', 'History'); workHome = joinPath(testDir, 'work'); diff --git a/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts b/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts index bbb5cce6be0..40e7be1ac1c 100644 --- a/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts @@ -25,7 +25,7 @@ import { ILabelService, Verbosity } from 'vs/platform/label/common/label'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { AbstractWorkspaceEditingService } from 'vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { INativeHostService } from 'vs/platform/native/common/native'; import { isMacintosh } from 'vs/base/common/platform'; import { WorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackupService'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; diff --git a/src/vs/workbench/services/workspaces/electron-sandbox/workspacesService.ts b/src/vs/workbench/services/workspaces/electron-sandbox/workspacesService.ts index e5cb1078e35..d4d82c05960 100644 --- a/src/vs/workbench/services/workspaces/electron-sandbox/workspacesService.ts +++ b/src/vs/workbench/services/workspaces/electron-sandbox/workspacesService.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces'; -import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; +import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { INativeHostService } from 'vs/platform/native/common/native'; // @ts-ignore: interface is implemented via proxy export class NativeWorkspacesService implements IWorkspacesService { diff --git a/src/vs/workbench/test/browser/arrayOperation.test.ts b/src/vs/workbench/test/browser/arrayOperation.test.ts new file mode 100644 index 00000000000..d51b85c57b6 --- /dev/null +++ b/src/vs/workbench/test/browser/arrayOperation.test.ts @@ -0,0 +1,77 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { ArrayEdit, MonotonousIndexTransformer, SingleArrayEdit } from 'vs/workbench/services/textMate/browser/arrayOperation'; + +suite('array operation', () => { + function seq(start: number, end: number) { + const result: number[] = []; + for (let i = start; i < end; i++) { + result.push(i); + } + return result; + } + + test('simple', () => { + const edit = new ArrayEdit([ + new SingleArrayEdit(4, 3, 2), + new SingleArrayEdit(8, 0, 2), + new SingleArrayEdit(9, 2, 0), + ]); + + const arr = seq(0, 15).map(x => `item${x}`); + const newArr = arr.slice(); + + edit.applyToArray(newArr); + assert.deepStrictEqual(newArr, [ + 'item0', + 'item1', + 'item2', + 'item3', + undefined, + undefined, + 'item7', + undefined, + undefined, + 'item8', + 'item11', + 'item12', + 'item13', + 'item14', + ]); + + const transformer = new MonotonousIndexTransformer(edit); + assert.deepStrictEqual( + seq(0, 15).map((x) => { + const t = transformer.transform(x); + let r = `arr[${x}]: ${arr[x]} -> `; + if (t !== undefined) { + r += `newArr[${t}]: ${newArr[t]}`; + } else { + r += 'undefined'; + } + return r; + }), + [ + 'arr[0]: item0 -> newArr[0]: item0', + 'arr[1]: item1 -> newArr[1]: item1', + 'arr[2]: item2 -> newArr[2]: item2', + 'arr[3]: item3 -> newArr[3]: item3', + 'arr[4]: item4 -> undefined', + 'arr[5]: item5 -> undefined', + 'arr[6]: item6 -> undefined', + 'arr[7]: item7 -> newArr[6]: item7', + 'arr[8]: item8 -> newArr[9]: item8', + 'arr[9]: item9 -> undefined', + 'arr[10]: item10 -> undefined', + 'arr[11]: item11 -> newArr[10]: item11', + 'arr[12]: item12 -> newArr[11]: item12', + 'arr[13]: item13 -> newArr[12]: item13', + 'arr[14]: item14 -> newArr[13]: item14', + ] + ); + }); +}); diff --git a/src/vs/workbench/test/browser/parts/editor/editorGroupModel.test.ts b/src/vs/workbench/test/browser/parts/editor/editorGroupModel.test.ts index 33e0061620d..1b70d16389c 100644 --- a/src/vs/workbench/test/browser/parts/editor/editorGroupModel.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/editorGroupModel.test.ts @@ -2124,7 +2124,7 @@ suite('EditorGroupModel', () => { assert.strictEqual(group.indexOf(input2), 1); assert.strictEqual(group.indexOf(input3), 2); - group.moveEditor(input1, 2); // moved out of sticky range + group.moveEditor(input1, 2); // moved out of sticky range// assert.strictEqual(group.isSticky(input1), false); assert.strictEqual(group.isSticky(input2), true); assert.strictEqual(group.isSticky(input3), false); @@ -2171,7 +2171,7 @@ suite('EditorGroupModel', () => { assert.strictEqual(group.indexOf(input2), 1); assert.strictEqual(group.indexOf(input3), 2); - group.moveEditor(input3, 0); // moved into sticky range + group.moveEditor(input3, 0); // moved into sticky range// assert.strictEqual(group.isSticky(input1), true); assert.strictEqual(group.isSticky(input2), false); assert.strictEqual(group.isSticky(input3), true); @@ -2325,4 +2325,40 @@ suite('EditorGroupModel', () => { assert.strictEqual(group2Events.opened[1].editor, input2group2); assert.strictEqual(group2Events.opened[1].editorIndex, 1); }); + + test('moving editor sends sticky event when sticky changes', () => { + const group1 = createEditorGroupModel(); + + const input1group1 = input(); + const input2group1 = input(); + const input3group1 = input(); + + // Open all the editors + group1.openEditor(input1group1, { pinned: true, active: true, index: 0, sticky: true }); + group1.openEditor(input2group1, { pinned: true, active: false, index: 1 }); + group1.openEditor(input3group1, { pinned: true, active: false, index: 2 }); + + const group1Events = groupListener(group1); + + group1.moveEditor(input2group1, 0); + assert.strictEqual(group1Events.sticky[0].editor, input2group1); + assert.strictEqual(group1Events.sticky[0].editorIndex, 0); + + const group2 = createEditorGroupModel(); + + const input1group2 = input(); + const input2group2 = input(); + const input3group2 = input(); + + // Open all the editors + group2.openEditor(input1group2, { pinned: true, active: true, index: 0, sticky: true }); + group2.openEditor(input2group2, { pinned: true, active: false, index: 1 }); + group2.openEditor(input3group2, { pinned: true, active: false, index: 2 }); + + const group2Events = groupListener(group2); + + group2.moveEditor(input1group2, 1); + assert.strictEqual(group2Events.unsticky[0].editor, input1group2); + assert.strictEqual(group2Events.unsticky[0].editorIndex, 1); + }); }); diff --git a/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts b/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts index f6fb00219b4..9d1a741e97c 100644 --- a/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts @@ -95,7 +95,7 @@ suite('EditorInput', () => { assert.ok(!isEditorInput({})); assert.ok(!isResourceEditorInput(input)); - assert.ok(!isUntitledResourceEditorInput(input)); + assert.ok(!isUntitledResourceEditorInput(input as any)); assert.ok(!isResourceDiffEditorInput(input)); assert.ok(!isResourceMergeEditorInput(input)); assert.ok(!isResourceSideBySideEditorInput(input)); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index cbae6e46829..7a2bcec8f60 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -57,7 +57,7 @@ import { IEditorService, ISaveEditorsOptions, IRevertAllEditorsOptions, Preferre import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { IEditorPaneRegistry, EditorPaneDescriptor } from 'vs/workbench/browser/editor'; import { Dimension, IDimension } from 'vs/base/browser/dom'; -import { ILoggerService, ILogService, NullLoggerService, NullLogService } from 'vs/platform/log/common/log'; +import { ILoggerService, ILogService, NullLogService } from 'vs/platform/log/common/log'; import { ILabelService } from 'vs/platform/label/common/label'; import { timeout } from 'vs/base/common/async'; import { PaneComposite, PaneCompositeDescriptor } from 'vs/workbench/browser/panecomposite'; @@ -99,7 +99,7 @@ import { IInputBox, IInputOptions, IPickOptions, IQuickInputButton, IQuickInputS import { QuickInputService } from 'vs/workbench/services/quickinput/browser/quickInputService'; import { IListService } from 'vs/platform/list/browser/listService'; import { win32, posix } from 'vs/base/common/path'; -import { TestContextService, TestStorageService, TestTextResourcePropertiesService, TestExtensionService, TestProductService, createFileStat } from 'vs/workbench/test/common/workbenchTestServices'; +import { TestContextService, TestStorageService, TestTextResourcePropertiesService, TestExtensionService, TestProductService, createFileStat, TestLoggerService } from 'vs/workbench/test/common/workbenchTestServices'; import { IViewsService, IView, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views'; import { IPaneComposite } from 'vs/workbench/common/panecomposite'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; @@ -233,6 +233,7 @@ export function workbenchInstantiationService( overrides?: { environmentService?: (instantiationService: IInstantiationService) => IEnvironmentService; fileService?: (instantiationService: IInstantiationService) => IFileService; + workingCopyBackupService?: (instantiationService: IInstantiationService) => IWorkingCopyBackupService; configurationService?: (instantiationService: IInstantiationService) => TestConfigurationService; textFileService?: (instantiationService: IInstantiationService) => ITextFileService; pathService?: (instantiationService: IInstantiationService) => IPathService; @@ -291,7 +292,7 @@ export function workbenchInstantiationService( instantiationService.stub(IUriIdentityService, uriIdentityService); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, new NullLogService())); instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - instantiationService.stub(IWorkingCopyBackupService, new TestWorkingCopyBackupService()); + instantiationService.stub(IWorkingCopyBackupService, overrides?.workingCopyBackupService ? overrides?.workingCopyBackupService(instantiationService) : new TestWorkingCopyBackupService()); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(INotificationService, new TestNotificationService()); instantiationService.stub(IUntitledTextEditorService, disposables.add(instantiationService.createInstance(UntitledTextEditorService))); @@ -304,7 +305,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 NullLoggerService()); + instantiationService.stub(ILoggerService, new TestLoggerService(TestEnvironmentService.logsHome)); instantiationService.stub(ILogService, new NullLogService()); const editorGroupService = new TestEditorGroupsService([new TestEditorGroupView(0)]); instantiationService.stub(IEditorGroupsService, editorGroupService); @@ -837,6 +838,7 @@ export class TestEditorGroupsService implements IEditorGroupsService { setSize(_group: number | IEditorGroup, _size: { width: number; height: number }): void { } arrangeGroups(_arrangement: GroupsArrangement): void { } applyLayout(_layout: EditorGroupLayout): void { } + getLayout(): EditorGroupLayout { throw new Error('not implemented'); } setGroupOrientation(_orientation: GroupOrientation): void { } addGroup(_location: number | IEditorGroup, _direction: GroupDirection, _options?: IAddGroupOptions): IEditorGroup { throw new Error('not implemented'); } removeGroup(_group: number | IEditorGroup): void { } @@ -1786,6 +1788,7 @@ export class TestTerminalInstanceService implements ITerminalInstanceService { preparePathForTerminalAsync(path: string, executable: string | undefined, title: string, shellType: TerminalShellType, remoteAuthority: string | undefined): Promise { throw new Error('Method not implemented.'); } createInstance(options: ICreateTerminalOptions, target: TerminalLocation): ITerminalInstance { throw new Error('Method not implemented.'); } async getBackend(remoteAuthority?: string): Promise { throw new Error('Method not implemented.'); } + didRegisterBackend(remoteAuthority?: string): void { throw new Error('Method not implemented.'); } } export class TestTerminalEditorService implements ITerminalEditorService { @@ -1849,6 +1852,7 @@ export class TestTerminalGroupService implements ITerminalGroupService { hidePanel(): void { throw new Error('Method not implemented.'); } focusTabs(): void { throw new Error('Method not implemented.'); } showTabs(): void { throw new Error('Method not implemented.'); } + focusHover(): void { throw new Error('Method not implemented.'); } setActiveInstance(instance: ITerminalInstance): void { throw new Error('Method not implemented.'); } focusActiveInstance(): Promise { throw new Error('Method not implemented.'); } getInstanceFromResource(resource: URI | undefined): ITerminalInstance | undefined { throw new Error('Method not implemented.'); } @@ -2037,7 +2041,7 @@ export class TestUserDataProfileService implements IUserDataProfileService { readonly _serviceBrand: undefined; readonly onDidUpdateCurrentProfile = Event.None; readonly onDidChangeCurrentProfile = Event.None; - readonly currentProfile = toUserDataProfile('test', 'test', URI.file('tests').with({ scheme: 'vscode-tests' })); + readonly currentProfile = toUserDataProfile('test', 'test', URI.file('tests').with({ scheme: 'vscode-tests' }), URI.file('tests').with({ scheme: 'vscode-tests' })); async updateCurrentProfile(): Promise { } getShortName(profile: IUserDataProfile): string { return profile.shortName ?? profile.name; } } diff --git a/src/vs/workbench/test/common/notifications.test.ts b/src/vs/workbench/test/common/notifications.test.ts index 126f512975b..bc96b826ea9 100644 --- a/src/vs/workbench/test/common/notifications.test.ts +++ b/src/vs/workbench/test/common/notifications.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { NotificationsModel, NotificationViewItem, INotificationChangeEvent, NotificationChangeType, NotificationViewItemContentChangeKind, IStatusMessageChangeEvent, StatusMessageChangeType } from 'vs/workbench/common/notifications'; import { Action } from 'vs/base/common/actions'; -import { INotification, Severity, NotificationsFilter } from 'vs/platform/notification/common/notification'; +import { INotification, Severity, NotificationsFilter, NotificationPriority } from 'vs/platform/notification/common/notification'; import { createErrorWithActions } from 'vs/base/common/errorMessage'; import { NotificationService } from 'vs/workbench/services/notification/common/notificationService'; import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; @@ -132,16 +132,16 @@ suite('Notifications', () => { // Filter const item8 = NotificationViewItem.create({ severity: Severity.Error, message: 'Error Message' }, NotificationsFilter.SILENT)!; - assert.strictEqual(item8.silent, true); + assert.strictEqual(item8.priority, NotificationPriority.SILENT); const item9 = NotificationViewItem.create({ severity: Severity.Error, message: 'Error Message' }, NotificationsFilter.OFF)!; - assert.strictEqual(item9.silent, false); + assert.strictEqual(item9.priority, NotificationPriority.DEFAULT); const item10 = NotificationViewItem.create({ severity: Severity.Error, message: 'Error Message' }, NotificationsFilter.ERROR)!; - assert.strictEqual(item10.silent, false); + assert.strictEqual(item10.priority, NotificationPriority.DEFAULT); const item11 = NotificationViewItem.create({ severity: Severity.Warning, message: 'Error Message' }, NotificationsFilter.ERROR)!; - assert.strictEqual(item11.silent, true); + assert.strictEqual(item11.priority, NotificationPriority.SILENT); }); test('Items - does not fire changed when message did not change (content, severity)', async () => { @@ -280,7 +280,7 @@ suite('Notifications', () => { service.info('hello there'); assert.strictEqual(addNotificationCount, 1); assert.strictEqual(notification.message, 'hello there'); - assert.strictEqual(notification.silent, false); + assert.strictEqual(notification.priority, NotificationPriority.DEFAULT); assert.strictEqual(notification.source, undefined); let notificationHandle = service.notify({ message: 'important message', severity: Severity.Warning }); @@ -297,10 +297,10 @@ suite('Notifications', () => { assert.strictEqual(removeNotificationCount, 1); assert.strictEqual(notification.message, 'important message'); - notificationHandle = service.notify({ silent: true, message: 'test', severity: Severity.Ignore }); + notificationHandle = service.notify({ priority: NotificationPriority.SILENT, message: 'test', severity: Severity.Ignore }); assert.strictEqual(addNotificationCount, 3); assert.strictEqual(notification.message, 'test'); - assert.strictEqual(notification.silent, true); + assert.strictEqual(notification.priority, NotificationPriority.SILENT); notificationHandle.close(); assert.strictEqual(removeNotificationCount, 2); }); diff --git a/src/vs/workbench/test/common/workbenchTestServices.ts b/src/vs/workbench/test/common/workbenchTestServices.ts index 31124d0e8dd..e1398daa91d 100644 --- a/src/vs/workbench/test/common/workbenchTestServices.ts +++ b/src/vs/workbench/test/common/workbenchTestServices.ts @@ -23,6 +23,14 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import product from 'vs/platform/product/common/product'; import { IActivity, IActivityService } from 'vs/workbench/services/activity/common/activity'; import { IStoredFileWorkingCopySaveEvent } from 'vs/workbench/services/workingCopy/common/storedFileWorkingCopy'; +import { AbstractLoggerService, ILogger, LogLevel, NullLogger } from 'vs/platform/log/common/log'; + +export class TestLoggerService extends AbstractLoggerService { + constructor(logsHome?: URI) { + super(LogLevel.Info, logsHome ?? URI.file('tests').with({ scheme: 'vscode-tests' })); + } + protected doCreateLogger(): ILogger { return new NullLogger(); } +} export class TestTextResourcePropertiesService implements ITextResourcePropertiesService { diff --git a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts similarity index 52% rename from src/vs/workbench/test/electron-browser/workbenchTestServices.ts rename to src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts index 2bb2ada89e6..142c563dd04 100644 --- a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts @@ -3,180 +3,49 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestLifecycleService, TestFilesConfigurationService, TestFileService, TestFileDialogService, TestPathService, TestEncodingOracle } from 'vs/workbench/test/browser/workbenchTestServices'; import { Event } from 'vs/base/common/event'; +import { workbenchInstantiationService as browserWorkbenchInstantiationService, ITestInstantiationService, TestEncodingOracle, TestEnvironmentService, TestFileDialogService, TestFilesConfigurationService, TestFileService, TestLifecycleService, TestTextFileService } from 'vs/workbench/test/browser/workbenchTestServices'; import { ISharedProcessService } from 'vs/platform/ipc/electron-sandbox/services'; -import { NativeTextFileService, } from 'vs/workbench/services/textfile/electron-sandbox/nativeTextFileService'; -import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; -import { FileOperationError, IFileService } from 'vs/platform/files/common/files'; -import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; -import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IModelService } from 'vs/editor/common/services/model'; -import { INativeWorkbenchEnvironmentService, NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService'; -import { IDialogService, IFileDialogService, INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs'; -import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; -import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; -import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { URI } from 'vs/base/common/uri'; -import { IReadTextFileOptions, ITextFileStreamContent, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel'; -import { IOpenEmptyWindowOptions, IWindowOpenable, IOpenWindowOptions, IOpenedWindow, IColorScheme, INativeWindowConfiguration } from 'vs/platform/window/common/window'; -import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv'; -import { LogLevel, ILogService, NullLogService } from 'vs/platform/log/common/log'; -import { IPathService } from 'vs/workbench/services/path/common/pathService'; -import { IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { ModelService } from 'vs/editor/common/services/modelService'; -import { IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackup'; -import { NodeTestWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/test/electron-browser/workingCopyBackupService.test'; -import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { TestContextService, TestProductService } from 'vs/workbench/test/common/workbenchTestServices'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { MouseInputEvent } from 'vs/base/parts/sandbox/common/electronTypes'; -import { ILanguageService } from 'vs/editor/common/languages/language'; -import { IOSProperties, IOSStatistics } from 'vs/platform/native/common/native'; -import { homedir, release, tmpdir, hostname } from 'os'; -import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { getUserDataPath } from 'vs/platform/environment/node/userDataPath'; -import product from 'vs/platform/product/common/product'; -import { IElevatedFileService } from 'vs/workbench/services/files/common/elevatedFileService'; -import { IDecorationsService } from 'vs/workbench/services/decorations/common/decorations'; +import { INativeHostService, IOSProperties, IOSStatistics } from 'vs/platform/native/common/native'; +import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer'; import { DisposableStore } from 'vs/base/common/lifecycle'; +import { URI } from 'vs/base/common/uri'; +import { IFileDialogService, INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs'; import { IPartsSplash } from 'vs/platform/theme/common/themeService'; -import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IOpenedWindow, IOpenEmptyWindowOptions, IWindowOpenable, IOpenWindowOptions, IColorScheme } from 'vs/platform/window/common/window'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IPathService } from 'vs/workbench/services/path/common/pathService'; +import { ITextEditorService } from 'vs/workbench/services/textfile/common/textEditorService'; +import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { AbstractNativeExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionTipsService'; +import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionRecommendationNotificationService } from 'vs/platform/extensionRecommendations/common/extensionRecommendations'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { IStorageService } from 'vs/platform/storage/common/storage'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IModelService } from 'vs/editor/common/services/model'; +import { ModelService } from 'vs/editor/common/services/modelService'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle'; +import { IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackup'; +import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; +import { NativeTextFileService } from 'vs/workbench/services/textfile/electron-sandbox/nativeTextFileService'; +import { insert } from 'vs/base/common/arrays'; +import { Schemas } from 'vs/base/common/network'; import { FileService } from 'vs/platform/files/common/fileService'; -import { joinPath } from 'vs/base/common/resources'; -import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; -import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; -import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; -import { VSBuffer } from 'vs/base/common/buffer'; - -const args = parseArgs(process.argv, OPTIONS); - -const homeDir = homedir(); -const NULL_PROFILE = { - name: '', - id: '', - shortName: '', - isDefault: false, - location: URI.file(homeDir), - settingsResource: joinPath(URI.file(homeDir), 'settings.json'), - globalStorageHome: joinPath(URI.file(homeDir), 'globalStorage'), - keybindingsResource: joinPath(URI.file(homeDir), 'keybindings.json'), - tasksResource: joinPath(URI.file(homeDir), 'tasks.json'), - snippetsHome: joinPath(URI.file(homeDir), 'snippets'), - extensionsResource: joinPath(URI.file(homeDir), 'extensions.json') -}; - -export const TestNativeWindowConfiguration: INativeWindowConfiguration = { - windowId: 0, - machineId: 'testMachineId', - logLevel: LogLevel.Error, - loggers: { global: [], window: [] }, - mainPid: 0, - appRoot: '', - userEnv: {}, - execPath: process.execPath, - perfMarks: [], - colorScheme: { dark: true, highContrast: false }, - os: { release: release(), hostname: hostname() }, - product, - homeDir: homeDir, - tmpDir: tmpdir(), - userDataDir: getUserDataPath(args, product.nameShort), - profiles: { profile: NULL_PROFILE, all: [NULL_PROFILE], home: URI.file(homeDir) }, - preferUtilityProcess: false, - ...args -}; - -export const TestEnvironmentService = new NativeWorkbenchEnvironmentService(TestNativeWindowConfiguration, TestProductService); - -export class TestTextFileService extends NativeTextFileService { - private resolveTextContentError!: FileOperationError | null; - - constructor( - @IFileService fileService: IFileService, - @IUntitledTextEditorService untitledTextEditorService: IUntitledTextEditorService, - @ILifecycleService lifecycleService: ILifecycleService, - @IInstantiationService instantiationService: IInstantiationService, - @IModelService modelService: IModelService, - @INativeWorkbenchEnvironmentService environmentService: INativeWorkbenchEnvironmentService, - @IDialogService dialogService: IDialogService, - @IFileDialogService fileDialogService: IFileDialogService, - @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, - @ICodeEditorService codeEditorService: ICodeEditorService, - @IPathService pathService: IPathService, - @IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService, - @ILogService logService: ILogService, - @IUriIdentityService uriIdentityService: IUriIdentityService, - @ILanguageService languageService: ILanguageService, - @IElevatedFileService elevatedFileService: IElevatedFileService, - @IDecorationsService decorationsService: IDecorationsService - ) { - super( - fileService, - untitledTextEditorService, - lifecycleService, - instantiationService, - modelService, - environmentService, - dialogService, - fileDialogService, - textResourceConfigurationService, - filesConfigurationService, - codeEditorService, - pathService, - workingCopyFileService, - uriIdentityService, - languageService, - elevatedFileService, - logService, - decorationsService - ); - } - - setResolveTextContentErrorOnce(error: FileOperationError): void { - this.resolveTextContentError = error; - } - - override async readStream(resource: URI, options?: IReadTextFileOptions): Promise { - if (this.resolveTextContentError) { - const error = this.resolveTextContentError; - this.resolveTextContentError = null; - - throw error; - } - - const content = await this.fileService.readFileStream(resource, options); - return { - resource: content.resource, - name: content.name, - mtime: content.mtime, - ctime: content.ctime, - etag: content.etag, - encoding: 'utf8', - value: await createTextBufferFactoryFromStream(content.value), - size: 10, - readonly: false - }; - } -} - -export class TestNativeTextFileServiceWithEncodingOverrides extends NativeTextFileService { - - private _testEncoding: TestEncodingOracle | undefined; - override get encoding(): TestEncodingOracle { - if (!this._testEncoding) { - this._testEncoding = this._register(this.instantiationService.createInstance(TestEncodingOracle)); - } - - return this._testEncoding; - } -} +import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; +import { NullLogService } from 'vs/platform/log/common/log'; +import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider'; +import { IWorkingCopyIdentifier } from 'vs/workbench/services/workingCopy/common/workingCopy'; +import { NativeWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupService'; +import { CancellationToken } from 'vs/base/common/cancellation'; export class TestSharedProcessService implements ISharedProcessService { @@ -275,26 +144,44 @@ export class TestNativeHostService implements INativeHostService { async writeClipboardBuffer(format: string, buffer: VSBuffer, type?: 'selection' | 'clipboard' | undefined): Promise { } async readClipboardBuffer(format: string): Promise { return VSBuffer.wrap(Uint8Array.from([])); } async hasClipboard(format: string, type?: 'selection' | 'clipboard' | undefined): Promise { return false; } - async sendInputEvent(event: MouseInputEvent): Promise { } + async sendInputEvent(event: any): Promise { } async windowsGetStringRegKey(hive: 'HKEY_CURRENT_USER' | 'HKEY_LOCAL_MACHINE' | 'HKEY_CLASSES_ROOT' | 'HKEY_USERS' | 'HKEY_CURRENT_CONFIG', path: string, name: string): Promise { return undefined; } async profileRenderer(): Promise { throw new Error(); } async enableSandbox(enabled: boolean): Promise { throw new Error('Method not implemented.'); } } -export function workbenchInstantiationService(disposables = new DisposableStore()): ITestInstantiationService { +export class TestExtensionTipsService extends AbstractNativeExtensionTipsService { + + constructor( + @INativeEnvironmentService environmentService: INativeEnvironmentService, + @ITelemetryService telemetryService: ITelemetryService, + @IExtensionManagementService extensionManagementService: IExtensionManagementService, + @IStorageService storageService: IStorageService, + @INativeHostService nativeHostService: INativeHostService, + @IExtensionRecommendationNotificationService extensionRecommendationNotificationService: IExtensionRecommendationNotificationService, + @IFileService fileService: IFileService, + @IProductService productService: IProductService, + ) { + super(environmentService.userHome, nativeHostService, telemetryService, extensionManagementService, storageService, extensionRecommendationNotificationService, fileService, productService); + } +} + +export function workbenchInstantiationService(overrides?: { + environmentService?: (instantiationService: IInstantiationService) => IEnvironmentService; + fileService?: (instantiationService: IInstantiationService) => IFileService; + configurationService?: (instantiationService: IInstantiationService) => TestConfigurationService; + textFileService?: (instantiationService: IInstantiationService) => ITextFileService; + pathService?: (instantiationService: IInstantiationService) => IPathService; + editorService?: (instantiationService: IInstantiationService) => IEditorService; + contextKeyService?: (instantiationService: IInstantiationService) => IContextKeyService; + textEditorService?: (instantiationService: IInstantiationService) => ITextEditorService; +}, disposables = new DisposableStore()): ITestInstantiationService { const instantiationService = browserWorkbenchInstantiationService({ - textFileService: insta => insta.createInstance(TestTextFileService), - pathService: insta => insta.createInstance(TestNativePathService) + workingCopyBackupService: (instantiationService: IInstantiationService) => new TestNativeWorkingCopyBackupService(), + ...overrides }, disposables); instantiationService.stub(INativeHostService, new TestNativeHostService()); - instantiationService.stub(IEnvironmentService, TestEnvironmentService); - instantiationService.stub(INativeEnvironmentService, TestEnvironmentService); - instantiationService.stub(IWorkbenchEnvironmentService, TestEnvironmentService); - instantiationService.stub(INativeWorkbenchEnvironmentService, TestEnvironmentService); - const fileService = new FileService(new NullLogService()); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(TestEnvironmentService, fileService, new UriIdentityService(fileService), new NullLogService())); - instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); return instantiationService; } @@ -309,16 +196,102 @@ export class TestServiceAccessor { @IFileService public fileService: TestFileService, @INativeHostService public nativeHostService: TestNativeHostService, @IFileDialogService public fileDialogService: TestFileDialogService, - @IWorkingCopyBackupService public workingCopyBackupService: NodeTestWorkingCopyBackupService, + @IWorkingCopyBackupService public workingCopyBackupService: TestNativeWorkingCopyBackupService, @IWorkingCopyService public workingCopyService: IWorkingCopyService, @IEditorService public editorService: IEditorService ) { } } -export class TestNativePathService extends TestPathService { +export class TestNativeTextFileServiceWithEncodingOverrides extends NativeTextFileService { - constructor() { - super(URI.file(homedir())); + private _testEncoding: TestEncodingOracle | undefined; + override get encoding(): TestEncodingOracle { + if (!this._testEncoding) { + this._testEncoding = this._register(this.instantiationService.createInstance(TestEncodingOracle)); + } + + return this._testEncoding; + } +} + +export class TestNativeWorkingCopyBackupService extends NativeWorkingCopyBackupService { + + private backupResourceJoiners: Function[]; + private discardBackupJoiners: Function[]; + discardedBackups: IWorkingCopyIdentifier[]; + discardedAllBackups: boolean; + private pendingBackupsArr: Promise[]; + + constructor() { + const environmentService = TestEnvironmentService; + const logService = new NullLogService(); + const fileService = new FileService(logService); + const lifecycleService = new TestLifecycleService(); + super(environmentService as any, fileService, logService, lifecycleService); + + const inMemoryFileSystemProvider = new InMemoryFileSystemProvider(); + fileService.registerProvider(Schemas.inMemory, inMemoryFileSystemProvider); + fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, inMemoryFileSystemProvider, Schemas.vscodeUserData, logService)); + + this.backupResourceJoiners = []; + this.discardBackupJoiners = []; + this.discardedBackups = []; + this.pendingBackupsArr = []; + this.discardedAllBackups = false; + } + + testGetFileService(): IFileService { + return this.fileService; + } + + async waitForAllBackups(): Promise { + await Promise.all(this.pendingBackupsArr); + } + + joinBackupResource(): Promise { + return new Promise(resolve => this.backupResourceJoiners.push(resolve)); + } + + override async backup(identifier: IWorkingCopyIdentifier, content?: VSBufferReadableStream | VSBufferReadable, versionId?: number, meta?: any, token?: CancellationToken): Promise { + const p = super.backup(identifier, content, versionId, meta, token); + const removeFromPendingBackups = insert(this.pendingBackupsArr, p.then(undefined, undefined)); + + try { + await p; + } finally { + removeFromPendingBackups(); + } + + while (this.backupResourceJoiners.length) { + this.backupResourceJoiners.pop()!(); + } + } + + joinDiscardBackup(): Promise { + return new Promise(resolve => this.discardBackupJoiners.push(resolve)); + } + + override async discardBackup(identifier: IWorkingCopyIdentifier): Promise { + await super.discardBackup(identifier); + this.discardedBackups.push(identifier); + + while (this.discardBackupJoiners.length) { + this.discardBackupJoiners.pop()!(); + } + } + + override async discardBackups(filter?: { except: IWorkingCopyIdentifier[] }): Promise { + this.discardedAllBackups = true; + + return super.discardBackups(filter); + } + + async getBackupContents(identifier: IWorkingCopyIdentifier): Promise { + const backupResource = this.toBackupResource(identifier); + + const fileContents = await this.fileService.readFile(backupResource); + + return fileContents.value.toString(); } } diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 88e9eabaaaa..c010c73133d 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -102,6 +102,9 @@ import 'vs/workbench/services/assignment/common/assignmentService'; import 'vs/workbench/services/outline/browser/outlineService'; import 'vs/workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl'; import 'vs/editor/common/services/languageFeaturesService'; +import 'vs/editor/common/services/semanticTokensStylingService'; +import 'vs/editor/common/services/treeViewsDndService'; +import 'vs/workbench/services/textMate/browser/textMateTokenizationFeature.contribution'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; @@ -166,6 +169,9 @@ import 'vs/workbench/contrib/contextmenu/browser/contextmenu.contribution'; // Notebook import 'vs/workbench/contrib/notebook/browser/notebook.contribution'; +import 'vs/workbench/contrib/interactiveSession/browser/interactiveSession.contribution'; +import 'vs/workbench/contrib/interactiveEditor/browser/interactiveEditor.contribution'; + // Interactive import 'vs/workbench/contrib/interactive/browser/interactive.contribution'; @@ -214,6 +220,9 @@ import 'vs/workbench/contrib/markers/browser/markers.contribution'; // Merge Editor import 'vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution'; +// Commands +import 'vs/workbench/contrib/commands/common/commands.contribution'; + // Comments import 'vs/workbench/contrib/comments/browser/comments.contribution'; @@ -239,11 +248,10 @@ import 'vs/workbench/contrib/output/browser/output.contribution'; import 'vs/workbench/contrib/output/browser/outputView'; // Terminal -import 'vs/workbench/contrib/terminal/common/environmentVariable.contribution'; -import 'vs/workbench/contrib/terminal/common/terminalExtensionPoints.contribution'; +import 'vs/workbench/contrib/terminal/terminal.all'; + +// External terminal import 'vs/workbench/contrib/externalTerminal/browser/externalTerminal.contribution'; -import 'vs/workbench/contrib/terminal/browser/terminal.contribution'; -import 'vs/workbench/contrib/terminal/browser/terminalView'; // Relauncher import 'vs/workbench/contrib/relauncher/browser/relauncher.contribution'; @@ -291,7 +299,6 @@ import 'vs/workbench/contrib/surveys/browser/ces.contribution'; import 'vs/workbench/contrib/surveys/browser/languageSurveys.contribution'; // Welcome -import 'vs/workbench/contrib/welcomeOverlay/browser/welcomeOverlay'; import 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution'; import 'vs/workbench/contrib/welcomeWalkthrough/browser/walkThrough.contribution'; import 'vs/workbench/contrib/welcomeViews/common/viewsWelcome.contribution'; diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 7d06a90c0cf..f95f43c8fd8 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -37,7 +37,6 @@ import 'vs/workbench/electron-sandbox/parts/dialogs/dialog.contribution'; import 'vs/workbench/services/textfile/electron-sandbox/nativeTextFileService'; import 'vs/workbench/services/dialogs/electron-sandbox/fileDialogService'; import 'vs/workbench/services/workspaces/electron-sandbox/workspacesService'; -import 'vs/workbench/services/textMate/browser/nativeTextMateService'; import 'vs/workbench/services/menubar/electron-sandbox/menubarService'; import 'vs/workbench/services/issue/electron-sandbox/issueService'; import 'vs/workbench/services/update/electron-sandbox/updateService'; @@ -62,7 +61,8 @@ import 'vs/workbench/services/localization/electron-sandbox/languagePackService' import 'vs/workbench/services/telemetry/electron-sandbox/telemetryService'; import 'vs/workbench/services/extensions/electron-sandbox/extensionHostStarter'; import 'vs/platform/extensionResourceLoader/common/extensionResourceLoaderService'; -import 'vs/platform/extensionManagement/electron-sandbox/extensionsScannerService'; +import 'vs/workbench/services/localization/electron-sandbox/localeService'; +import 'vs/workbench/services/extensions/electron-sandbox/extensionsScannerService'; import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementServerService'; import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionTipsService'; import 'vs/workbench/services/userDataSync/electron-sandbox/userDataSyncMachinesService'; @@ -89,9 +89,11 @@ import 'vs/workbench/services/extensions/electron-sandbox/nativeExtensionService import 'vs/platform/userDataProfile/electron-sandbox/userDataProfileStorageService'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IUserDataInitializationService, UserDataInitializationService } from 'vs/workbench/services/userData/browser/userDataInit'; import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; import { ExtensionsProfileScannerService } from 'vs/platform/extensionManagement/electron-sandbox/extensionsProfileScannerService'; +registerSingleton(IUserDataInitializationService, UserDataInitializationService, InstantiationType.Delayed); registerSingleton(IExtensionsProfileScannerService, ExtensionsProfileScannerService, InstantiationType.Delayed); diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index f7c8567da5e..caaabcf3778 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -35,7 +35,6 @@ import 'vs/workbench/browser/web.main'; //#region --- workbench services import 'vs/workbench/services/integrity/browser/integrityService'; -import 'vs/workbench/services/textMate/browser/browserTextMateService'; import 'vs/workbench/services/search/browser/searchService'; import 'vs/workbench/services/textfile/browser/browserTextFileService'; import 'vs/workbench/services/keybinding/browser/keyboardLayoutService'; @@ -53,6 +52,7 @@ import 'vs/workbench/services/dialogs/browser/fileDialogService'; import 'vs/workbench/services/host/browser/browserHostService'; import 'vs/workbench/services/lifecycle/browser/lifecycleService'; import 'vs/workbench/services/clipboard/browser/clipboardService'; +import 'vs/workbench/services/localization/browser/localeService'; import 'vs/workbench/services/path/browser/pathService'; import 'vs/workbench/services/themes/browser/browserHostColorSchemeService'; import 'vs/workbench/services/encryption/browser/encryptionService'; @@ -134,6 +134,9 @@ import 'vs/workbench/contrib/debug/browser/extensionHostDebugService'; // Welcome Banner import 'vs/workbench/contrib/welcomeBanner/browser/welcomeBanner.contribution'; +// Welcome Dialog +import 'vs/workbench/contrib/welcomeDialog/browser/welcomeDialog.contribution'; + // Webview import 'vs/workbench/contrib/webview/browser/webview.web.contribution'; @@ -152,7 +155,7 @@ import 'vs/workbench/contrib/tasks/browser/taskService'; import 'vs/workbench/contrib/tags/browser/workspaceTagsService'; // Issues -import 'vs/workbench/contrib/issue/browser/issue.web.contribution'; +import 'vs/workbench/contrib/issue/browser/issue.contribution'; // Splash import 'vs/workbench/contrib/splash/browser/splash.contribution'; @@ -180,7 +183,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { GroupOrientation } from 'vs/workbench/services/editor/common/editorGroupsService'; import { UserDataSyncResourceProviderService } from 'vs/platform/userDataSync/common/userDataSyncResourceProvider'; -import { RemoteAuthorityResolverError } from 'vs/platform/remote/common/remoteAuthorityResolver'; +import { RemoteAuthorityResolverError, RemoteAuthorityResolverErrorCode } from 'vs/platform/remote/common/remoteAuthorityResolver'; export { @@ -195,6 +198,7 @@ export { GroupOrientation, LogLevel, RemoteAuthorityResolverError, + RemoteAuthorityResolverErrorCode, // Facade API env, diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index 33deba6c8a5..57453d62b50 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -10496,6 +10496,7 @@ declare module 'vscode' { * Retrieves the data transfer item for a given mime type. * * @param mimeType The mime type to get the data transfer item for, such as `text/plain` or `image/png`. + * Mimes type look ups are case-insensitive. * * Special mime types: * - `text/uri-list` — A string with `toString()`ed Uris separated by `\r\n`. To specify a cursor position in the file, @@ -10505,7 +10506,8 @@ declare module 'vscode' { /** * Sets a mime type to data transfer item mapping. - * @param mimeType The mime type to set the data for. + * + * @param mimeType The mime type to set the data for. Mimes types stored in lower case, with case-insensitive looks up. * @param value The data transfer item for the given mime type. */ set(mimeType: string, value: DataTransferItem): void; @@ -12276,7 +12278,7 @@ declare module 'vscode' { * If you want to monitor file events across all opened workspace folders: * * ```ts - * vscode.workspace.createFileSystemWatcher('**​/*.js')); + * vscode.workspace.createFileSystemWatcher('**​/*.js'); * ``` * * *Note:* the array of workspace folders can be empty if no workspace is opened (empty window). @@ -15960,6 +15962,13 @@ declare module 'vscode' { */ isDefault: boolean; + /** + * Whether this profile supports continuous running of requests. If so, + * then {@link TestRunRequest.continuous} may be set to `true`. Defaults + * to false. + */ + supportsContinuousRun: boolean; + /** * Associated tag for the profile. If this is set, only {@link TestItem} * instances with the same tag will be eligible to execute in this profile. @@ -15980,6 +15989,11 @@ declare module 'vscode' { * associated with the request should be created before the function returns * or the returned promise is resolved. * + * If {@link supportsContinuousRun} is set, then {@link TestRunRequest.continuous} + * may be `true`. In this case, the profile should observe changes to + * source code and create new test runs by calling {@link TestController.createTestRun}, + * until the cancellation is requested on the `token`. + * * @param request Request information for the test run. * @param cancellationToken Token that signals the used asked to abort the * test run. If cancellation is requested on this token, all {@link TestRun} @@ -16034,10 +16048,11 @@ declare module 'vscode' { * @param runHandler Function called to start a test run. * @param isDefault Whether this is the default action for its kind. * @param tag Profile test tag. + * @param supportsContinuousRun Whether the profile supports continuous running. * @returns An instance of a {@link TestRunProfile}, which is automatically * associated with this controller. */ - createRunProfile(label: string, kind: TestRunProfileKind, runHandler: (request: TestRunRequest, token: CancellationToken) => Thenable | void, isDefault?: boolean, tag?: TestTag): TestRunProfile; + createRunProfile(label: string, kind: TestRunProfileKind, runHandler: (request: TestRunRequest, token: CancellationToken) => Thenable | void, isDefault?: boolean, tag?: TestTag, supportsContinuousRun?: boolean): TestRunProfile; /** * A function provided by the extension that the editor may call to request @@ -16152,12 +16167,19 @@ declare module 'vscode' { */ readonly profile: TestRunProfile | undefined; + /** + * Whether the profile should run continuously as source code changes. Only + * relevant for profiles that set {@link TestRunProfile.supportsContinuousRun}. + */ + readonly continuous?: boolean; + /** * @param include Array of specific tests to run, or undefined to run all tests * @param exclude An array of tests to exclude from the run. * @param profile The run profile used for this request. + * @param continuous Whether to run tests continuously as source changes. */ - constructor(include?: readonly TestItem[], exclude?: readonly TestItem[], profile?: TestRunProfile); + constructor(include?: readonly TestItem[], exclude?: readonly TestItem[], profile?: TestRunProfile, continuous?: boolean); } /** @@ -16231,7 +16253,8 @@ declare module 'vscode' { /** * Appends raw output from the test runner. On the user's request, the * output will be displayed in a terminal. ANSI escape sequences, - * such as colors and text styles, are supported. + * such as colors and text styles, are supported. New lines must be given + * as CRLF (`\r\n`) rather than LF (`\n`). * * @param output Output text to append. * @param location Indicate that the output was logged at the given diff --git a/src/vscode-dts/vscode.proposed.notebookControllerKind.d.ts b/src/vscode-dts/vscode.proposed.commentsDraftState.d.ts similarity index 67% rename from src/vscode-dts/vscode.proposed.notebookControllerKind.d.ts rename to src/vscode-dts/vscode.proposed.commentsDraftState.d.ts index b8a4a5376e8..ee41130910a 100644 --- a/src/vscode-dts/vscode.proposed.notebookControllerKind.d.ts +++ b/src/vscode-dts/vscode.proposed.commentsDraftState.d.ts @@ -5,12 +5,14 @@ declare module 'vscode' { - // https://github.com/microsoft/vscode-jupyter/issues/7373 + // https://github.com/microsoft/vscode/issues/171166 - export interface NotebookController { - /** - * The human-readable label used to categorise controllers. - */ - kind?: string; + export enum CommentState { + Published = 0, + Draft = 1 + } + + export interface Comment { + state?: CommentState; } } diff --git a/src/vscode-dts/vscode.proposed.contribEditorLineNumberMenu.d.ts b/src/vscode-dts/vscode.proposed.contribEditorLineNumberMenu.d.ts new file mode 100644 index 00000000000..7ee400c56b3 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.contribEditorLineNumberMenu.d.ts @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// empty placeholder declaration for the `editor/lineNumber/context` menu contribution point + +// https://github.com/microsoft/vscode/issues/175945 @joyceerhl diff --git a/src/vscode-dts/vscode.proposed.contribShareMenu.d.ts b/src/vscode-dts/vscode.proposed.contribShareMenu.d.ts index a38d03f4fde..e308029d4e2 100644 --- a/src/vscode-dts/vscode.proposed.contribShareMenu.d.ts +++ b/src/vscode-dts/vscode.proposed.contribShareMenu.d.ts @@ -4,3 +4,4 @@ *--------------------------------------------------------------------------------------------*/ // empty placeholder declaration for the `file/share`-submenu contribution point +// https://github.com/microsoft/vscode/issues/176316 diff --git a/src/vscode-dts/vscode.proposed.fileComments.d.ts b/src/vscode-dts/vscode.proposed.fileComments.d.ts new file mode 100644 index 00000000000..09c729145f2 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.fileComments.d.ts @@ -0,0 +1,85 @@ +/*--------------------------------------------------------------------------------------------- + * 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 CommentThread2 { + /** + * The uri of the document the thread has been created on. + */ + readonly uri: Uri; + + /** + * The range the comment thread is located within the document. The thread icon will be shown + * at the last line of the range. + */ + range: Range | undefined; + + /** + * The ordered comments of the thread. + */ + comments: readonly Comment[]; + + /** + * Whether the thread should be collapsed or expanded when opening the document. + * Defaults to Collapsed. + */ + collapsibleState: CommentThreadCollapsibleState; + + /** + * Whether the thread supports reply. + * Defaults to true. + */ + canReply: boolean; + + /** + * Context value of the comment thread. This can be used to contribute thread specific actions. + * For example, a comment thread is given a context value as `editable`. When contributing actions to `comments/commentThread/title` + * using `menus` extension point, you can specify context value for key `commentThread` in `when` expression like `commentThread == editable`. + * ```json + * "contributes": { + * "menus": { + * "comments/commentThread/title": [ + * { + * "command": "extension.deleteCommentThread", + * "when": "commentThread == editable" + * } + * ] + * } + * } + * ``` + * This will show action `extension.deleteCommentThread` only for comment threads with `contextValue` is `editable`. + */ + contextValue?: string; + + /** + * The optional human-readable label describing the {@link CommentThread Comment Thread} + */ + label?: string; + + /** + * The optional state of a comment thread, which may affect how the comment is displayed. + */ + state?: CommentThreadState; + + /** + * Dispose this comment thread. + * + * Once disposed, this comment thread will be removed from visible editors and Comment Panel when appropriate. + */ + dispose(): void; + } + + export interface CommentController { + createCommentThread(uri: Uri, range: Range | undefined, comments: readonly Comment[]): CommentThread | CommentThread2; + } + + export interface CommentingRangeProvider2 { + /** + * Provide a list of ranges which allow new comment threads creation or null for a given document + */ + provideCommentingRanges(document: TextDocument, token: CancellationToken): ProviderResult; + } +} diff --git a/src/vscode-dts/vscode.proposed.getSessions.d.ts b/src/vscode-dts/vscode.proposed.getSessions.d.ts new file mode 100644 index 00000000000..f94ab74d821 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.getSessions.d.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + // https://github.com/microsoft/vscode/issues/152399 + + export namespace authentication { + /** + * Get all authentication sessions matching the desired scopes that this extension has access to. In order to request access, + * use {@link getSession}. To request an additional account, specify {@link AuthenticationGetSessionOptions.clearSessionPreference} + * and {@link AuthenticationGetSessionOptions.createIfNone} together. + * + * Currently, there are only two authentication providers that are contributed from built in extensions + * to the editor that implement GitHub and Microsoft authentication: their providerId's are 'github' and 'microsoft'. + * + * @param providerId The id of the provider to use + * @param scopes A list of scopes representing the permissions requested. These are dependent on the authentication provider + * @returns A thenable that resolves to a readonly array of authentication sessions. + */ + export function getSessions(providerId: string, scopes: readonly string[]): Thenable; + } +} diff --git a/src/vscode-dts/vscode.proposed.interactive.d.ts b/src/vscode-dts/vscode.proposed.interactive.d.ts new file mode 100644 index 00000000000..d0897c7c859 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.interactive.d.ts @@ -0,0 +1,228 @@ +/*--------------------------------------------------------------------------------------------- + * 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 InteractiveEditorSlashCommand { + command: string; + detail?: string; + refer?: boolean; + // kind: CompletionItemKind; + } + + // todo@API make classes + export interface InteractiveEditorSession { + placeholder?: string; + slashCommands?: InteractiveEditorSlashCommand[]; + wholeRange?: Range; + } + + // todo@API make classes + export interface InteractiveEditorRequest { + session: InteractiveEditorSession; + prompt: string; + + selection: Selection; + wholeRange: Range; + } + + // todo@API make classes + export interface InteractiveEditorResponse { + edits: TextEdit[] | WorkspaceEdit; + placeholder?: string; + wholeRange?: Range; + } + + // todo@API make classes + export interface InteractiveEditorMessageResponse { + contents: MarkdownString; + placeholder?: string; + wholeRange?: Range; + } + + export enum InteractiveEditorResponseFeedbackKind { + Unhelpful = 0, + Helpful = 1, + Undone = 2 + } + + export interface TextDocumentContext { + document: TextDocument; + selection: Selection; + action?: string; + } + + export interface InteractiveEditorSessionProvider { + // Create a session. The lifetime of this session is the duration of the editing session with the input mode widget. + prepareInteractiveEditorSession(context: TextDocumentContext, token: CancellationToken): ProviderResult; + + provideInteractiveEditorResponse(request: InteractiveEditorRequest, token: CancellationToken): ProviderResult; + + // eslint-disable-next-line local/vscode-dts-provider-naming + releaseInteractiveEditorSession?(session: S): any; + + // todo@API use enum instead of boolean + // eslint-disable-next-line local/vscode-dts-provider-naming + handleInteractiveEditorResponseFeedback?(session: S, response: R, kind: InteractiveEditorResponseFeedbackKind): void; + } + + + export interface InteractiveSessionState { } + + export interface InteractiveSessionParticipantInformation { + name: string; + + /** + * A full URI for the icon of the participant. + */ + icon?: Uri; + } + + export interface InteractiveSession { + requester: InteractiveSessionParticipantInformation; + responder: InteractiveSessionParticipantInformation; + inputPlaceholder?: string; + + saveState?(): InteractiveSessionState; + } + + export interface InteractiveSessionRequestArgs { + command: string; + args: any; + } + + export interface InteractiveRequest { + session: InteractiveSession; + message: string | InteractiveSessionReplyFollowup; + } + + export interface InteractiveResponseErrorDetails { + message: string; + responseIsIncomplete?: boolean; + responseIsFiltered?: boolean; + } + + export interface InteractiveResponseForProgress { + errorDetails?: InteractiveResponseErrorDetails; + } + + export interface InteractiveProgressContent { + content: string; + } + + export interface InteractiveProgressId { + responseId: string; + } + + export type InteractiveProgress = InteractiveProgressContent | InteractiveProgressId; + + export interface InteractiveResponseCommand { + commandId: string; + args?: any[]; + title: string; // supports codicon strings + } + + export interface InteractiveSessionSlashCommand { + command: string; + kind: CompletionItemKind; + detail?: string; + } + + export interface InteractiveSessionReplyFollowup { + message: string; + tooltip?: string; + title?: string; + + // Extensions can put any serializable data here, such as an ID/version + metadata?: any; + } + + export type InteractiveSessionFollowup = InteractiveSessionReplyFollowup | InteractiveResponseCommand; + + export type InteractiveWelcomeMessageContent = string | InteractiveSessionReplyFollowup[]; + + export interface InteractiveSessionProvider { + provideInitialSuggestions?(token: CancellationToken): ProviderResult; + provideWelcomeMessage?(token: CancellationToken): ProviderResult; + provideFollowups?(session: InteractiveSession, token: CancellationToken): ProviderResult<(string | InteractiveSessionFollowup)[]>; + provideSlashCommands?(session: InteractiveSession, token: CancellationToken): ProviderResult; + + prepareSession(initialState: InteractiveSessionState | undefined, token: CancellationToken): ProviderResult; + resolveRequest(session: InteractiveSession, context: InteractiveSessionRequestArgs | string, token: CancellationToken): ProviderResult; + provideResponseWithProgress(request: InteractiveRequest, progress: Progress, token: CancellationToken): ProviderResult; + } + + export enum InteractiveSessionVoteDirection { + Up = 1, + Down = 2 + } + + export interface InteractiveSessionVoteAction { + kind: 'vote'; + responseId: string; + direction: InteractiveSessionVoteDirection; + } + + export enum InteractiveSessionCopyKind { + // Keyboard shortcut or context menu + Action = 1, + Toolbar = 2 + } + + export interface InteractiveSessionCopyAction { + kind: 'copy'; + responseId: string; + codeBlockIndex: number; + copyType: InteractiveSessionCopyKind; + copiedCharacters: number; + totalCharacters: number; + copiedText: string; + } + + export interface InteractiveSessionInsertAction { + kind: 'insert'; + responseId: string; + codeBlockIndex: number; + } + + export interface InteractiveSessionCommandAction { + kind: 'command'; + command: InteractiveResponseCommand; + } + + export type InteractiveSessionUserAction = InteractiveSessionVoteAction | InteractiveSessionCopyAction | InteractiveSessionInsertAction | InteractiveSessionCommandAction; + + export interface InteractiveSessionUserActionEvent { + action: InteractiveSessionUserAction; + providerId: string; + } + + export interface InteractiveSessionDynamicRequest { + /** + * The message that will be displayed in the UI + */ + message: string; + + /** + * Any extra metadata/context that will go to the provider. + * NOTE not actually used yet. + */ + metadata?: any; + } + + export namespace interactive { + // current version of the proposal. + export const _version: 1 | number; + + export function registerInteractiveSessionProvider(id: string, provider: InteractiveSessionProvider): Disposable; + export function addInteractiveRequest(context: InteractiveSessionRequestArgs): void; + + export function sendInteractiveRequestToProvider(providerId: string, message: InteractiveSessionDynamicRequest): void; + + export function registerInteractiveEditorSessionProvider(provider: InteractiveEditorSessionProvider): Disposable; + + export const onDidPerformUserAction: Event; + } +} diff --git a/src/vscode-dts/vscode.proposed.notebookDocumentWillSave.d.ts b/src/vscode-dts/vscode.proposed.notebookDocumentWillSave.d.ts new file mode 100644 index 00000000000..e751bbcf669 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.notebookDocumentWillSave.d.ts @@ -0,0 +1,39 @@ +/*--------------------------------------------------------------------------------------------- + * 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' { + /** + * An event that is fired when a {@link NotebookDocument document} will be saved. + * + * To make modifications to the document before it is being saved, call the + * {@linkcode NotebookDocumentWillSaveEvent.waitUntil waitUntil}-function with a thenable + * that resolves to an array of {@link TextEdit text edits}. + */ + export interface NotebookDocumentWillSaveEvent { + /** + * A cancellation token. + */ + readonly token: CancellationToken; + + /** + * The document that will be saved. + */ + readonly document: NotebookDocument; + + /** + * The reason why save was triggered. + */ + readonly reason: TextDocumentSaveReason; + + waitUntil(thenable: Thenable): void; + + waitUntil(thenable: Thenable): void; + } + + export namespace workspace { + + export const onWillSaveNotebookDocument: Event; + } +} diff --git a/src/vscode-dts/vscode.proposed.testContinuousRun.d.ts b/src/vscode-dts/vscode.proposed.testContinuousRun.d.ts deleted file mode 100644 index bb6240132a9..00000000000 --- a/src/vscode-dts/vscode.proposed.testContinuousRun.d.ts +++ /dev/null @@ -1,66 +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' { - export interface TestRunProfile { - /** - * Whether this profile supports continuous running of requests. If so, - * then {@link TestRunRequest.continuous} may be set to `true`. Defaults - * to false. - */ - supportsContinuousRun: boolean; - - /** - * Handler called to start a test run. When invoked, the function should call - * {@link TestController.createTestRun} at least once, and all test runs - * associated with the request should be created before the function returns - * or the returned promise is resolved. - * - * If {@link supportsContinuousRun} is set, then {@link TestRunRequest2.continuous} - * may be `true`. In this case, the profile should observe changes to - * source code and create new test runs by calling {@link TestController.createTestRun}, - * until the cancellation is requested on the `token`. - * - * @param request Request information for the test run. - * @param cancellationToken Token that signals the used asked to abort the - * test run. If cancellation is requested on this token, all {@link TestRun} - * instances associated with the request will be - * automatically cancelled as well. - */ - runHandler: (request: TestRunRequest, token: CancellationToken) => Thenable | void; - } - - export interface TestController { - /** - * Creates a profile used for running tests. Extensions must create - * at least one profile in order for tests to be run. - * @param label A human-readable label for this profile. - * @param kind Configures what kind of execution this profile manages. - * @param runHandler Function called to start a test run. - * @param isDefault Whether this is the default action for its kind. - * @param tag Profile test tag. - * @param supportsContinuousRun Whether the profile supports continuous running. - * @returns An instance of a {@link TestRunProfile}, which is automatically - * associated with this controller. - */ - createRunProfile(label: string, kind: TestRunProfileKind, runHandler: (request: TestRunRequest, token: CancellationToken) => Thenable | void, isDefault?: boolean, tag?: TestTag, supportsContinuousRun?: boolean): TestRunProfile; - } - - export class TestRunRequest2 extends TestRunRequest { - /** - * Whether the profile should run continuously as source code changes. Only - * relevant for profiles that set {@link TestRunProfile.supportsContinuousRun}. - */ - readonly continuous?: boolean; - - /** - * @param tests Array of specific tests to run, or undefined to run all tests - * @param exclude An array of tests to exclude from the run. - * @param profile The run profile used for this request. - * @param continuous Whether to run tests continuously as source changes. - */ - constructor(include?: readonly TestItem[], exclude?: readonly TestItem[], profile?: TestRunProfile, continuous?: boolean); - } -} diff --git a/test/automation/src/playwrightBrowser.ts b/test/automation/src/playwrightBrowser.ts index 808da87137b..7d35ba9517a 100644 --- a/test/automation/src/playwrightBrowser.ts +++ b/test/automation/src/playwrightBrowser.ts @@ -22,11 +22,11 @@ export async function launch(options: LaunchOptions): Promise<{ serverProcess: C const { serverProcess, endpoint } = await launchServer(options); // Launch browser - const { browser, context, page } = await launchBrowser(options, endpoint); + const { browser, context, page, pageLoadedPromise } = await launchBrowser(options, endpoint); return { serverProcess, - driver: new PlaywrightDriver(browser, context, page, serverProcess, options) + driver: new PlaywrightDriver(browser, context, page, serverProcess, pageLoadedPromise, options) }; } @@ -88,7 +88,11 @@ async function launchServer(options: LaunchOptions) { async function launchBrowser(options: LaunchOptions, endpoint: string) { const { logger, workspacePath, tracing, headless } = options; - const browser = await measureAndLog(() => playwright[options.browser ?? 'chromium'].launch({ headless: headless ?? false }), 'playwright#launch', logger); + const browser = await measureAndLog(() => playwright[options.browser ?? 'chromium'].launch({ + headless: headless ?? false, + timeout: 0 + }), 'playwright#launch', logger); + browser.on('disconnected', () => logger.log(`Playwright: browser disconnected`)); const context = await measureAndLog(() => browser.newContext(), 'browser.newContext', logger); @@ -133,9 +137,12 @@ async function launchBrowser(options: LaunchOptions, endpoint: string) { `["logLevel","${options.verbose ? 'trace' : 'info'}"]` ].join(',')}]`; - await measureAndLog(() => page.goto(`${endpoint}&${workspacePath.endsWith('.code-workspace') ? 'workspace' : 'folder'}=${URI.file(workspacePath!).path}&payload=${payloadParam}`), 'page.goto()', logger); + const gotoPromise = measureAndLog(() => page.goto(`${endpoint}&${workspacePath.endsWith('.code-workspace') ? 'workspace' : 'folder'}=${URI.file(workspacePath!).path}&payload=${payloadParam}`), 'page.goto()', logger); + const pageLoadedPromise = page.waitForLoadState('load'); - return { browser, context, page }; + await gotoPromise; + + return { browser, context, page, pageLoadedPromise }; } function waitForEndpoint(server: ChildProcess, logger: Logger): Promise { diff --git a/test/automation/src/playwrightDriver.ts b/test/automation/src/playwrightDriver.ts index 3425d11a74c..1c21a31bb59 100644 --- a/test/automation/src/playwrightDriver.ts +++ b/test/automation/src/playwrightDriver.ts @@ -36,6 +36,7 @@ export class PlaywrightDriver { private readonly context: playwright.BrowserContext, private readonly page: playwright.Page, private readonly serverProcess: ChildProcess | undefined, + private readonly whenLoaded: Promise, private readonly options: LaunchOptions ) { } @@ -78,17 +79,7 @@ export class PlaywrightDriver { } async didFinishLoad(): Promise { - - // Web: via `load` state - if (this.options.web) { - return this.page.waitForLoadState('load'); - } - - // Desktop: via `window` event - return new Promise(resolve => { - // https://playwright.dev/docs/api/class-electronapplication#electron-application-event-window - (this.application as playwright.ElectronApplication).on('window', () => resolve()); - }); + await this.whenLoaded; } private async takeScreenshot(name: string): Promise { @@ -180,7 +171,7 @@ export class PlaywrightDriver { } async getTitle() { - return this.evaluateWithDriver(([driver]) => driver.getTitle()); + return this.page.title(); } async isActiveElement(selector: string) { diff --git a/test/automation/src/playwrightElectron.ts b/test/automation/src/playwrightElectron.ts index 83ed79e9047..660320be235 100644 --- a/test/automation/src/playwrightElectron.ts +++ b/test/automation/src/playwrightElectron.ts @@ -22,7 +22,7 @@ export async function launch(options: LaunchOptions): Promise<{ electronProcess: return { electronProcess, - driver: new PlaywrightDriver(electron, context, page, undefined /* no server process */, options) + driver: new PlaywrightDriver(electron, context, page, undefined /* no server process */, Promise.resolve() /* Window is open already */, options) }; } @@ -32,10 +32,14 @@ async function launchElectron(configuration: IElectronConfiguration, options: La const electron = await measureAndLog(() => playwright._electron.launch({ executablePath: configuration.electronPath, args: configuration.args, - env: configuration.env as { [key: string]: string } + env: configuration.env as { [key: string]: string }, + timeout: 0 }), 'playwright-electron#launch', logger); - const window = await measureAndLog(() => electron.firstWindow(), 'playwright-electron#firstWindow', logger); + let window = electron.windows()[0]; + if (!window) { + window = await measureAndLog(() => electron.waitForEvent('window', { timeout: 0 }), 'playwright-electron#firstWindow', logger); + } const context = window.context(); diff --git a/test/automation/src/search.ts b/test/automation/src/search.ts index f05e5b8668c..844003955e7 100644 --- a/test/automation/src/search.ts +++ b/test/automation/src/search.ts @@ -35,7 +35,7 @@ export class Search extends Viewlet { async clearSearchResults(): Promise { await retry( - () => this.code.waitAndClick(`.sidebar .codicon-search-clear-results`), + () => this.code.waitAndClick(`.sidebar .title-actions .codicon-search-clear-results`), () => this.waitForNoResultText(10)); } diff --git a/test/unit/electron/index.js b/test/unit/electron/index.js index 60cdcfd4ba3..a338a2d6ab0 100644 --- a/test/unit/electron/index.js +++ b/test/unit/electron/index.js @@ -182,7 +182,7 @@ app.on('ready', () => { width: 800, show: false, webPreferences: { - preload: path.join(__dirname, '..', '..', '..', 'src', 'vs', 'base', 'parts', 'sandbox', 'electron-browser', 'preload.js'), // ensure similar environment as VSCode as tests may depend on this + preload: path.join(__dirname, '..', '..', '..', 'src', 'vs', 'base', 'parts', 'sandbox', 'electron-sandbox', 'preload.js'), // ensure similar environment as VSCode as tests may depend on this additionalArguments: [`--vscode-window-config=vscode:test-vscode-window-config`], nodeIntegration: true, contextIsolation: false, diff --git a/yarn.lock b/yarn.lock index 2b3fa64c4ee..7eabceca09c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -340,21 +340,38 @@ esquery "^1.4.0" jsdoc-type-pratt-parser "~3.1.0" -"@eslint/eslintrc@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.5.tgz#33f1b838dbf1f923bfa517e008362b78ddbbf318" - integrity sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ== +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.4.1.tgz#087cb8d9d757bb22e9c9946c9c0c2bf8806830f1" + integrity sha512-BISJ6ZE4xQsuL/FmsyRaiffpq977bMlsKfGHTQrOGFErfByxIe6iZTxPf/00Zon9b9a7iUykfQwejN3s2ZW/Bw== + +"@eslint/eslintrc@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.1.tgz#7888fe7ec8f21bc26d646dbd2c11cd776e21192d" + integrity sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.2.0" - globals "^13.9.0" - ignore "^4.0.6" + espree "^9.5.0" + globals "^13.19.0" + ignore "^5.2.0" import-fresh "^3.2.1" js-yaml "^4.1.0" - minimatch "^3.0.4" + minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@eslint/js@8.36.0": + version "8.36.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.36.0.tgz#9837f768c03a1e4a30bd304a64fb8844f0e72efe" + integrity sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg== + "@gulp-sourcemaps/identity-map@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz#a6e8b1abec8f790ec6be2b8c500e6e68037c0019" @@ -374,14 +391,19 @@ normalize-path "^2.0.1" through2 "^2.0.3" -"@humanwhocodes/config-array@^0.9.2": - version "0.9.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914" - integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA== +"@humanwhocodes/config-array@^0.11.8": + version "0.11.8" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" + integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" - minimatch "^3.0.4" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" @@ -502,11 +524,24 @@ "@nodelib/fs.stat" "2.0.3" run-parallel "^1.1.9" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + "@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": version "2.0.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== +"@nodelib/fs.stat@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + "@nodelib/fs.walk@^1.2.3": version "1.2.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" @@ -515,6 +550,14 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" +"@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + "@npmcli/move-file@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.0.1.tgz#de103070dac0f48ce49cf6693c23af59c0f70464" @@ -638,13 +681,15 @@ node-addon-api "^3.2.1" node-gyp-build "^4.3.0" -"@playwright/test@1.27.1": - version "1.27.1" - resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.27.1.tgz#9364d1e02021261211c8ff586d903faa79ce95c4" - integrity sha512-mrL2q0an/7tVqniQQF6RBL2saskjljXzqNcCOVMUjRIgE6Y38nCNaP+Dc2FBW06bcpD3tqIws/HT9qiMHbNU0A== +"@playwright/test@1.32.1": + version "1.32.1" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.32.1.tgz#749c9791adb048c266277a39ba0f7e33fe593ffe" + integrity sha512-FTwjCuhlm1qHUGf4hWjfr64UMJD/z0hXYbk+O387Ioe6WdyZQ+0TBDAc6P+pHjx2xCv1VYNgrKbYrNixFWy4Dg== dependencies: "@types/node" "*" - playwright-core "1.27.1" + playwright-core "1.32.1" + optionalDependencies: + fsevents "2.3.2" "@sindresorhus/is@^0.14.0": version "0.14.0" @@ -1003,6 +1048,11 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ== +"@types/semver@^7.3.12": + version "7.3.13" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" + integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== + "@types/sinon-test@^2.4.2": version "2.4.2" resolved "https://registry.yarnpkg.com/@types/sinon-test/-/sinon-test-2.4.2.tgz#f55bdf5486e7b7a4dd7257789fcc2b7b125c4164" @@ -1124,91 +1174,95 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@^5.39.0": - version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz#778b2d9e7f293502c7feeea6c74dca8eb3e67511" - integrity sha512-xVfKOkBm5iWMNGKQ2fwX5GVgBuHmZBO1tCRwXmY5oAIsPscfwm2UADDuNB8ZVYCtpQvJK4xpjrK7jEhcJ0zY9A== +"@typescript-eslint/eslint-plugin@^5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.57.0.tgz#52c8a7a4512f10e7249ca1e2e61f81c62c34365c" + integrity sha512-itag0qpN6q2UMM6Xgk6xoHa0D0/P+M17THnr4SVgqn9Rgam5k/He33MA7/D7QoJcdMxHFyX7U9imaBonAX/6qA== dependencies: - "@typescript-eslint/scope-manager" "5.39.0" - "@typescript-eslint/type-utils" "5.39.0" - "@typescript-eslint/utils" "5.39.0" + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.57.0" + "@typescript-eslint/type-utils" "5.57.0" + "@typescript-eslint/utils" "5.57.0" debug "^4.3.4" + grapheme-splitter "^1.0.4" ignore "^5.2.0" - regexpp "^3.2.0" + natural-compare-lite "^1.4.0" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@^5.39.0": - version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.39.0.tgz#9263bb72b57449cc2f07ffb7fd4e12d0160b7f5e" - integrity sha512-n5N9kG/oGu2xXhHzsWzn94s6CWoiUj59FPU2dF2IQZxPftw+q6Jm5sV2vj5qTgAElRooHhrgtl2gxBQDCPt6WA== +"@typescript-eslint/experimental-utils@^5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.57.0.tgz#e4ddb5f1c77f5be73e7d0435c8d0bf3196b9d2ed" + integrity sha512-0RnrwGQ7MmgtOSnzB/rSGYr2iXENi6L+CtPzX3g5ovo0HlruLukSEKcc4s+q0IEc+DLTDc7Edan0Y4WSQ/bFhw== dependencies: - "@typescript-eslint/utils" "5.39.0" + "@typescript-eslint/utils" "5.57.0" -"@typescript-eslint/parser@^5.39.0": - version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.39.0.tgz#93fa0bc980a3a501e081824f6097f7ca30aaa22b" - integrity sha512-PhxLjrZnHShe431sBAGHaNe6BDdxAASDySgsBCGxcBecVCi8NQWxQZMcizNA4g0pN51bBAn/FUfkWG3SDVcGlA== +"@typescript-eslint/parser@^5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.57.0.tgz#f675bf2cd1a838949fd0de5683834417b757e4fa" + integrity sha512-orrduvpWYkgLCyAdNtR1QIWovcNZlEm6yL8nwH/eTxWLd8gsP+25pdLHYzL2QdkqrieaDwLpytHqycncv0woUQ== dependencies: - "@typescript-eslint/scope-manager" "5.39.0" - "@typescript-eslint/types" "5.39.0" - "@typescript-eslint/typescript-estree" "5.39.0" + "@typescript-eslint/scope-manager" "5.57.0" + "@typescript-eslint/types" "5.57.0" + "@typescript-eslint/typescript-estree" "5.57.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.39.0": - version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz#873e1465afa3d6c78d8ed2da68aed266a08008d0" - integrity sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw== +"@typescript-eslint/scope-manager@5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.57.0.tgz#79ccd3fa7bde0758059172d44239e871e087ea36" + integrity sha512-NANBNOQvllPlizl9LatX8+MHi7bx7WGIWYjPHDmQe5Si/0YEYfxSljJpoTyTWFTgRy3X8gLYSE4xQ2U+aCozSw== dependencies: - "@typescript-eslint/types" "5.39.0" - "@typescript-eslint/visitor-keys" "5.39.0" + "@typescript-eslint/types" "5.57.0" + "@typescript-eslint/visitor-keys" "5.57.0" -"@typescript-eslint/type-utils@5.39.0": - version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz#0a8c00f95dce4335832ad2dc6bc431c14e32a0a6" - integrity sha512-KJHJkOothljQWzR3t/GunL0TPKY+fGJtnpl+pX+sJ0YiKTz3q2Zr87SGTmFqsCMFrLt5E0+o+S6eQY0FAXj9uA== +"@typescript-eslint/type-utils@5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.57.0.tgz#98e7531c4e927855d45bd362de922a619b4319f2" + integrity sha512-kxXoq9zOTbvqzLbdNKy1yFrxLC6GDJFE2Yuo3KqSwTmDOFjUGeWSakgoXT864WcK5/NAJkkONCiKb1ddsqhLXQ== dependencies: - "@typescript-eslint/typescript-estree" "5.39.0" - "@typescript-eslint/utils" "5.39.0" + "@typescript-eslint/typescript-estree" "5.57.0" + "@typescript-eslint/utils" "5.57.0" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.39.0": - version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.39.0.tgz#f4e9f207ebb4579fd854b25c0bf64433bb5ed78d" - integrity sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw== +"@typescript-eslint/types@5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.57.0.tgz#727bfa2b64c73a4376264379cf1f447998eaa132" + integrity sha512-mxsod+aZRSyLT+jiqHw1KK6xrANm19/+VFALVFP5qa/aiJnlP38qpyaTd0fEKhWvQk6YeNZ5LGwI1pDpBRBhtQ== -"@typescript-eslint/typescript-estree@5.39.0": - version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz#c0316aa04a1a1f4f7f9498e3c13ef1d3dc4cf88b" - integrity sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA== +"@typescript-eslint/typescript-estree@5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.57.0.tgz#ebcd0ee3e1d6230e888d88cddf654252d41e2e40" + integrity sha512-LTzQ23TV82KpO8HPnWuxM2V7ieXW8O142I7hQTxWIHDcCEIjtkat6H96PFkYBQqGFLW/G/eVVOB9Z8rcvdY/Vw== dependencies: - "@typescript-eslint/types" "5.39.0" - "@typescript-eslint/visitor-keys" "5.39.0" + "@typescript-eslint/types" "5.57.0" + "@typescript-eslint/visitor-keys" "5.57.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.39.0": - version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.39.0.tgz#b7063cca1dcf08d1d21b0d91db491161ad0be110" - integrity sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg== +"@typescript-eslint/utils@5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.57.0.tgz#eab8f6563a2ac31f60f3e7024b91bf75f43ecef6" + integrity sha512-ps/4WohXV7C+LTSgAL5CApxvxbMkl9B9AUZRtnEFonpIxZDIT7wC1xfvuJONMidrkB9scs4zhtRyIwHh4+18kw== dependencies: + "@eslint-community/eslint-utils" "^4.2.0" "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.39.0" - "@typescript-eslint/types" "5.39.0" - "@typescript-eslint/typescript-estree" "5.39.0" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.57.0" + "@typescript-eslint/types" "5.57.0" + "@typescript-eslint/typescript-estree" "5.57.0" eslint-scope "^5.1.1" - eslint-utils "^3.0.0" + semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.39.0": - version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz#8f41f7d241b47257b081ddba5d3ce80deaae61e2" - integrity sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg== +"@typescript-eslint/visitor-keys@5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.57.0.tgz#e2b2f4174aff1d15eef887ce3d019ecc2d7a8ac1" + integrity sha512-ery2g3k0hv5BLiKpPuwYt9KBkAp2ugT6VvyShXdLOkax895EC55sP0Tx5L0fZaQueiK3fBLvHVvEl3jFS5ia+g== dependencies: - "@typescript-eslint/types" "5.39.0" + "@typescript-eslint/types" "5.57.0" eslint-visitor-keys "^3.3.0" "@ungap/promise-all-settled@1.1.2": @@ -1234,17 +1288,17 @@ yargs "^17.5.1" "@vscode/policy-watcher@^1.1.4": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@vscode/policy-watcher/-/policy-watcher-1.1.4.tgz#a47e30c6f02d025187d8900a3e21adb2626dece5" - integrity sha512-/xYsB7PmEeEpuRIKPAqDvK8baJ6AfOhHsnPPJrje7Bpf1z2GLwRFq7pm9KjBGtcwJGInuDxQERMtX0RIERi8YA== + version "1.1.6" + resolved "https://registry.yarnpkg.com/@vscode/policy-watcher/-/policy-watcher-1.1.6.tgz#5867ff8297507dc1cc7c6f826a67bb2536a5cafe" + integrity sha512-EoJizB6aq/mgsL42mcNLGZ5vOwdZs/EHcLQkdY6Rg4uzcRkCapQdNy20wnCsrBpv3QntgBibsS6m+JXm8efY/Q== dependencies: bindings "^1.5.0" node-addon-api "^6.0.0" -"@vscode/ripgrep@^1.14.2": - version "1.14.2" - resolved "https://registry.yarnpkg.com/@vscode/ripgrep/-/ripgrep-1.14.2.tgz#47c0eec2b64f53d8f7e1b5ffd22a62e229191c34" - integrity sha512-KDaehS8Jfdg1dqStaIPDKYh66jzKd5jy5aYEPzIv0JYFLADPsCSQPBUdsJVXnr0t72OlDcj96W05xt/rSnNFFQ== +"@vscode/ripgrep@^1.15.0": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@vscode/ripgrep/-/ripgrep-1.15.0.tgz#d6fec68d7c44d594967f21a6e6c97416cc7fb2bc" + integrity sha512-qbLYP3XPTfS5a80+WnGvDLhsD01LDrs03zjbbtWWnvwt8G9hP3j8mc3ckaIid7pj86MBSTyUb/ECaIWmJIGBYw== dependencies: https-proxy-agent "^5.0.0" proxy-from-env "^1.1.0" @@ -1262,12 +1316,12 @@ resolved "https://registry.yarnpkg.com/@vscode/sudo-prompt/-/sudo-prompt-9.3.1.tgz#c562334bc6647733649fd42afc96c0eea8de3b65" integrity sha512-9ORTwwS74VaTn38tNbQhsA5U44zkJfcb0BdTSyyG6frP4e8KMtHuTXYmwefe5dpL8XB1aGSIVTaLjD3BbWb5iA== -"@vscode/telemetry-extractor@^1.9.8": - version "1.9.8" - resolved "https://registry.yarnpkg.com/@vscode/telemetry-extractor/-/telemetry-extractor-1.9.8.tgz#ffc000720ea2b9cd3421ba8a7bd172972c398b06" - integrity sha512-L27/fgC/gM7AY6AXriFGrznnX1M4Nc7VmHabYinDPoJDQYLjbSEDDVjjlSS6BiVkzc3OrFQStqXpHBhImis2eQ== +"@vscode/telemetry-extractor@^1.9.9": + version "1.9.9" + resolved "https://registry.yarnpkg.com/@vscode/telemetry-extractor/-/telemetry-extractor-1.9.9.tgz#fe1029a58181287d6ab809aae26ee877f181536c" + integrity sha512-nWuXoyXvuS1VBM+U2UQUxUC9fjkquD5QBOv1FlpVkzY+n9hJQ/G4woJdSsOdNgEKnOMUFUSByg8Bl52E4YakKw== dependencies: - "@vscode/ripgrep" "^1.14.2" + "@vscode/ripgrep" "^1.15.0" command-line-args "^5.2.1" ts-morph "^15.1.0" @@ -1624,7 +1678,7 @@ acorn-jsx@^5.0.0: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== -acorn-jsx@^5.3.1: +acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -1644,10 +1698,10 @@ acorn@^8.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== -acorn@^8.7.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== +acorn@^8.8.0: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== agent-base@4: version "4.2.0" @@ -4209,10 +4263,10 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.0.tgz#c1f6ea30ac583031f203d65c73e723b01298f153" - integrity sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg== +eslint-scope@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -4224,73 +4278,61 @@ eslint-utils@^1.3.1: dependencies: eslint-visitor-keys "^1.1.0" -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1" - integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ== - eslint-visitor-keys@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@8.7.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.7.0.tgz#22e036842ee5b7cf87b03fe237731675b4d3633c" - integrity sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w== +eslint@8.36.0: + version "8.36.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.36.0.tgz#1bd72202200a5492f91803b113fb8a83b11285cf" + integrity sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw== dependencies: - "@eslint/eslintrc" "^1.0.5" - "@humanwhocodes/config-array" "^0.9.2" + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.1" + "@eslint/js" "8.36.0" + "@humanwhocodes/config-array" "^0.11.8" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.1.0" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.2.0" - espree "^9.3.0" - esquery "^1.4.0" + eslint-scope "^7.1.1" + eslint-visitor-keys "^3.3.0" + espree "^9.5.0" + esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.6.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" - minimatch "^3.0.4" + minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.1" - regexpp "^3.2.0" strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" - v8-compile-cache "^2.0.3" eslint@^5.0.1: version "5.16.0" @@ -4343,14 +4385,14 @@ espree@^5.0.1: acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" -espree@^9.2.0, espree@^9.3.0: - version "9.3.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.0.tgz#c1240d79183b72aaee6ccfa5a90bc9111df085a8" - integrity sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ== +espree@^9.5.0: + version "9.5.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.0.tgz#3646d4e3f58907464edba852fa047e6a27bdf113" + integrity sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw== dependencies: - acorn "^8.7.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^3.1.0" + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" esprima@^4.0.0: version "4.0.1" @@ -4371,6 +4413,13 @@ esquery@^1.4.0: dependencies: estraverse "^5.1.0" +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + esrecurse@^4.1.0, esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" @@ -4765,7 +4814,7 @@ find-replace@^3.0.0: dependencies: array-back "^3.0.1" -find-up@5.0.0: +find-up@5.0.0, find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== @@ -4995,6 +5044,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@2.3.2, fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + fsevents@^1.2.7: version "1.2.13" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" @@ -5008,11 +5062,6 @@ fsevents@~2.3.1: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - fstream@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" @@ -5144,7 +5193,7 @@ glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.0, dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1: +glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -5290,10 +5339,10 @@ globals@^11.1.0, globals@^11.7.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.6.0, globals@^13.9.0: - version "13.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" - integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg== +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== dependencies: type-fest "^0.20.2" @@ -5372,6 +5421,11 @@ graceful-fs@^4.1.2, graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -6401,6 +6455,11 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^1.1: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -6649,6 +6708,11 @@ js-beautify@^1.8.9: mkdirp "~0.5.0" nopt "~4.0.1" +js-sdsl@^4.1.4: + version "4.4.0" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.0.tgz#8b437dbe642daa95760400b602378ed8ffea8430" + integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -7438,7 +7502,7 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.3, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -7702,15 +7766,20 @@ native-is-elevated@0.4.3: resolved "https://registry.yarnpkg.com/native-is-elevated/-/native-is-elevated-0.4.3.tgz#f1071c4a821acc71d43f36ff8051d3816d832e1c" integrity sha512-bHS3sCoh+raqFGIxmL/plER3eBQ+IEBy4RH/4uahhToZneTvqNKQrL0PgOTtnpL55XjBd3dy0pNtZMkCk0J48g== -native-keymap@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/native-keymap/-/native-keymap-3.3.2.tgz#de3b3161b6041be80ac754bfed44a499aa8b3409" - integrity sha512-AKE9k0jVOPrpfSlmtNDVJaADW+Vo6dDHQf55Ystvc5Aj4REbmlMSqXIBU1LpMC2pEzxzg0O2zbtQYWmqETfhzg== +native-keymap@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/native-keymap/-/native-keymap-3.3.3.tgz#cdc92331721e289605f1fb55ca4609ce52888845" + integrity sha512-TKBPTNHWK+8be1htLFNy/fsDtxv5A2z4IwvQ/XeiDkNgAthqdlImxza/dDBu3eN2lqNnFSkJl0fZ8221hV92hg== -native-watchdog@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/native-watchdog/-/native-watchdog-1.4.1.tgz#f5462cb878796c75f8a6c3c71aa0aa52d4992e05" - integrity sha512-RzGXNgoe54BmkkIFwegz7eeJm7xovTj/VG5qREfF+KeSqiVzHGnVwFoLzNLlYsqSSdIOIYoCOFlEhoS+asRVyQ== +native-watchdog@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/native-watchdog/-/native-watchdog-1.4.2.tgz#cf9f913157ee992723aa372b6137293c663be9b7" + integrity sha512-iT3Uj6FFdrW5vHbQ/ybiznLus9oiUoMJ8A8nyugXv9rV3EBhIodmGs+mztrwQyyBc+PB5/CrskAH/WxaUVRRSQ== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== natural-compare@^1.4.0: version "1.4.0" @@ -7833,10 +7902,10 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-pty@0.11.0-beta29: - version "0.11.0-beta29" - resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.11.0-beta29.tgz#863bce79346b453ed199614686008d1a3220abe8" - integrity sha512-pkSldLXjjwFrGd3EJWI0Pu1jnxeQaW0P9i2EQtO2RaK/pZ22pf99lQ8OfptYTPK2oKZbkjwzqh05uJJ2krH9iA== +node-pty@0.11.0-beta31: + version "0.11.0-beta31" + resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.11.0-beta31.tgz#f1e7b79d437a96b50c23580475eb7d4bdceb577f" + integrity sha512-fqsvKbdP1NuaFxu2zXborL/b5+CDrLruRK7CU0YaTjgbrYUsCR6IITCs1mORb1ZpIZ26ccvcc8TVfstGqwgl9g== dependencies: nan "^2.17.0" @@ -8577,16 +8646,16 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -playwright-core@1.27.1: - version "1.27.1" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.27.1.tgz#840ef662e55a3ed759d8b5d3d00a5f885a7184f4" - integrity sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q== - playwright-core@1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.30.0.tgz#de987cea2e86669e3b85732d230c277771873285" integrity sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g== +playwright-core@1.32.1: + version "1.32.1" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.32.1.tgz#5a10c32403323b07d75ea428ebeed866a80b76a1" + integrity sha512-KZYUQC10mXD2Am1rGlidaalNGYk3LU1vZqqNk0gT4XPty1jOqgup8KDP8l2CUlqoNKhXM5IfGjWgW37xvGllBA== + playwright@^1.29.2: version "1.30.0" resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.30.0.tgz#b1d7be2d45d97fbb59f829f36f521f12010fe072" @@ -9329,11 +9398,6 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - remove-bom-buffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" @@ -11011,10 +11075,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.0.0-dev.20230209: - version "5.0.0-dev.20230209" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.0-dev.20230209.tgz#d7c763483e62f745f0bfa1610ffab76fbdce83ac" - integrity sha512-EKEs7zC40JV4BTgxULx8oDWSya4r2FeqSVpwuK7ZRu4OBErBo8n59wBAR6r+NBbkxG8JzxMOE2+fazbu/nLi9A== +typescript@^5.1.0-dev.20230328: + version "5.1.0-dev.20230328" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.0-dev.20230328.tgz#00e4f9d9ac4c7c7b17add10949a7b950ddf3f6d5" + integrity sha512-pylwLhhCSsZX72UUJTSD+5DKoEUUKsqQg6w4bLdRVbYVXDCxPLExUayWWCaRSmx9WJjf00YwMA2MXS2z2t5+2g== typical@^4.0.0: version "4.0.0" @@ -11248,11 +11312,6 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -v8-compile-cache@^2.0.3: - version "2.2.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" - integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== - v8-compile-cache@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" @@ -11452,10 +11511,10 @@ vscode-regexpp@^3.1.0: resolved "https://registry.yarnpkg.com/vscode-regexpp/-/vscode-regexpp-3.1.0.tgz#42d059b6fffe99bd42939c0d013f632f0cad823f" integrity sha512-pqtN65VC1jRLawfluX4Y80MMG0DHJydWhe5ZwMHewZD6sys4LbU6lHwFAHxeuaVE6Y6+xZOtAw+9hvq7/0ejkg== -vscode-textmate@8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" - integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== +vscode-textmate@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-9.0.0.tgz#313c6c8792b0507aef35aeb81b6b370b37c44d6c" + integrity sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg== vscode-uri@^3.0.7: version "3.0.7" @@ -11838,10 +11897,10 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" -xterm-addon-canvas@0.4.0-beta.7: - version "0.4.0-beta.7" - resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.4.0-beta.7.tgz#ae365d8e10c900292186529f70f7f275ac94b3d5" - integrity sha512-r1hbQTsulI49orR5G3qWrJCwn2dKsEUCrgj6xsmgXuTeoUcGfed6lly+MvYlL3P8aPrxS2fC2TEzSM0Au4SX+w== +xterm-addon-canvas@0.4.0-beta.9: + version "0.4.0-beta.9" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.4.0-beta.9.tgz#e570fa4592890f92cc86706f2bba0dd128a8641d" + integrity sha512-BWRVWyUW7NY2g4BBMm3ecPQvbdyKXFgABnpmh4m0TVHqFJMNeXdNuTc94KiDbE+cvw8jtAY9NC/OIM4HcgjAIQ== xterm-addon-search@0.11.0: version "0.11.0" @@ -11858,20 +11917,20 @@ xterm-addon-unicode11@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-webgl@0.15.0-beta.7: - version "0.15.0-beta.7" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.15.0-beta.7.tgz#ab247b499f61e8eebff92e08ec5ca999d87e06af" - integrity sha512-7WCI/D6uFNp3y9TeTsbSo1h7gCy4h/yP2lWn8ZEjCaiGvO11DbKMq17fbiwaR3YmGWXoRKkcLaNIiqxFnjKO4w== +xterm-addon-webgl@0.15.0-beta.8: + version "0.15.0-beta.8" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.15.0-beta.8.tgz#2005198582f6f1f4a9b2612b9354c0bcc9f148d8" + integrity sha512-HjTr9bi3FvdOIPaaIpih6qdHX2z+H7sQPluLj5KzwCqRiEVUVRi19dl8SdHjf6dCmN3GahMhjV7D+zxHi2pLTw== -xterm-headless@5.2.0-beta.29: - version "5.2.0-beta.29" - resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.2.0-beta.29.tgz#dd08312fdb4292c217e685d9e2e8b1957364e298" - integrity sha512-1P4urIeDTkl2C+zGb4WUnKJMACZMPGYHwVXMjkB0WhMISbkt6M34MH9ljxHhnL99dHwlx2Lvi6wvhnpyZucWCg== +xterm-headless@5.2.0-beta.35: + version "5.2.0-beta.35" + resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.2.0-beta.35.tgz#8c3d4d06747e27a5bc4f0bf914479820a5b8f529" + integrity sha512-tq/zKnXEsVXGlhXHGNqPO47x9Fvew2avZ0wfMI1G80AEYrjxGY/3Quxwe9/C5ngIuPwk2CMbgDZwHhSFvyOrMA== -xterm@5.2.0-beta.29: - version "5.2.0-beta.29" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.29.tgz#99764aff5cd8cdb4335f5d59466b134cfcb45e3e" - integrity sha512-zx5RKcQqo78bza4R/m3WtxAJCBAF4U61fy6cxqb1PkqXF9/qdYlySUCVOauMxv+6n6cAxt3EQWwLlgvbvQBbsw== +xterm@5.2.0-beta.35: + version "5.2.0-beta.35" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.35.tgz#4a0c0aa81c89c42167c22d023648cced44fa3c25" + integrity sha512-6x6i61lucRrLWRKFeMO/ZOx5anvYR6FHpReLO2g0y1bp5zYWyZFzM6DepMV50729gubzxSLB8mvbmb9EpeIugQ== y18n@^3.2.1: version "3.2.2"