diff --git a/.github/workflows/locker.yml b/.github/workflows/locker.yml index 5860349a437..cc6e89aa6da 100644 --- a/.github/workflows/locker.yml +++ b/.github/workflows/locker.yml @@ -21,8 +21,8 @@ jobs: uses: ./actions/locker with: daysSinceClose: 45 - appInsightsKey: ${{secrets.TRIAGE_ACTIONS_APP_INSIGHTS}} daysSinceUpdate: 3 ignoredLabel: "*out-of-scope,accessibility" ignoreLabelUntil: "author-verification-requested" + ignoredMilestones: "Backlog Candidates" labelUntil: "verified" diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index 41c33f3f265..9a3748ed6fc 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -135,13 +135,22 @@ steps: - script: | set -e - AZURE_STORAGE_ACCOUNT="ticino" \ + AZURE_STORAGE_ACCOUNT="vscodeweb" \ AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \ node build/azure-pipelines/upload-sourcemaps displayName: Upload sourcemaps to Azure + - script: | + set -e + AZURE_STORAGE_ACCOUNT="ticino" \ + AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ + AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ + AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \ + node build/azure-pipelines/upload-sourcemaps + displayName: Upload sourcemaps to Azure (Deprecated) + - script: ./build/azure-pipelines/common/extract-telemetry.sh displayName: Generate lists of telemetry events diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index bf43d9212cf..5e423d077c7 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -129,6 +129,15 @@ steps: node build/azure-pipelines/upload-cdn displayName: Upload to CDN + - script: | + set -e + AZURE_STORAGE_ACCOUNT="vscodeweb" \ + AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ + AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ + AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \ + node build/azure-pipelines/upload-sourcemaps out-vscode-web-min out-vscode-web-min/vs/workbench/workbench.web.main.js.map + displayName: Upload sourcemaps (Web) + # upload only the workbench.web.main.js source maps because # we just compiled these bits in the previous step and the # general task to upload source maps has already been run @@ -139,7 +148,7 @@ steps: AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \ node build/azure-pipelines/upload-sourcemaps out-vscode-web-min out-vscode-web-min/vs/workbench/workbench.web.main.js.map - displayName: Upload sourcemaps (Web) + displayName: Upload sourcemaps (Deprecated) - script: | set -e diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index 55904959778..b85425bccfc 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -71,7 +71,7 @@ const compilations = [ '.vscode/extensions/vscode-selfhost-test-provider/tsconfig.json', ]; -const getBaseUrl = out => `https://ticino.blob.core.windows.net/sourcemaps/${commit}/${out}`; +const getBaseUrl = out => `https://main.vscode-cdn.net/sourcemaps/${commit}/${out}`; const tasks = compilations.map(function (tsconfigFile) { const absolutePath = path.join(root, tsconfigFile); diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index c2b81d0cf7c..4ab7dcbc4b6 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -439,7 +439,7 @@ function tweakProductForServerWeb(product) { const minifyTask = task.define(`minify-vscode-${type}`, task.series( optimizeTask, util.rimraf(`out-vscode-${type}-min`), - optimize.minifyTask(`out-vscode-${type}`, `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`) + optimize.minifyTask(`out-vscode-${type}`, `https://main.vscode-cdn.net/sourcemaps/${commit}/core`) )); gulp.task(minifyTask); diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 3b1aeafd080..c6202c70883 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -133,7 +133,7 @@ const optimizeVSCodeTask = task.define('optimize-vscode', task.series( )); gulp.task(optimizeVSCodeTask); -const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`; +const sourceMappingURLBase = `https://main.vscode-cdn.net/sourcemaps/${commit}`; const minifyVSCodeTask = task.define('minify-vscode', task.series( optimizeVSCodeTask, util.rimraf('out-vscode-min'), diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js index 85129a523da..50c7e6fb631 100644 --- a/build/gulpfile.vscode.web.js +++ b/build/gulpfile.vscode.web.js @@ -175,7 +175,7 @@ const optimizeVSCodeWebTask = task.define('optimize-vscode-web', task.series( const minifyVSCodeWebTask = task.define('minify-vscode-web', task.series( optimizeVSCodeWebTask, util.rimraf('out-vscode-web-min'), - optimize.minifyTask('out-vscode-web', `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`) + optimize.minifyTask('out-vscode-web', `https://main.vscode-cdn.net/sourcemaps/${commit}/core`) )); gulp.task(minifyVSCodeWebTask); diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 6a6c0a7b4cd..58d4d3e9a7f 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -34,7 +34,7 @@ const getVersion_1 = require("./getVersion"); const fetch_1 = require("./fetch"); const root = path.dirname(path.dirname(__dirname)); const commit = (0, getVersion_1.getVersion)(root); -const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`; +const sourceMappingURLBase = `https://main.vscode-cdn.net/sourcemaps/${commit}`; function minifyExtensionResources(input) { const jsonFilter = filter(['**/*.json', '**/*.code-snippets'], { restore: true }); return input diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 6edfdcb63fb..0582e0cb11e 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -28,7 +28,7 @@ import { fetchUrls, fetchGithub } from './fetch'; const root = path.dirname(path.dirname(__dirname)); const commit = getVersion(root); -const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`; +const sourceMappingURLBase = `https://main.vscode-cdn.net/sourcemaps/${commit}`; function minifyExtensionResources(input: Stream): Stream { const jsonFilter = filter(['**/*.json', '**/*.code-snippets'], { restore: true }); diff --git a/extensions/git/package.json b/extensions/git/package.json index dfbb29289db..23b3220a00c 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -3401,7 +3401,7 @@ "@vscode/iconv-lite-umd": "0.7.0", "byline": "^5.0.0", "file-type": "16.5.4", - "jschardet": "3.0.0", + "jschardet": "3.1.2", "picomatch": "2.3.1", "vscode-uri": "^2.0.0", "which": "4.0.0" diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index 266157e9e5c..06023a61227 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -182,10 +182,10 @@ isexe@^3.1.1: resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d" integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ== -jschardet@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" - integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== +jschardet@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.1.2.tgz#9bf4364deba0677fe9e3bd9e29eda57febf2e9db" + integrity sha512-mw3CBZGzW8nUBPYhFU2ztZ/kJ6NClQUQVpyzvFMfznZsoC///ZQ30J2RCUanNsr5yF22LqhgYr/lj807/ZleWA== peek-readable@^4.1.0: version "4.1.0" diff --git a/extensions/package.json b/extensions/package.json index 2c83af40936..5475af18d40 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -4,7 +4,7 @@ "license": "MIT", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "5.4.5" + "typescript": "^5.5.0-dev.20240603" }, "scripts": { "postinstall": "node ./postinstall.mjs" diff --git a/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts b/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts index f96f89452b9..bddd062b3e8 100644 --- a/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts +++ b/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts @@ -191,7 +191,6 @@ export default class FileConfigurationManager extends Disposable { includeCompletionsWithClassMemberSnippets: config.get('suggest.classMemberSnippets.enabled', true), includeCompletionsWithObjectLiteralMethodSnippets: config.get('suggest.objectLiteralMethodSnippets.enabled', true), autoImportFileExcludePatterns: this.getAutoImportFileExcludePatternsPreference(preferencesConfig, vscode.workspace.getWorkspaceFolder(document.uri)?.uri), - // @ts-expect-error until 5.3 #56090 preferTypeOnlyAutoImports: preferencesConfig.get('preferTypeOnlyAutoImports', false), useLabelDetailsInCompletionEntries: true, allowIncompleteCompletions: true, diff --git a/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts b/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts index 900d66f37ab..747e7c22e37 100644 --- a/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts +++ b/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts @@ -19,70 +19,5 @@ declare module '../../../../node_modules/typescript/lib/typescript' { interface Response { readonly _serverType?: ServerType; } - - //#region MapCode - export interface MapCodeRequestArgs extends FileRequestArgs { - /** - * The files and changes to try and apply/map. - */ - mapping: MapCodeRequestDocumentMapping; - } - - export interface MapCodeRequestDocumentMapping { - /** - * The specific code to map/insert/replace in the file. - */ - contents: string[]; - - /** - * Areas of "focus" to inform the code mapper with. For example, cursor - * location, current selection, viewport, etc. Nested arrays denote - * priority: toplevel arrays are more important than inner arrays, and - * inner array priorities are based on items within that array. Items - * earlier in the arrays have higher priority. - */ - focusLocations?: TextSpan[][]; - } - - export interface MapCodeRequest extends FileRequest { - command: 'mapCode'; - arguments: MapCodeRequestArgs; - } - - export interface MapCodeResponse extends Response { - body: FileCodeEdits[] - } - //#endregion - - //#region Paste - export interface GetPasteEditsRequest extends Request { - command: 'getPasteEdits'; - arguments: GetPasteEditsRequestArgs; - } - - export interface GetPasteEditsRequestArgs extends FileRequestArgs { - /** The text that gets pasted in a file. */ - pastedText: string[]; - /** Locations of where the `pastedText` gets added in a file. If the length of the `pastedText` and `pastedLocations` are not the same, - * then the `pastedText` is combined into one and added at all the `pastedLocations`. - */ - pasteLocations: TextSpan[]; - /** The source location of each `pastedText`. If present, the length of `spans` must be equal to the length of `pastedText`. */ - copiedFrom?: { - file: string; - spans: TextSpan[]; - }; - } - - export interface GetPasteEditsResponse extends Response { - body: PasteEditsAction; - } - export interface PasteEditsAction { - edits: FileCodeEdits[]; - fixId?: {}; - } - //#endregion } } - - diff --git a/extensions/yarn.lock b/extensions/yarn.lock index fa4595ffa74..cb3213ad8e7 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -234,10 +234,10 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -typescript@5.4.5: - version "5.4.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" - integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== +typescript@^5.5.0-dev.20240603: + version "5.5.0-dev.20240603" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.0-dev.20240603.tgz#a1b7311df5039a8abbaaa2213c21cac6ec547490" + integrity sha512-gdm3Sh1A+Pjj9ZlfBEJY3o2rs3tvpcSbu3vYqcCijMe09BePQBtZlsuShuPn+zCnP+qBLxdKjFiw5v1tkna3tA== vscode-grammar-updater@^1.1.0: version "1.1.0" diff --git a/package.json b/package.json index 1965949114d..014e508cb07 100644 --- a/package.json +++ b/package.json @@ -82,17 +82,17 @@ "@vscode/windows-mutex": "^0.5.0", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-image": "0.9.0-beta.17", - "@xterm/addon-search": "0.16.0-beta.17", - "@xterm/addon-serialize": "0.14.0-beta.17", - "@xterm/addon-unicode11": "0.9.0-beta.17", - "@xterm/addon-webgl": "0.19.0-beta.17", - "@xterm/headless": "5.6.0-beta.17", - "@xterm/xterm": "5.6.0-beta.17", + "@xterm/addon-image": "0.9.0-beta.19", + "@xterm/addon-search": "0.16.0-beta.19", + "@xterm/addon-serialize": "0.14.0-beta.19", + "@xterm/addon-unicode11": "0.9.0-beta.19", + "@xterm/addon-webgl": "0.19.0-beta.19", + "@xterm/headless": "5.6.0-beta.19", + "@xterm/xterm": "5.6.0-beta.19", "graceful-fs": "4.2.11", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", - "jschardet": "3.0.0", + "jschardet": "3.1.2", "kerberos": "^2.0.1", "minimist": "^1.2.6", "native-is-elevated": "0.7.0", @@ -208,7 +208,7 @@ "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "tsec": "0.2.7", - "typescript": "^5.5.0-dev.20240521", + "typescript": "^5.5.0-dev.20240603", "util": "^0.12.4", "vscode-nls-dev": "^3.3.1", "webpack": "^5.91.0", diff --git a/remote/package.json b/remote/package.json index b84f5136fb1..0641f0779dd 100644 --- a/remote/package.json +++ b/remote/package.json @@ -14,18 +14,18 @@ "@vscode/vscode-languagedetection": "1.0.21", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-image": "0.9.0-beta.17", - "@xterm/addon-search": "0.16.0-beta.17", - "@xterm/addon-serialize": "0.14.0-beta.17", - "@xterm/addon-unicode11": "0.9.0-beta.17", - "@xterm/addon-webgl": "0.19.0-beta.17", - "@xterm/headless": "5.6.0-beta.17", - "@xterm/xterm": "5.6.0-beta.17", + "@xterm/addon-image": "0.9.0-beta.19", + "@xterm/addon-search": "0.16.0-beta.19", + "@xterm/addon-serialize": "0.14.0-beta.19", + "@xterm/addon-unicode11": "0.9.0-beta.19", + "@xterm/addon-webgl": "0.19.0-beta.19", + "@xterm/headless": "5.6.0-beta.19", + "@xterm/xterm": "5.6.0-beta.19", "cookie": "^0.4.0", "graceful-fs": "4.2.11", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", - "jschardet": "3.0.0", + "jschardet": "3.1.2", "kerberos": "^2.0.1", "minimist": "^1.2.6", "native-watchdog": "^1.4.1", diff --git a/remote/web/package.json b/remote/web/package.json index 76375094a7d..efd58cd8310 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -7,13 +7,13 @@ "@microsoft/1ds-post-js": "^3.2.13", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/vscode-languagedetection": "1.0.21", - "@xterm/addon-image": "0.9.0-beta.17", - "@xterm/addon-search": "0.16.0-beta.17", - "@xterm/addon-serialize": "0.14.0-beta.17", - "@xterm/addon-unicode11": "0.9.0-beta.17", - "@xterm/addon-webgl": "0.19.0-beta.17", - "@xterm/xterm": "5.6.0-beta.17", - "jschardet": "3.0.0", + "@xterm/addon-image": "0.9.0-beta.19", + "@xterm/addon-search": "0.16.0-beta.19", + "@xterm/addon-serialize": "0.14.0-beta.19", + "@xterm/addon-unicode11": "0.9.0-beta.19", + "@xterm/addon-webgl": "0.19.0-beta.19", + "@xterm/xterm": "5.6.0-beta.19", + "jschardet": "3.1.2", "tas-client-umd": "0.2.0", "vscode-oniguruma": "1.7.0", "vscode-textmate": "9.0.0" diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index 81215235ac6..1aa21866239 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -48,40 +48,40 @@ resolved "https://registry.yarnpkg.com/@vscode/vscode-languagedetection/-/vscode-languagedetection-1.0.21.tgz#89b48f293f6aa3341bb888c1118d16ff13b032d3" integrity sha512-zSUH9HYCw5qsCtd7b31yqkpaCU6jhtkKLkvOOA8yTrIRfBSOFb8PPhgmMicD7B/m+t4PwOJXzU1XDtrM9Fd3/g== -"@xterm/addon-image@0.9.0-beta.17": - version "0.9.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.9.0-beta.17.tgz#343d0665a6060d4f893b4f2d32de6ccbbd00bb63" - integrity sha512-g0r2hpBcLABY5as4llsMP36RHtkWooEn7tf+7U0/hTndJoCAvs4uGDqZNQigFgeAM3lJ4PnRYh4lfnEh9bGt8A== +"@xterm/addon-image@0.9.0-beta.19": + version "0.9.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.9.0-beta.19.tgz#3823382e5c55268998f0e0d8d77e8b7810925830" + integrity sha512-LX9g03po3mXYE/HZFoKbdnIRvdD56Qw84FpQ9LCJGDsyx9SFIf47DXLS+lXCEpJ2hjKIing46BQxP+MDEayXDw== -"@xterm/addon-search@0.16.0-beta.17": - version "0.16.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.16.0-beta.17.tgz#7cb01c7f498405909d37040884ee22d1889a36d2" - integrity sha512-wBfxmWOeqG6HHHE5mVamDJ75zBdHC35ERNy5/aTpQsQsyxrnV0Ks76c8ZVTaTu9wyBCAyx7UmZT42Ot80khY/g== +"@xterm/addon-search@0.16.0-beta.19": + version "0.16.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.16.0-beta.19.tgz#46b3374eb312a1bff974a5df188b1ebf777ff49d" + integrity sha512-iTJVUEsKSdL8SyhcDBqN6gYxhqv0wrwtP1QCUGLKNAAVDI7HKVgig3V9wToqRxYfOnu/anyU+u0qFUoKCRLnCg== -"@xterm/addon-serialize@0.14.0-beta.17": - version "0.14.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.17.tgz#1cb8e35c0d118060a807adb340624fa7f80dd9c5" - integrity sha512-/c3W39kdRgGGYDoYjXb5HrUC421qwPn6NryAT4WJuJWnyMtFbe2DPwKsTfHuCBPiPyovS3a9j950Md3O3YXDZA== +"@xterm/addon-serialize@0.14.0-beta.19": + version "0.14.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.19.tgz#c7a0a0e5f5b1bd94a35a775ec6224ba42282556c" + integrity sha512-D+BiXQfuxDb3azAIBq1RJTQGZlvo459V6U/2s/3dKpTAvRybqCRMazuf8cLoffUoNcjTb3uSWpii9+MVVvHIrQ== -"@xterm/addon-unicode11@0.9.0-beta.17": - version "0.9.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.17.tgz#b5558148029a796c6a6d78e2a8b7255f92a51530" - integrity sha512-z7v8uojFVrO1aLSWtnz5MzSrfWRT8phde7kh9ufqHLBv7YYtMHxlPVjSuW8PZ2h4eY1LOZf6icUAzrmyJmJ7Kg== +"@xterm/addon-unicode11@0.9.0-beta.19": + version "0.9.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.19.tgz#529d8b22d9378cff8c31df1b7e76250b2f8079c3" + integrity sha512-0Umiu9GkjwL/jaT85Rcfka9HVyJw3UhJsnOVOVZd/3YBZqMY2SZMHqz73W/qpXl5nz6vvyCWKbpkfddsJhpToA== -"@xterm/addon-webgl@0.19.0-beta.17": - version "0.19.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.17.tgz#68ad9e68dd1cf581b391971de33f5c04966b0d8e" - integrity sha512-X8ObRgoZl7UZTgdndM+mpSO3hLzAhWKoXXrGvUQg/7XabRKAPrQ2XvdyZm04nYwibE6Tpit2h5kkxjlVqupIig== +"@xterm/addon-webgl@0.19.0-beta.19": + version "0.19.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.19.tgz#655d1e27b1249c19352c65a8ea1d0bf319397b35" + integrity sha512-Y5efISx8X5hpFAsPOTza1Fp0xiD8x+l3MuH+mv68v1El8tpna/MW5EM4oX25qYOsPDZY00mpmkBmPbAT5loMEg== -"@xterm/xterm@5.6.0-beta.17": - version "5.6.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.6.0-beta.17.tgz#67ce2e2ff45bd6cc9f26d455d5522c6c4a122ed9" - integrity sha512-+wAv8PhaGQSN9yXWIa8EFtT33pbrA4lZakMB1P05fr+DQ7zoH66QOAUoDY95uOf/4+S6Ihz8wzP2+FH8zETQEA== +"@xterm/xterm@5.6.0-beta.19": + version "5.6.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.6.0-beta.19.tgz#2cc292fc93b25c7c655ed6d1f0425a636b36747d" + integrity sha512-mGoJxrUxAL4dueZEqw2e23KCrGNSvYaw5twTnccKqK7lITK/hDrosWCxb1jL1AjFf7bBzMxw9/dZdhWncKQQmw== -jschardet@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" - integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== +jschardet@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.1.2.tgz#9bf4364deba0677fe9e3bd9e29eda57febf2e9db" + integrity sha512-mw3CBZGzW8nUBPYhFU2ztZ/kJ6NClQUQVpyzvFMfznZsoC///ZQ30J2RCUanNsr5yF22LqhgYr/lj807/ZleWA== tas-client-umd@0.2.0: version "0.2.0" diff --git a/remote/yarn.lock b/remote/yarn.lock index 4241bf03b14..dc0c4938aaf 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -122,40 +122,40 @@ resolved "https://registry.yarnpkg.com/@vscode/windows-registry/-/windows-registry-1.1.0.tgz#03dace7c29c46f658588b9885b9580e453ad21f9" integrity sha512-5AZzuWJpGscyiMOed0IuyEwt6iKmV5Us7zuwCDCFYMIq7tsvooO9BUiciywsvuthGz6UG4LSpeDeCxvgMVhnIw== -"@xterm/addon-image@0.9.0-beta.17": - version "0.9.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.9.0-beta.17.tgz#343d0665a6060d4f893b4f2d32de6ccbbd00bb63" - integrity sha512-g0r2hpBcLABY5as4llsMP36RHtkWooEn7tf+7U0/hTndJoCAvs4uGDqZNQigFgeAM3lJ4PnRYh4lfnEh9bGt8A== +"@xterm/addon-image@0.9.0-beta.19": + version "0.9.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.9.0-beta.19.tgz#3823382e5c55268998f0e0d8d77e8b7810925830" + integrity sha512-LX9g03po3mXYE/HZFoKbdnIRvdD56Qw84FpQ9LCJGDsyx9SFIf47DXLS+lXCEpJ2hjKIing46BQxP+MDEayXDw== -"@xterm/addon-search@0.16.0-beta.17": - version "0.16.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.16.0-beta.17.tgz#7cb01c7f498405909d37040884ee22d1889a36d2" - integrity sha512-wBfxmWOeqG6HHHE5mVamDJ75zBdHC35ERNy5/aTpQsQsyxrnV0Ks76c8ZVTaTu9wyBCAyx7UmZT42Ot80khY/g== +"@xterm/addon-search@0.16.0-beta.19": + version "0.16.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.16.0-beta.19.tgz#46b3374eb312a1bff974a5df188b1ebf777ff49d" + integrity sha512-iTJVUEsKSdL8SyhcDBqN6gYxhqv0wrwtP1QCUGLKNAAVDI7HKVgig3V9wToqRxYfOnu/anyU+u0qFUoKCRLnCg== -"@xterm/addon-serialize@0.14.0-beta.17": - version "0.14.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.17.tgz#1cb8e35c0d118060a807adb340624fa7f80dd9c5" - integrity sha512-/c3W39kdRgGGYDoYjXb5HrUC421qwPn6NryAT4WJuJWnyMtFbe2DPwKsTfHuCBPiPyovS3a9j950Md3O3YXDZA== +"@xterm/addon-serialize@0.14.0-beta.19": + version "0.14.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.19.tgz#c7a0a0e5f5b1bd94a35a775ec6224ba42282556c" + integrity sha512-D+BiXQfuxDb3azAIBq1RJTQGZlvo459V6U/2s/3dKpTAvRybqCRMazuf8cLoffUoNcjTb3uSWpii9+MVVvHIrQ== -"@xterm/addon-unicode11@0.9.0-beta.17": - version "0.9.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.17.tgz#b5558148029a796c6a6d78e2a8b7255f92a51530" - integrity sha512-z7v8uojFVrO1aLSWtnz5MzSrfWRT8phde7kh9ufqHLBv7YYtMHxlPVjSuW8PZ2h4eY1LOZf6icUAzrmyJmJ7Kg== +"@xterm/addon-unicode11@0.9.0-beta.19": + version "0.9.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.19.tgz#529d8b22d9378cff8c31df1b7e76250b2f8079c3" + integrity sha512-0Umiu9GkjwL/jaT85Rcfka9HVyJw3UhJsnOVOVZd/3YBZqMY2SZMHqz73W/qpXl5nz6vvyCWKbpkfddsJhpToA== -"@xterm/addon-webgl@0.19.0-beta.17": - version "0.19.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.17.tgz#68ad9e68dd1cf581b391971de33f5c04966b0d8e" - integrity sha512-X8ObRgoZl7UZTgdndM+mpSO3hLzAhWKoXXrGvUQg/7XabRKAPrQ2XvdyZm04nYwibE6Tpit2h5kkxjlVqupIig== +"@xterm/addon-webgl@0.19.0-beta.19": + version "0.19.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.19.tgz#655d1e27b1249c19352c65a8ea1d0bf319397b35" + integrity sha512-Y5efISx8X5hpFAsPOTza1Fp0xiD8x+l3MuH+mv68v1El8tpna/MW5EM4oX25qYOsPDZY00mpmkBmPbAT5loMEg== -"@xterm/headless@5.6.0-beta.17": - version "5.6.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/headless/-/headless-5.6.0-beta.17.tgz#bff1d67c9c061c57adff22571e733d54e3aba2b7" - integrity sha512-ehS7y/XRqX1ppx4RPiYc0vu0SdIQ91aA4lSN/2XNOf3IGdP0A38Q7a0T6mzqxRGZKiiyA0kTR1szr78wnY+wmA== +"@xterm/headless@5.6.0-beta.19": + version "5.6.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/headless/-/headless-5.6.0-beta.19.tgz#dbbd4dd420e24e9bdee6e533153f405bfc1ba89b" + integrity sha512-zFTcftonaaMEbMqfQnFwos1YQCmqWnvIzSNXwmfIymkEvSxhsB03oynEjFwm48dT2filTcJXpYT91io4qvR+3g== -"@xterm/xterm@5.6.0-beta.17": - version "5.6.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.6.0-beta.17.tgz#67ce2e2ff45bd6cc9f26d455d5522c6c4a122ed9" - integrity sha512-+wAv8PhaGQSN9yXWIa8EFtT33pbrA4lZakMB1P05fr+DQ7zoH66QOAUoDY95uOf/4+S6Ihz8wzP2+FH8zETQEA== +"@xterm/xterm@5.6.0-beta.19": + version "5.6.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.6.0-beta.19.tgz#2cc292fc93b25c7c655ed6d1f0425a636b36747d" + integrity sha512-mGoJxrUxAL4dueZEqw2e23KCrGNSvYaw5twTnccKqK7lITK/hDrosWCxb1jL1AjFf7bBzMxw9/dZdhWncKQQmw== agent-base@^7.0.1, agent-base@^7.0.2, agent-base@^7.1.0: version "7.1.0" @@ -347,10 +347,10 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -jschardet@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" - integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== +jschardet@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.1.2.tgz#9bf4364deba0677fe9e3bd9e29eda57febf2e9db" + integrity sha512-mw3CBZGzW8nUBPYhFU2ztZ/kJ6NClQUQVpyzvFMfznZsoC///ZQ30J2RCUanNsr5yF22LqhgYr/lj807/ZleWA== jsonfile@^6.0.1: version "6.1.0" diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 3614986c445..1c2fafb0316 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -18,6 +18,7 @@ import * as platform from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { hash } from 'vs/base/common/hash'; import { CodeWindow, ensureCodeWindow, mainWindow } from 'vs/base/browser/window'; +import { isPointWithinTriangle } from 'vs/base/common/numbers'; export interface IRegisteredCodeWindow { readonly window: CodeWindow; @@ -2408,3 +2409,53 @@ export function trackAttributes(from: Element, to: Element, filter?: string[]): return disposables; } + +/** + * Helper for calculating the "safe triangle" occluded by hovers to avoid early dismissal. + * @see https://www.smashingmagazine.com/2023/08/better-context-menus-safe-triangles/ for example + */ +export class SafeTriangle { + // 4 triangles, 2 points (x, y) stored for each + private triangles: number[] = []; + + constructor( + private readonly originX: number, + private readonly originY: number, + target: HTMLElement + ) { + const { top, left, right, bottom } = target.getBoundingClientRect(); + const t = this.triangles; + let i = 0; + + t[i++] = left; + t[i++] = top; + t[i++] = right; + t[i++] = top; + + t[i++] = left; + t[i++] = top; + t[i++] = left; + t[i++] = bottom; + + t[i++] = right; + t[i++] = top; + t[i++] = right; + t[i++] = bottom; + + t[i++] = left; + t[i++] = bottom; + t[i++] = right; + t[i++] = bottom; + } + + public contains(x: number, y: number) { + const { triangles, originX, originY } = this; + for (let i = 0; i < 4; i++) { + if (isPointWithinTriangle(x, y, originX, originY, triangles[2 * i], triangles[2 * i + 1], triangles[2 * i + 2], triangles[2 * i + 3])) { + return true; + } + } + + return false; + } +} diff --git a/src/vs/base/common/iterator.ts b/src/vs/base/common/iterator.ts index 0bbc2413bb5..0dad18867e8 100644 --- a/src/vs/base/common/iterator.ts +++ b/src/vs/base/common/iterator.ts @@ -44,9 +44,10 @@ export namespace Iterable { return iterable[Symbol.iterator]().next().value; } - export function some(iterable: Iterable, predicate: (t: T) => unknown): boolean { + export function some(iterable: Iterable, predicate: (t: T, i: number) => unknown): boolean { + let i = 0; for (const element of iterable) { - if (predicate(element)) { + if (predicate(element, i++)) { return true; } } diff --git a/src/vs/base/common/numbers.ts b/src/vs/base/common/numbers.ts index 29e65b86032..ab4c9f92e06 100644 --- a/src/vs/base/common/numbers.ts +++ b/src/vs/base/common/numbers.ts @@ -69,3 +69,30 @@ export class SlidingWindowAverage { return this._val; } } + +/** Returns whether the point is within the triangle formed by the following 6 x/y point pairs */ +export function isPointWithinTriangle( + x: number, y: number, + ax: number, ay: number, + bx: number, by: number, + cx: number, cy: number +) { + const v0x = cx - ax; + const v0y = cy - ay; + const v1x = bx - ax; + const v1y = by - ay; + const v2x = x - ax; + const v2y = y - ay; + + const dot00 = v0x * v0x + v0y * v0y; + const dot01 = v0x * v1x + v0y * v1y; + const dot02 = v0x * v2x + v0y * v2y; + const dot11 = v1x * v1x + v1y * v1y; + const dot12 = v1x * v2x + v1y * v2y; + + const invDenom = 1 / (dot00 * dot11 - dot01 * dot01); + const u = (dot11 * dot02 - dot01 * dot12) * invDenom; + const v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + return u >= 0 && v >= 0 && u + v < 1; +} diff --git a/src/vs/base/test/common/numbers.test.ts b/src/vs/base/test/common/numbers.test.ts new file mode 100644 index 00000000000..7095b7aae40 --- /dev/null +++ b/src/vs/base/test/common/numbers.test.ts @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { isPointWithinTriangle } from 'vs/base/common/numbers'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; + +suite('isPointWithinTriangle', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + + test('should return true if the point is within the triangle', () => { + const result = isPointWithinTriangle(0.25, 0.25, 0, 0, 1, 0, 0, 1); + assert.ok(result); + }); + + test('should return false if the point is outside the triangle', () => { + const result = isPointWithinTriangle(2, 2, 0, 0, 1, 0, 0, 1); + assert.ok(!result); + }); + + test('should return true if the point is on the edge of the triangle', () => { + const result = isPointWithinTriangle(0.5, 0, 0, 0, 1, 0, 0, 1); + assert.ok(result); + }); +}); diff --git a/src/vs/editor/common/services/getIconClasses.ts b/src/vs/editor/common/services/getIconClasses.ts index 3608f3042a8..52a1e2633e6 100644 --- a/src/vs/editor/common/services/getIconClasses.ts +++ b/src/vs/editor/common/services/getIconClasses.ts @@ -123,5 +123,5 @@ function detectLanguageId(modelService: IModelService, languageService: ILanguag } function cssEscape(str: string): string { - return str.replace(/[\11\12\14\15\40]/g, '/'); // HTML class names can not contain certain whitespace characters, use / instead, which doesn't exist in file names. + return str.replace(/[\x11\x12\x14\x15\x40]/g, '/'); // HTML class names can not contain certain whitespace characters, use / instead, which doesn't exist in file names. } diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts index bdc0542b18e..6f5e09d5a48 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts @@ -51,7 +51,7 @@ export class StickyScrollController extends Disposable implements IEditorContrib private readonly _sessionStore: DisposableStore = new DisposableStore(); private _widgetState: StickyScrollWidgetState; - private _foldingModel: FoldingModel | null = null; + private _foldingModel: FoldingModel | undefined; private _maxStickyLines: number = Number.MAX_SAFE_INTEGER; private _stickyRangeProjectedOnEditor: IRange | undefined; @@ -67,7 +67,7 @@ export class StickyScrollController extends Disposable implements IEditorContrib private _positionRevealed = false; private _onMouseDown = false; private _endLineNumbers: number[] = []; - private _showEndForLine: number | null = null; + private _showEndForLine: number | undefined; constructor( private readonly _editor: ICodeEditor, @@ -84,7 +84,7 @@ export class StickyScrollController extends Disposable implements IEditorContrib this._register(this._stickyScrollWidget); this._register(this._stickyLineCandidateProvider); - this._widgetState = new StickyScrollWidgetState([], [], 0); + this._widgetState = StickyScrollWidgetState.Empty; this._onDidResize(); this._readConfiguration(); const stickyScrollDomNode = this._stickyScrollWidget.getDomNode(); @@ -291,14 +291,14 @@ export class StickyScrollController extends Disposable implements IEditorContrib this._renderStickyScroll(); return; } - if (this._showEndForLine !== null) { - this._showEndForLine = null; + if (this._showEndForLine !== undefined) { + this._showEndForLine = undefined; this._renderStickyScroll(); } })); this._register(dom.addDisposableListener(stickyScrollWidgetDomNode, dom.EventType.MOUSE_LEAVE, (e) => { - if (this._showEndForLine !== null) { - this._showEndForLine = null; + if (this._showEndForLine !== undefined) { + this._showEndForLine = undefined; this._renderStickyScroll(); } })); @@ -415,14 +415,14 @@ export class StickyScrollController extends Disposable implements IEditorContrib this._editor.addOverlayWidget(this._stickyScrollWidget); this._sessionStore.add(this._editor.onDidScrollChange((e) => { if (e.scrollTopChanged) { - this._showEndForLine = null; + this._showEndForLine = undefined; 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._showEndForLine = null; + this._showEndForLine = undefined; this._renderStickyScroll(); })); this._enabled = true; @@ -431,7 +431,7 @@ export class StickyScrollController extends Disposable implements IEditorContrib const lineNumberOption = this._editor.getOption(EditorOption.lineNumbers); if (lineNumberOption.renderType === RenderLineNumbersType.Relative) { this._sessionStore.add(this._editor.onDidChangeCursorPosition(() => { - this._showEndForLine = null; + this._showEndForLine = undefined; this._renderStickyScroll(0); })); } @@ -479,32 +479,28 @@ export class StickyScrollController extends Disposable implements IEditorContrib this._maxStickyLines = Math.round(theoreticalLines * .25); } - private async _renderStickyScroll(rebuildFromLine?: number) { + private async _renderStickyScroll(rebuildFromLine?: number): Promise { const model = this._editor.getModel(); if (!model || model.isTooLargeForTokenization()) { - this._foldingModel = null; - this._stickyScrollWidget.setState(undefined, null); + this._resetState(); return; } - const stickyLineVersion = this._stickyLineCandidateProvider.getVersionId(); - if (stickyLineVersion === undefined || stickyLineVersion === model.getVersionId()) { - this._foldingModel = await FoldingController.get(this._editor)?.getFoldingModel() ?? null; - this._widgetState = this.findScrollWidgetState(); - this._stickyScrollVisibleContextKey.set(!(this._widgetState.startLineNumbers.length === 0)); - + const stickyWidgetVersion = this._stickyLineCandidateProvider.getVersionId(); + const shouldUpdateState = stickyWidgetVersion === undefined || stickyWidgetVersion === model.getVersionId(); + if (shouldUpdateState) { if (!this._focused) { - this._stickyScrollWidget.setState(this._widgetState, this._foldingModel, rebuildFromLine); + await this._updateState(rebuildFromLine); } else { // 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._foldingModel, rebuildFromLine); + await this._updateState(rebuildFromLine); this._focusedStickyElementIndex = this._stickyScrollWidget.lineNumberCount - 1; if (this._focusedStickyElementIndex !== -1) { this._stickyScrollWidget.focusLineWithIndex(this._focusedStickyElementIndex); } } else { const focusedStickyElementLineNumber = this._stickyScrollWidget.lineNumbers[this._focusedStickyElementIndex]; - this._stickyScrollWidget.setState(this._widgetState, this._foldingModel, rebuildFromLine); + await this._updateState(rebuildFromLine); // Suppose that after setting the state, there are no sticky lines, set the focused index to -1 if (this._stickyScrollWidget.lineNumberCount === 0) { this._focusedStickyElementIndex = -1; @@ -522,6 +518,20 @@ export class StickyScrollController extends Disposable implements IEditorContrib } } } + private async _updateState(rebuildFromLine?: number): Promise { + this._foldingModel = await FoldingController.get(this._editor)?.getFoldingModel() ?? undefined; + this._widgetState = this.findScrollWidgetState(); + const stickyWidgetHasLines = this._widgetState.startLineNumbers.length > 0; + this._stickyScrollVisibleContextKey.set(stickyWidgetHasLines); + this._stickyScrollWidget.setState(this._widgetState, this._foldingModel, rebuildFromLine); + } + + private async _resetState(): Promise { + this._foldingModel = undefined; + this._widgetState = StickyScrollWidgetState.Empty; + this._stickyScrollVisibleContextKey.set(false); + this._stickyScrollWidget.setState(undefined, undefined); + } findScrollWidgetState(): StickyScrollWidgetState { const lineHeight: number = this._editor.getOption(EditorOption.lineHeight); diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts index d0e8da4b17a..27d3d8e1a58 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts @@ -35,6 +35,10 @@ export class StickyScrollWidgetState { && equals(this.startLineNumbers, other.startLineNumbers) && equals(this.endLineNumbers, other.endLineNumbers); } + + static get Empty() { + return new StickyScrollWidgetState([], [], 0); + } } const _ttPolicy = createTrustedTypesPolicy('stickyScrollViewLayer', { createHTML: value => value }); @@ -126,7 +130,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { return this._lineNumbers; } - setState(_state: StickyScrollWidgetState | undefined, foldingModel: FoldingModel | null, _rebuildFromLine?: number): void { + setState(_state: StickyScrollWidgetState | undefined, foldingModel: FoldingModel | undefined, _rebuildFromLine?: number): void { if (_rebuildFromLine === undefined && ((!this._previousState && !_state) || (this._previousState && this._previousState.equals(_state))) ) { @@ -205,7 +209,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { } } - private async _renderRootNode(state: StickyScrollWidgetState | undefined, foldingModel: FoldingModel | null, rebuildFromLine: number): Promise { + private async _renderRootNode(state: StickyScrollWidgetState | undefined, foldingModel: FoldingModel | undefined, rebuildFromLine: number): Promise { this._clearStickyLinesFromLine(rebuildFromLine); if (!state) { return; @@ -258,7 +262,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { })); } - private _renderChildNode(index: number, line: number, foldingModel: FoldingModel | null, layoutInfo: EditorLayoutInfo): RenderedStickyLine | undefined { + private _renderChildNode(index: number, line: number, foldingModel: FoldingModel | undefined, layoutInfo: EditorLayoutInfo): RenderedStickyLine | undefined { const viewModel = this._editor._getViewModel(); if (!viewModel) { return; @@ -358,7 +362,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { return stickyLine; } - private _renderFoldingIconForLine(foldingModel: FoldingModel | null, line: number): StickyFoldingIcon | undefined { + private _renderFoldingIconForLine(foldingModel: FoldingModel | undefined, line: number): StickyFoldingIcon | undefined { const showFoldingControls: 'mouseover' | 'always' | 'never' = this._editor.getOption(EditorOption.showFoldingControls); if (!foldingModel || showFoldingControls === 'never') { return; diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index ea2f3c43a06..ba936cd9e82 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -5003,8 +5003,8 @@ declare namespace monaco.editor { screenReaderAnnounceInlineSuggestion: IEditorOption; autoClosingBrackets: IEditorOption; autoClosingComments: IEditorOption; - autoClosingDelete: IEditorOption; - autoClosingOvertype: IEditorOption; + autoClosingDelete: IEditorOption; + autoClosingOvertype: IEditorOption; autoClosingQuotes: IEditorOption; autoIndent: IEditorOption; automaticLayout: IEditorOption; @@ -5016,7 +5016,7 @@ declare namespace monaco.editor { codeLensFontFamily: IEditorOption; codeLensFontSize: IEditorOption; colorDecorators: IEditorOption; - colorDecoratorActivatedOn: IEditorOption; + colorDecoratorActivatedOn: IEditorOption; colorDecoratorsLimit: IEditorOption; columnSelection: IEditorOption; comments: IEditorOption>>; @@ -5124,13 +5124,13 @@ declare namespace monaco.editor { tabCompletion: IEditorOption; tabIndex: IEditorOption; unicodeHighlight: IEditorOption; - unusualLineTerminators: IEditorOption; + unusualLineTerminators: IEditorOption; useShadowDOM: IEditorOption; useTabStops: IEditorOption; wordBreak: IEditorOption; wordSegmenterLocales: IEditorOption; wordSeparators: IEditorOption; - wordWrap: IEditorOption; + wordWrap: IEditorOption; wordWrapBreakAfterCharacters: IEditorOption; wordWrapBreakBeforeCharacters: IEditorOption; wordWrapColumn: IEditorOption; diff --git a/src/vs/platform/tunnel/common/tunnel.ts b/src/vs/platform/tunnel/common/tunnel.ts index 86b4da4b409..b1433f2e745 100644 --- a/src/vs/platform/tunnel/common/tunnel.ts +++ b/src/vs/platform/tunnel/common/tunnel.ts @@ -5,7 +5,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter, Event } from 'vs/base/common/event'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { OperatingSystem } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -215,7 +215,7 @@ export class DisposableTunnel { } } -export abstract class AbstractTunnelService implements ITunnelService { +export abstract class AbstractTunnelService extends Disposable implements ITunnelService { declare readonly _serviceBrand: undefined; private _onTunnelOpened: Emitter = new Emitter(); @@ -234,7 +234,7 @@ export abstract class AbstractTunnelService implements ITunnelService { public constructor( @ILogService protected readonly logService: ILogService, @IConfigurationService protected readonly configurationService: IConfigurationService - ) { } + ) { super(); } get hasTunnelProvider(): boolean { return !!this._tunnelProvider; @@ -308,7 +308,8 @@ export abstract class AbstractTunnelService implements ITunnelService { return tunnels; } - async dispose(): Promise { + override async dispose(): Promise { + super.dispose(); for (const portMap of this._tunnels.values()) { for (const { value } of portMap.values()) { await value.then(tunnel => typeof tunnel !== 'string' ? tunnel?.dispose() : undefined); diff --git a/src/vs/workbench/api/browser/mainThreadChatVariables.ts b/src/vs/workbench/api/browser/mainThreadChatVariables.ts index bf7103206a0..9e08e5d1423 100644 --- a/src/vs/workbench/api/browser/mainThreadChatVariables.ts +++ b/src/vs/workbench/api/browser/mainThreadChatVariables.ts @@ -5,10 +5,7 @@ import { DisposableMap } from 'vs/base/common/lifecycle'; import { revive } from 'vs/base/common/marshalling'; -import { URI } from 'vs/base/common/uri'; -import { Location } from 'vs/editor/common/languages'; import { ExtHostChatVariablesShape, ExtHostContext, IChatVariableResolverProgressDto, MainContext, MainThreadChatVariablesShape } from 'vs/workbench/api/common/extHost.protocol'; -import { ChatAgentLocation } from 'vs/workbench/contrib/chat/common/chatAgents'; import { IChatRequestVariableValue, IChatVariableData, IChatVariableResolverProgress, IChatVariablesService } from 'vs/workbench/contrib/chat/common/chatVariables'; import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers'; @@ -50,8 +47,4 @@ export class MainThreadChatVariables implements MainThreadChatVariablesShape { $unregisterVariable(handle: number): void { this._variables.deleteAndDispose(handle); } - - $attachContext(name: string, value: string | URI | Location | unknown, location: ChatAgentLocation.Panel): void { - this._chatVariablesService.attachContext(name, revive(value), location); - } } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 680d04cb5dd..d76d6aa4bf0 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1429,10 +1429,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I createDynamicChatParticipant(id: string, dynamicProps: vscode.DynamicChatParticipantProps, handler: vscode.ChatExtendedRequestHandler): vscode.ChatParticipant { checkProposedApiEnabled(extension, 'chatParticipantPrivate'); return extHostChatAgents2.createDynamicChatAgent(extension, id, dynamicProps, handler); - }, - attachContext(name: string, value: string | vscode.Uri | vscode.Location | unknown, location: vscode.ChatLocation.Panel) { - checkProposedApiEnabled(extension, 'chatVariableResolver'); - return extHostChatVariables.attachContext(name, value, location); } }; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 2d10d6b7129..ee8399645e8 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -6,7 +6,6 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IRemoteConsoleLog } from 'vs/base/common/console'; -import { Location } from 'vs/editor/common/languages'; import { SerializedError } from 'vs/base/common/errors'; import { IRelativePattern } from 'vs/base/common/glob'; import { IMarkdownString } from 'vs/base/common/htmlContent'; @@ -1291,7 +1290,6 @@ export interface MainThreadChatVariablesShape extends IDisposable { $registerVariable(handle: number, data: IChatVariableData): void; $handleProgressChunk(requestId: string, progress: IChatVariableResolverProgressDto): Promise; $unregisterVariable(handle: number): void; - $attachContext(name: string, value: string | Dto | URI | unknown, location: ChatAgentLocation): void; } export type IChatRequestVariableValueDto = Dto; diff --git a/src/vs/workbench/api/common/extHostChatVariables.ts b/src/vs/workbench/api/common/extHostChatVariables.ts index 5f0bf7d2449..dfc37201bd4 100644 --- a/src/vs/workbench/api/common/extHostChatVariables.ts +++ b/src/vs/workbench/api/common/extHostChatVariables.ts @@ -64,10 +64,6 @@ export class ExtHostChatVariables implements ExtHostChatVariablesShape { this._proxy.$unregisterVariable(handle); }); } - - attachContext(name: string, value: string | vscode.Location | vscode.Uri | unknown, location: vscode.ChatLocation.Panel) { - this._proxy.$attachContext(name, extHostTypes.Location.isLocation(value) ? typeConvert.Location.from(value) : value, typeConvert.ChatLocation.from(location)); - } } class ChatVariableResolverResponseStream { diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts b/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts index 2622ffd8daf..0ed847ca9fd 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts @@ -171,118 +171,77 @@ const configuration: IConfigurationNode = { type: 'boolean', default: true }, - 'accessibility.signalOptions': { - description: 'Configures the behavior of signals (audio cues and announcements) in the workbench. Includes volume, debounce position changes, and delays for different types of signals.', - type: 'object', - additionalProperties: false, - properties: { - 'volume': { - 'description': localize('accessibility.signalOptions.volume', "The volume of the sounds in percent (0-100)."), + 'accessibility.signalOptions.volume': { + 'description': localize('accessibility.signalOptions.volume', "The volume of the sounds in percent (0-100)."), + 'type': 'number', + 'minimum': 0, + 'maximum': 100, + 'default': 70, + 'tags': ['accessibility'] + }, + 'accessibility.signalOptions.debouncePositionChanges': { + 'description': localize('accessibility.signalOptions.debouncePositionChanges', "Whether or not position changes should be debounced"), + 'type': 'boolean', + 'default': false, + 'tags': ['accessibility'] + }, + 'accessibility.signalOptions.experimental.delays.general': { + 'type': 'object', + 'description': 'Delays for all signals besides error and warning at position', + 'additionalProperties': false, + 'properties': { + 'announcement': { + 'description': localize('accessibility.signalOptions.delays.general.announcement', "The delay in milliseconds before an announcement is made."), 'type': 'number', 'minimum': 0, - 'maximum': 100, - 'default': 70, + 'default': 3000 }, - 'debouncePositionChanges': { - 'description': localize('accessibility.signalOptions.debouncePositionChanges', "Whether or not position changes should be debounced"), - 'type': 'boolean', - 'default': false, - }, - 'experimental.delays': { - 'type': 'object', - 'additionalProperties': false, - 'properties': { - 'general': { - 'type': 'object', - 'description': 'Delays for all signals besides error and warning at position', - 'additionalProperties': false, - 'properties': { - 'announcement': { - 'description': localize('accessibility.signalOptions.delays.general.announcement', "The delay in milliseconds before an announcement is made."), - 'type': 'number', - 'minimum': 0, - 'default': 3000 - }, - 'sound': { - 'description': localize('accessibility.signalOptions.delays.general.sound', "The delay in milliseconds before a sound is played."), - 'type': 'number', - 'minimum': 0, - 'default': 400 - } - }, - }, - 'warningAtPosition': { - 'type': 'object', - 'additionalProperties': false, - 'properties': { - 'announcement': { - 'description': localize('accessibility.signalOptions.delays.warningAtPosition.announcement', "The delay in milliseconds before an announcement is made when there's a warning at the position."), - 'type': 'number', - 'minimum': 0, - 'default': 3000 - }, - 'sound': { - 'description': localize('accessibility.signalOptions.delays.warningAtPosition.sound', "The delay in milliseconds before a sound is played when there's a warning at the position."), - 'type': 'number', - 'minimum': 0, - 'default': 1000 - } - }, - }, - 'errorAtPosition': { - 'type': 'object', - 'additionalProperties': false, - 'properties': { - 'announcement': { - 'description': localize('accessibility.signalOptions.delays.errorAtPosition.announcement', "The delay in milliseconds before an announcement is made when there's an error at the position."), - 'type': 'number', - 'minimum': 0, - 'default': 3000 - }, - 'sound': { - 'description': localize('accessibility.signalOptions.delays.errorAtPosition.sound', "The delay in milliseconds before a sound is played when there's an error at the position."), - 'type': 'number', - 'minimum': 0, - 'default': 1000 - } - }, - }, - }, - 'default': { - 'general': { - 'announcement': 3000, - 'sound': 400 - }, - 'warningAtPosition': { - 'announcement': 3000, - 'sound': 1000 - }, - 'errorAtPosition': { - 'announcement': 3000, - 'sound': 1000 - } - } - }, - }, - 'default': { - 'volume': 70, - 'debouncePositionChanges': false, - 'delays': { - 'general': { - 'announcement': 3000, - 'sound': 400 - }, - 'warningAtPosition': { - 'announcement': 3000, - 'sound': 1000 - }, - 'errorAtPosition': { - 'announcement': 3000, - 'sound': 1000 - } + 'sound': { + 'description': localize('accessibility.signalOptions.delays.general.sound', "The delay in milliseconds before a sound is played."), + 'type': 'number', + 'minimum': 0, + 'default': 400 } }, - tags: ['accessibility'] + 'tags': ['accessibility'] + }, + 'accessibility.signalOptions.experimental.delays.warningAtPosition': { + 'type': 'object', + 'additionalProperties': false, + 'properties': { + 'announcement': { + 'description': localize('accessibility.signalOptions.delays.warningAtPosition.announcement', "The delay in milliseconds before an announcement is made when there's a warning at the position."), + 'type': 'number', + 'minimum': 0, + 'default': 3000 + }, + 'sound': { + 'description': localize('accessibility.signalOptions.delays.warningAtPosition.sound', "The delay in milliseconds before a sound is played when there's a warning at the position."), + 'type': 'number', + 'minimum': 0, + 'default': 1000 + } + }, + 'tags': ['accessibility'] + }, + 'accessibility.signalOptions.experimental.delays.errorAtPosition': { + 'type': 'object', + 'additionalProperties': false, + 'properties': { + 'announcement': { + 'description': localize('accessibility.signalOptions.delays.errorAtPosition.announcement', "The delay in milliseconds before an announcement is made when there's an error at the position."), + 'type': 'number', + 'minimum': 0, + 'default': 3000 + }, + 'sound': { + 'description': localize('accessibility.signalOptions.delays.errorAtPosition.sound', "The delay in milliseconds before a sound is played when there's an error at the position."), + 'type': 'number', + 'minimum': 0, + 'default': 1000 + } + }, + 'tags': ['accessibility'] }, 'accessibility.signals.lineHasBreakpoint': { ...signalFeatureBase, @@ -804,10 +763,9 @@ export class DynamicSpeechAccessibilityConfiguration extends Disposable implemen Registry.as(WorkbenchExtensions.ConfigurationMigration) .registerConfigurationMigrations([{ key: 'audioCues.volume', - migrateFn: (volume, accessor) => { - const debouncePositionChanges = getDebouncePositionChangesFromConfig(accessor); + migrateFn: (value, accessor) => { return [ - ['accessibility.signalOptions', { value: debouncePositionChanges !== undefined ? { volume, debouncePositionChanges } : { volume } }], + ['accessibility.signalOptions.volume', { value }], ['audioCues.volume', { value: undefined }] ]; } @@ -816,10 +774,9 @@ Registry.as(WorkbenchExtensions.ConfigurationMi Registry.as(WorkbenchExtensions.ConfigurationMigration) .registerConfigurationMigrations([{ key: 'audioCues.debouncePositionChanges', - migrateFn: (debouncePositionChanges, accessor) => { - const volume = getVolumeFromConfig(accessor); + migrateFn: (value) => { return [ - ['accessibility.signalOptions', { value: volume !== undefined ? { volume, debouncePositionChanges } : { debouncePositionChanges } }], + ['accessibility.signalOptions.debouncePositionChanges', { value }], ['audioCues.debouncePositionChanges', { value: undefined }] ]; } @@ -829,12 +786,18 @@ Registry.as(WorkbenchExtensions.ConfigurationMi .registerConfigurationMigrations([{ key: 'accessibility.signalOptions', migrateFn: (value, accessor) => { - const delays = value.delays; - if (!delays) { - return []; - } + const delayGeneral = getDelaysFromConfig(accessor, 'general'); + const delayError = getDelaysFromConfig(accessor, 'errorAtPosition'); + const delayWarning = getDelaysFromConfig(accessor, 'warningAtPosition'); + const volume = getVolumeFromConfig(accessor); + const debouncePositionChanges = getDebouncePositionChangesFromConfig(accessor); return [ - ['accessibility.signalOptions', { value: { ...value, 'experimental.delays': delays, 'delays': undefined } }], + ['accessibility.signalOptions.volume', { value: volume }], + ['accessibility.signalOptions.debouncePositionChanges', { value: debouncePositionChanges }], + ['accessibility.signalOptions.experimental.delays.general', { value: delayGeneral }], + ['accessibility.signalOptions.experimental.delays.errorAtPosition', { value: delayError }], + ['accessibility.signalOptions.experimental.delays.warningAtPosition', { value: delayWarning }], + ['accessibility.signalOptions', { value: undefined }], ]; } }]); @@ -843,10 +806,9 @@ Registry.as(WorkbenchExtensions.ConfigurationMi Registry.as(WorkbenchExtensions.ConfigurationMigration) .registerConfigurationMigrations([{ key: 'accessibility.signals.sounds.volume', - migrateFn: (volume, accessor) => { - const debouncePositionChanges = getDebouncePositionChangesFromConfig(accessor); + migrateFn: (value) => { return [ - ['accessibility.signalOptions', { value: debouncePositionChanges !== undefined ? { volume, debouncePositionChanges } : { volume } }], + ['accessibility.signalOptions.volume', { value }], ['accessibility.signals.sounds.volume', { value: undefined }] ]; } @@ -855,21 +817,24 @@ Registry.as(WorkbenchExtensions.ConfigurationMi Registry.as(WorkbenchExtensions.ConfigurationMigration) .registerConfigurationMigrations([{ key: 'accessibility.signals.debouncePositionChanges', - migrateFn: (debouncePositionChanges, accessor) => { - const volume = getVolumeFromConfig(accessor); + migrateFn: (value) => { return [ - ['accessibility.signalOptions', { value: volume !== undefined ? { volume, debouncePositionChanges } : { debouncePositionChanges } }], + ['accessibility.signalOptions.debouncePositionChanges', { value }], ['accessibility.signals.debouncePositionChanges', { value: undefined }] ]; } }]); +function getDelaysFromConfig(accessor: (key: string) => any, type: 'general' | 'errorAtPosition' | 'warningAtPosition'): { announcement: number; sound: number } | undefined { + return accessor(`accessibility.signalOptions.experimental.delays.${type}`) || accessor('accessibility.signalOptions')?.['experimental.delays']?.[`${type}`] || accessor('accessibility.signalOptions')?.['delays']?.[`${type}`]; +} + function getVolumeFromConfig(accessor: (key: string) => any): string | undefined { - return accessor('accessibility.signalOptions')?.volume || accessor('accessibility.signals.sounds.volume') || accessor('audioCues.volume'); + return accessor('accessibility.signalOptions.volume') || accessor('accessibility.signalOptions')?.volume || accessor('accessibility.signals.sounds.volume') || accessor('audioCues.volume'); } function getDebouncePositionChangesFromConfig(accessor: (key: string) => any): number | undefined { - return accessor('accessibility.signalOptions')?.debouncePositionChanges || accessor('accessibility.signals.debouncePositionChanges') || accessor('audioCues.debouncePositionChanges'); + return accessor('accessibility.signalOptions.debouncePositionChanges') || accessor('accessibility.signalOptions')?.debouncePositionChanges || accessor('accessibility.signals.debouncePositionChanges') || accessor('audioCues.debouncePositionChanges'); } Registry.as(WorkbenchExtensions.ConfigurationMigration) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.ts index 01a8f050bac..f37af7c9d29 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.ts @@ -30,9 +30,13 @@ import { IChatVariablesService } from 'vs/workbench/contrib/chat/common/chatVari import { AnythingQuickAccessProvider } from 'vs/workbench/contrib/search/browser/anythingQuickAccess'; import { ISymbolQuickPickItem, SymbolsQuickAccessProvider } from 'vs/workbench/contrib/search/browser/symbolsQuickAccess'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { EditorType } from 'vs/editor/common/editorCommon'; export function registerChatContextActions() { registerAction2(AttachContextAction); + registerAction2(AttachFileAction); + registerAction2(AttachSelectionAction); } export type IChatContextQuickPickItem = IFileQuickPickItem | IDynamicVariableQuickPickItem | IStaticVariableQuickPickItem | IGotoSymbolQuickPickItem | ISymbolQuickPickItem | IQuickAccessQuickPickItem; @@ -77,6 +81,58 @@ export interface IQuickAccessQuickPickItem extends IQuickPickItem { prefix: string; } +class AttachFileAction extends Action2 { + + static readonly ID = 'workbench.action.chat.attachFile'; + + constructor() { + super({ + id: AttachFileAction.ID, + title: localize2('workbench.action.chat.attachFile.label', "Attach File"), + category: CHAT_CATEGORY, + f1: false + }); + } + + override async run(accessor: ServicesAccessor, ...args: any[]): Promise { + const variablesService = accessor.get(IChatVariablesService); + const textEditorService = accessor.get(IEditorService); + + const activeUri = textEditorService.activeEditor?.resource; + if (textEditorService.activeTextEditorControl?.getEditorType() === EditorType.ICodeEditor && activeUri && [Schemas.file, Schemas.vscodeRemote].includes(activeUri.scheme)) { + variablesService.attachContext('file', activeUri, ChatAgentLocation.Panel); + } + } +} + +class AttachSelectionAction extends Action2 { + + static readonly ID = 'workbench.action.chat.attachSelection'; + + constructor() { + super({ + id: AttachSelectionAction.ID, + title: localize2('workbench.action.chat.attachSelection.label', "Add Selection to Chat"), + category: CHAT_CATEGORY, + f1: false + }); + } + + override async run(accessor: ServicesAccessor, ...args: any[]): Promise { + const variablesService = accessor.get(IChatVariablesService); + const textEditorService = accessor.get(IEditorService); + + const activeEditor = textEditorService.activeTextEditorControl; + const activeUri = textEditorService.activeEditor?.resource; + if (textEditorService.activeTextEditorControl?.getEditorType() === EditorType.ICodeEditor && activeUri && [Schemas.file, Schemas.vscodeRemote].includes(activeUri.scheme)) { + const selection = activeEditor?.getSelection(); + if (selection) { + variablesService.attachContext('file', { uri: activeUri, range: selection }, ChatAgentLocation.Panel); + } + } + } +} + class AttachContextAction extends Action2 { static readonly ID = 'workbench.action.chat.attachContext'; diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index 9d1f8781ed6..6e29cb90874 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -105,6 +105,10 @@ interface IItemHeightChangeParams { height: number; } +interface IChatMarkdownRenderResult extends IMarkdownRenderResult { + codeBlockCount: number; +} + const forceVerboseLayoutTracing = false; export interface IChatRendererDelegate { @@ -481,11 +485,12 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer { const result = data.kind === 'treeData' ? this.renderTreeData(data.treeData, element, templateData, fileTreeIndex++) : data.kind === 'markdownContent' - ? this.renderMarkdown(data.content, element, templateData, fillInIncompleteTokens) + ? this.renderMarkdown(data.content, element, templateData, fillInIncompleteTokens, codeBlockIndex) : data.kind === 'progressMessage' && onlyProgressMessagesAfterI(value, index) ? this.renderProgressMessage(data, false) // TODO render command : data.kind === 'progressTask' ? this.renderProgressTask(data, false, element, templateData) : data.kind === 'command' ? this.renderCommandButton(element, data) @@ -497,6 +502,10 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer { @@ -1193,6 +1202,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer disposables.add(d)); return { + codeBlockCount: codeBlockIndex - codeBlockStartIndex, element: result.element, dispose() { result.dispose(); diff --git a/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts b/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts index b047830a881..37931a102ea 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts @@ -29,8 +29,6 @@ import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLa import { OS } from 'vs/base/common/platform'; import { status } from 'vs/base/browser/ui/aria/aria'; import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { Extensions, IConfigurationMigrationRegistry } from 'vs/workbench/common/configuration'; import { LOG_MODE_ID, OUTPUT_MODE_ID } from 'vs/workbench/services/output/common/output'; import { SEARCH_RESULT_LANGUAGE_ID } from 'vs/workbench/services/search/common/search'; import { getDefaultHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegateFactory'; @@ -39,23 +37,6 @@ import { ChatAgentLocation, IChatAgent, IChatAgentService } from 'vs/workbench/c const $ = dom.$; -// TODO@joyceerhl remove this after a few iterations -Registry.as(Extensions.ConfigurationMigration) - .registerConfigurationMigrations([{ - key: 'workbench.editor.untitled.hint', - migrateFn: (value, _accessor) => ([ - [emptyTextEditorHintSetting, { value }], - ['workbench.editor.untitled.hint', { value: undefined }] - ]) - }, - { - key: 'accessibility.verbosity.untitledHint', - migrateFn: (value, _accessor) => ([ - [AccessibilityVerbositySettingId.EmptyEditorHint, { value }], - ['accessibility.verbosity.untitledHint', { value: undefined }] - ]) - }]); - export interface IEmptyTextEditorHintOptions { readonly clickable?: boolean; } @@ -218,6 +199,12 @@ class EmptyTextEditorHintContentWidget implements IContentWidget { return EmptyTextEditorHintContentWidget.ID; } + private _disableHint() { + this.configurationService.updateValue(emptyTextEditorHintSetting, 'hidden'); + this.dispose(); + this.editor.focus(); + } + private _getHintInlineChat(providers: IChatAgent[]) { const providerName = (providers.length === 1 ? providers[0].fullName : undefined) ?? this.productService.nameShort; @@ -257,6 +244,7 @@ class EmptyTextEditorHintContentWidget implements IContentWidget { const hintPart = $('a', undefined, fragment); hintPart.style.fontStyle = 'italic'; hintPart.style.cursor = 'pointer'; + this.toDispose.add(dom.addDisposableListener(label.element, dom.EventType.CONTEXT_MENU, () => this._disableHint())); this.toDispose.add(dom.addDisposableListener(hintPart, dom.EventType.CLICK, handleClick)); return hintPart; } else { @@ -275,6 +263,7 @@ class EmptyTextEditorHintContentWidget implements IContentWidget { if (this.options.clickable) { label.element.style.cursor = 'pointer'; + this.toDispose.add(dom.addDisposableListener(label.element, dom.EventType.CONTEXT_MENU, () => this._disableHint())); this.toDispose.add(dom.addDisposableListener(label.element, dom.EventType.CLICK, handleClick)); } @@ -297,7 +286,7 @@ class EmptyTextEditorHintContentWidget implements IContentWidget { hintElement.appendChild(rendered); } - return { ariaLabel, hintHandler, hintElement }; + return { ariaLabel, hintElement }; } private _getHintDefault() { @@ -315,7 +304,7 @@ class EmptyTextEditorHintContentWidget implements IContentWidget { chooseEditorOnClickOrTap(event.browserEvent); break; case '3': - dontShowOnClickOrTap(); + this._disableHint(); break; } } @@ -360,12 +349,6 @@ class EmptyTextEditorHintContentWidget implements IContentWidget { } }; - const dontShowOnClickOrTap = () => { - this.configurationService.updateValue(emptyTextEditorHintSetting, 'hidden'); - this.dispose(); - this.editor.focus(); - }; - const hintMsg = localize({ key: 'message', comment: [ diff --git a/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts b/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts index 59a3a4dd4bf..6aada91c214 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts @@ -264,7 +264,7 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi } private createTriggerBreakpointInput(container: HTMLElement) { - const breakpoints = this.debugService.getModel().getBreakpoints().filter(bp => bp !== this.breakpoint); + const breakpoints = this.debugService.getModel().getBreakpoints().filter(bp => bp !== this.breakpoint && !bp.logMessage); const breakpointOptions: ISelectOptionItem[] = [ { text: nls.localize('noTriggerByBreakpoint', 'None'), isDisabled: true }, ...breakpoints.map(bp => ({ @@ -433,12 +433,12 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi if (success) { // if there is already a breakpoint on this location - remove it. - let condition = this.breakpoint?.condition; - let hitCondition = this.breakpoint?.hitCondition; - let logMessage = this.breakpoint?.logMessage; - let triggeredBy = this.breakpoint?.triggeredBy; - let mode = this.breakpoint?.mode; - let modeLabel = this.breakpoint?.modeLabel; + let condition: string | undefined = undefined; + let hitCondition: string | undefined = undefined; + let logMessage: string | undefined = undefined; + let triggeredBy: string | undefined = undefined; + let mode: string | undefined = undefined; + let modeLabel: string | undefined = undefined; this.rememberInput(); diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 8b989fb46f4..4afa61df99c 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -1643,7 +1643,7 @@ registerAction2(class extends Action2 { } else if (breakpoint instanceof DataBreakpoint) { await debugService.removeDataBreakpoints(breakpoint.getId()); } else if (breakpoint instanceof InstructionBreakpoint) { - await debugService.removeInstructionBreakpoints(breakpoint.instructionReference); + await debugService.removeInstructionBreakpoints(breakpoint.instructionReference, breakpoint.offset); } } }); diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts index 4ab2ba9d777..1612646a1e9 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts @@ -6,6 +6,7 @@ import { addDisposableListener, isKeyboardEvent } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { distinct } from 'vs/base/common/arrays'; import { RunOnceScheduler } from 'vs/base/common/async'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; @@ -208,7 +209,7 @@ export class DebugEditorContribution implements IDebugEditorContribution { private toDispose: IDisposable[]; private hoverWidget: DebugHoverWidget; - private hoverPosition: Position | null = null; + private hoverPosition?: { position: Position; event: IMouseEvent }; private mouseDown = false; private exceptionWidgetVisible: IContextKey; private gutterIsHovered = false; @@ -341,7 +342,7 @@ export class DebugEditorContribution implements IDebugEditorContribution { if (debugHoverWasVisible && this.hoverPosition) { // If the debug hover was visible immediately show the editor hover for the alt transition to be smooth - this.showEditorHover(this.hoverPosition, false); + this.showEditorHover(this.hoverPosition.position, false); } const onKeyUp = new DomEmitter(ownerDocument, 'keyup'); @@ -361,14 +362,14 @@ export class DebugEditorContribution implements IDebugEditorContribution { }); } - async showHover(position: Position, focus: boolean): Promise { + async showHover(position: Position, focus: boolean, mouseEvent?: IMouseEvent): Promise { // normally will already be set in `showHoverScheduler`, but public callers may hit this directly: this.preventDefaultEditorHover(); const sf = this.debugService.getViewModel().focusedStackFrame; const model = this.editor.getModel(); if (sf && model && this.uriIdentityService.extUri.isEqual(sf.source.uri, model.uri)) { - const result = await this.hoverWidget.showAt(position, focus); + const result = await this.hoverWidget.showAt(position, focus, mouseEvent); if (result === ShowDebugHoverResult.NOT_AVAILABLE) { // When no expression available fallback to editor hover this.showEditorHover(position, focus); @@ -438,7 +439,7 @@ export class DebugEditorContribution implements IDebugEditorContribution { private get showHoverScheduler() { const scheduler = new RunOnceScheduler(() => { if (this.hoverPosition && !this.altPressed) { - this.showHover(this.hoverPosition, false); + this.showHover(this.hoverPosition.position, false, this.hoverPosition.event); } }, this.hoverDelay); this.toDispose.push(scheduler); @@ -493,8 +494,8 @@ export class DebugEditorContribution implements IDebugEditorContribution { } if (target.type === MouseTargetType.CONTENT_TEXT) { - if (target.position && !Position.equals(target.position, this.hoverPosition)) { - this.hoverPosition = target.position; + if (target.position && !Position.equals(target.position, this.hoverPosition?.position || null) && !this.hoverWidget.isInSafeTriangle(mouseEvent.event.posx, mouseEvent.event.posy)) { + this.hoverPosition = { position: target.position, event: mouseEvent.event }; // Disable the editor hover during the request to avoid flickering this.preventDefaultEditorHover(); this.showHoverScheduler.schedule(this.hoverDelay); diff --git a/src/vs/workbench/contrib/debug/browser/debugHover.ts b/src/vs/workbench/contrib/debug/browser/debugHover.ts index b534c3fba67..c3191626a32 100644 --- a/src/vs/workbench/contrib/debug/browser/debugHover.ts +++ b/src/vs/workbench/contrib/debug/browser/debugHover.ts @@ -5,6 +5,7 @@ import * as dom from 'vs/base/browser/dom'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; @@ -83,6 +84,7 @@ export class DebugHoverWidget implements IContentWidget { readonly allowEditorOverflow = true; private _isVisible: boolean; + private safeTriangle?: dom.SafeTriangle; private showCancellationSource?: CancellationTokenSource; private domNode!: HTMLElement; private tree!: AsyncDataTree; @@ -228,7 +230,15 @@ export class DebugHoverWidget implements IContentWidget { return this.domNode; } - async showAt(position: Position, focus: boolean): Promise { + /** + * Gets whether the given coordinates are in the safe triangle formed from + * the position at which the hover was initiated. + */ + isInSafeTriangle(x: number, y: number) { + return this._isVisible && !!this.safeTriangle?.contains(x, y); + } + + async showAt(position: Position, focus: boolean, mouseEvent?: IMouseEvent): Promise { this.showCancellationSource?.cancel(); const cancellationSource = this.showCancellationSource = new CancellationTokenSource(); const session = this.debugService.getViewModel().focusedSession; @@ -269,7 +279,7 @@ export class DebugHoverWidget implements IContentWidget { options: DebugHoverWidget._HOVER_HIGHLIGHT_DECORATION_OPTIONS }]); - return this.doShow(result.range.getStartPosition(), expression, focus); + return this.doShow(result.range.getStartPosition(), expression, focus, mouseEvent); } private static readonly _HOVER_HIGHLIGHT_DECORATION_OPTIONS = ModelDecorationOptions.register({ @@ -277,7 +287,7 @@ export class DebugHoverWidget implements IContentWidget { className: 'hoverHighlight' }); - private async doShow(position: Position, expression: IExpression, focus: boolean, forceValueHover = false): Promise { + private async doShow(position: Position, expression: IExpression, focus: boolean, mouseEvent: IMouseEvent | undefined): Promise { if (!this.domNode) { this.create(); } @@ -285,7 +295,7 @@ export class DebugHoverWidget implements IContentWidget { this.showAtPosition = position; this._isVisible = true; - if (!expression.hasChildren || forceValueHover) { + if (!expression.hasChildren) { this.complexValueContainer.hidden = true; this.valueContainer.hidden = false; renderExpressionValue(expression, this.valueContainer, { @@ -312,6 +322,7 @@ export class DebugHoverWidget implements IContentWidget { this.tree.scrollTop = 0; this.tree.scrollLeft = 0; this.complexValueContainer.hidden = false; + this.safeTriangle = mouseEvent && new dom.SafeTriangle(mouseEvent.posx, mouseEvent.posy, this.domNode); if (focus) { this.editor.render(); diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index cc21b0371a6..24e4478a278 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -816,7 +816,7 @@ Registry.as(ConfigurationExtensions.Configuration).regis }, ['interactiveWindow.executeWithShiftEnter']: { type: 'boolean', - default: true, + default: false, markdownDescription: localize('interactiveWindow.executeWithShiftEnter', "Execute the interactive window (REPL) input box with shift+enter, so that enter can be used to create a newline.") } } diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts index 6a0fd291276..d7a74993bed 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts @@ -697,6 +697,14 @@ export class NotebookService extends Disposable implements INotebookService { return result; } + tryGetDataProviderSync(viewType: string): SimpleNotebookProviderInfo | undefined { + const selected = this.notebookProviderInfoStore.get(viewType); + if (!selected) { + return undefined; + } + return this._notebookProviders.get(selected.id); + } + private _persistMementos(): void { this._memento.saveMemento(); diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index 9cc82bc223a..ee8efdec5a2 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -436,7 +436,7 @@ export class BackLayerWebView extends Themable { } table, thead, tr, th, td, tbody { - border: none !important; + border: none; border-color: transparent; border-spacing: 0; border-collapse: collapse; diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts index 3c26eff229a..a6a06d63186 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts @@ -15,6 +15,7 @@ import { assertType } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWriteFileOptions, IFileStatWithMetadata } from 'vs/platform/files/common/files'; +import { ILogService } from 'vs/platform/log/common/log'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IRevertOptions, ISaveOptions, IUntypedEditorInput } from 'vs/workbench/common/editor'; import { EditorModel } from 'vs/workbench/common/editor/editorModel'; @@ -197,7 +198,8 @@ export class NotebookFileWorkingCopyModel extends Disposable implements IStoredF private readonly _notebookModel: NotebookTextModel, private readonly _notebookService: INotebookService, private readonly _configurationService: IConfigurationService, - private readonly _telemetryService: ITelemetryService + private readonly _telemetryService: ITelemetryService, + private readonly _logService: ILogService ) { super(); @@ -237,13 +239,22 @@ export class NotebookFileWorkingCopyModel extends Disposable implements IStoredF } private async setSaveDelegate() { - const serializer = await this.getNotebookSerializer(); - this.save = async (options: IWriteFileOptions, token: CancellationToken) => { - if (token.isCancellationRequested) { - throw new CancellationError(); - } + // make sure we wait for a serializer to resolve before we try to handle saves in the EH + await this.getNotebookSerializer(); + this.save = async (options: IWriteFileOptions, token: CancellationToken) => { try { + let serializer = this._notebookService.tryGetDataProviderSync(this.notebookModel.viewType)?.serializer; + + if (!serializer) { + this._logService.warn('No serializer found for notebook model, checking if provider still needs to be resolved'); + serializer = await this.getNotebookSerializer(); + } + + if (token.isCancellationRequested) { + throw new CancellationError(); + } + const stat = await serializer.save(this._notebookModel.uri, this._notebookModel.versionId, options, token); return stat; } catch (error) { @@ -358,7 +369,8 @@ export class NotebookFileWorkingCopyModelFactory implements IStoredFileWorkingCo private readonly _viewType: string, @INotebookService private readonly _notebookService: INotebookService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @ITelemetryService private readonly _telemetryService: ITelemetryService + @ITelemetryService private readonly _telemetryService: ITelemetryService, + @ILogService private readonly _logService: ILogService ) { } async createModel(resource: URI, stream: VSBufferReadableStream, token: CancellationToken): Promise { @@ -376,7 +388,7 @@ export class NotebookFileWorkingCopyModelFactory implements IStoredFileWorkingCo } const notebookModel = this._notebookService.createNotebookTextModel(info.viewType, resource, data, info.serializer.options); - return new NotebookFileWorkingCopyModel(notebookModel, this._notebookService, this._configurationService, this._telemetryService); + return new NotebookFileWorkingCopyModel(notebookModel, this._notebookService, this._configurationService, this._telemetryService, this._logService); } } diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverServiceImpl.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverServiceImpl.ts index 9d0a90e4576..318a2a96731 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverServiceImpl.ts @@ -70,7 +70,7 @@ class NotebookModelReferenceCollection extends ReferenceCollection>this._instantiationService.createInstance( FileWorkingCopyManager, workingCopyTypeId, diff --git a/src/vs/workbench/contrib/notebook/common/notebookService.ts b/src/vs/workbench/contrib/notebook/common/notebookService.ts index 7709674b937..50e49939035 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookService.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookService.ts @@ -65,6 +65,7 @@ export interface INotebookService { registerNotebookSerializer(viewType: string, extensionData: NotebookExtensionDescription, serializer: INotebookSerializer): IDisposable; withNotebookDataProvider(viewType: string): Promise; + tryGetDataProviderSync(viewType: string): SimpleNotebookProviderInfo | undefined; getOutputMimeTypeInfo(textModel: NotebookTextModel, kernelProvides: readonly string[] | undefined, output: IOutputDto): readonly IOrderedMimeType[]; diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookEditorModel.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookEditorModel.test.ts index 0775af91399..a7849fd7319 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookEditorModel.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookEditorModel.test.ts @@ -15,6 +15,7 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { IFileStatWithMetadata } from 'vs/platform/files/common/files'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { ILogService } from 'vs/platform/log/common/log'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; import { CellKind, IOutputDto, NotebookData, NotebookSetting, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; @@ -28,7 +29,10 @@ suite('NotebookFileWorkingCopyModel', function () { let disposables: DisposableStore; let instantiationService: TestInstantiationService; const configurationService = new TestConfigurationService(); - const telemetryService = new class extends mock() { }; + const telemetryService = new class extends mock() { + override publicLogError2() { } + }; + const logservice = new class extends mock() { }; teardown(() => disposables.dispose()); @@ -65,7 +69,8 @@ suite('NotebookFileWorkingCopyModel', function () { } ), configurationService, - telemetryService + telemetryService, + logservice )); await model.snapshot(SnapshotContext.Save, CancellationToken.None); @@ -88,7 +93,8 @@ suite('NotebookFileWorkingCopyModel', function () { } ), configurationService, - telemetryService + telemetryService, + logservice )); await model.snapshot(SnapshotContext.Save, CancellationToken.None); assert.strictEqual(callCount, 1); @@ -123,7 +129,8 @@ suite('NotebookFileWorkingCopyModel', function () { } ), configurationService, - telemetryService + telemetryService, + logservice )); await model.snapshot(SnapshotContext.Save, CancellationToken.None); @@ -147,6 +154,7 @@ suite('NotebookFileWorkingCopyModel', function () { ), configurationService, telemetryService, + logservice )); await model.snapshot(SnapshotContext.Save, CancellationToken.None); @@ -181,7 +189,8 @@ suite('NotebookFileWorkingCopyModel', function () { } ), configurationService, - telemetryService + telemetryService, + logservice )); await model.snapshot(SnapshotContext.Save, CancellationToken.None); @@ -204,7 +213,8 @@ suite('NotebookFileWorkingCopyModel', function () { } ), configurationService, - telemetryService + telemetryService, + logservice )); await model.snapshot(SnapshotContext.Save, CancellationToken.None); assert.strictEqual(callCount, 1); @@ -239,7 +249,8 @@ suite('NotebookFileWorkingCopyModel', function () { } ), configurationService, - telemetryService + telemetryService, + logservice )); try { @@ -282,7 +293,8 @@ suite('NotebookFileWorkingCopyModel', function () { notebook, notebookService, configurationService, - telemetryService + telemetryService, + logservice )); // the save method should not be set if the serializer is not yet resolved @@ -299,11 +311,25 @@ suite('NotebookFileWorkingCopyModel', function () { function mockNotebookService(notebook: NotebookTextModel, notebookSerializer: Promise | INotebookSerializer) { return new class extends mock() { + private serializer: INotebookSerializer | undefined = undefined; override async withNotebookDataProvider(viewType: string): Promise { - const serializer = await notebookSerializer; + this.serializer = await notebookSerializer; return new SimpleNotebookProviderInfo( notebook.viewType, - serializer, + this.serializer, + { + id: new ExtensionIdentifier('test'), + location: undefined + } + ); + } + override tryGetDataProviderSync(viewType: string): SimpleNotebookProviderInfo | undefined { + if (!this.serializer) { + return undefined; + } + return new SimpleNotebookProviderInfo( + notebook.viewType, + this.serializer, { id: new ExtensionIdentifier('test'), location: undefined diff --git a/src/vs/workbench/contrib/search/browser/searchResultsView.ts b/src/vs/workbench/contrib/search/browser/searchResultsView.ts index d7c088c442e..5e66ae72d6c 100644 --- a/src/vs/workbench/contrib/search/browser/searchResultsView.ts +++ b/src/vs/workbench/contrib/search/browser/searchResultsView.ts @@ -136,7 +136,7 @@ export class FolderMatchRenderer extends Disposable implements ICompressibleTree SearchContext.FileFocusKey.bindTo(contextKeyServiceMain).set(false); SearchContext.FolderFocusKey.bindTo(contextKeyServiceMain).set(true); - const instantiationService = this.instantiationService.createChild(new ServiceCollection([IContextKeyService, contextKeyServiceMain])); + const instantiationService = this._register(this.instantiationService.createChild(new ServiceCollection([IContextKeyService, contextKeyServiceMain]))); const actions = disposables.add(instantiationService.createInstance(MenuWorkbenchToolBar, actionBarContainer, MenuId.SearchActionMenu, { menuOptions: { shouldForwardArgs: true diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index 69e8a910540..6359674b81f 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -237,8 +237,8 @@ export class SearchView extends ViewPane { this.inputPatternExclusionsFocused = Constants.SearchContext.PatternExcludesFocusedKey.bindTo(this.contextKeyService); this.isEditableItem = Constants.SearchContext.IsEditableItemKey.bindTo(this.contextKeyService); - this.instantiationService = this.instantiationService.createChild( - new ServiceCollection([IContextKeyService, this.contextKeyService])); + this.instantiationService = this._register(this.instantiationService.createChild( + new ServiceCollection([IContextKeyService, this.contextKeyService]))); this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('search.sortOrder')) { diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts index c0f0f27dbfa..e1929d3a930 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts @@ -141,7 +141,7 @@ export class SearchEditor extends AbstractTextCodeEditor this.createQueryEditor( this.queryEditorContainer, - this.instantiationService.createChild(new ServiceCollection([IContextKeyService, scopedContextKeyService])), + this._register(this.instantiationService.createChild(new ServiceCollection([IContextKeyService, scopedContextKeyService]))), SearchContext.InputBoxFocusedKey.bindTo(scopedContextKeyService) ); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalRunRecentQuickPick.ts b/src/vs/workbench/contrib/terminal/browser/terminalRunRecentQuickPick.ts index a17b660a13c..b795f91f201 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalRunRecentQuickPick.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalRunRecentQuickPick.ts @@ -269,6 +269,9 @@ export async function showRunRecentQuickPick( return; } const [item] = quickPick.activeItems; + if (!item) { + return; + } if ('command' in item && item.command && item.command.marker) { if (!terminalScrollStateSaved) { xterm.markTracker.saveScrollState(); diff --git a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminal.initialHint.contribution.ts b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminal.initialHint.contribution.ts index 82bd0de7ec4..eb9cce92522 100644 --- a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminal.initialHint.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminal.initialHint.contribution.ts @@ -29,9 +29,14 @@ import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal import 'vs/css!./media/terminalInitialHint'; import { TerminalInitialHintSettingId } from 'vs/workbench/contrib/terminalContrib/chat/common/terminalInitialHintConfiguration'; import { ChatAgentLocation, IChatAgent, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; const $ = dom.$; +const enum Constants { + InitialHintHideStorageKey = 'terminal.initialHint.hide' +} + export class InitialHintAddon extends Disposable implements ITerminalAddon { private readonly _onDidRequestCreateHint = this._register(new Emitter()); get onDidRequestCreateHint(): Event { return this._onDidRequestCreateHint.event; } @@ -90,11 +95,22 @@ export class TerminalInitialHintContribution extends Disposable implements ITerm @ITerminalGroupService private readonly _terminalGroupService: ITerminalGroupService, @ITerminalEditorService private readonly _terminalEditorService: ITerminalEditorService, @IChatAgentService private readonly _chatAgentService: IChatAgentService, + @IStorageService private readonly _storageService: IStorageService, ) { super(); + + // Reset hint state when config changes + this._register(this._configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(TerminalInitialHintSettingId.Enabled)) { + this._storageService.remove(Constants.InitialHintHideStorageKey, StorageScope.APPLICATION); + } + })); } xtermOpen(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { + if (this._storageService.getBoolean(Constants.InitialHintHideStorageKey, StorageScope.APPLICATION, false)) { + return; + } if (this._terminalGroupService.instances.length + this._terminalEditorService.instances.length !== 1) { // only show for the first terminal return; @@ -108,7 +124,7 @@ export class TerminalInitialHintContribution extends Disposable implements ITerm private _createHint(): void { const instance = this._instance instanceof TerminalInstance ? this._instance : undefined; const commandDetectionCapability = instance?.capabilities.get(TerminalCapability.CommandDetection); - if (!instance || !this._xterm || this._hintWidget || !commandDetectionCapability || commandDetectionCapability.promptInputModel.value || instance.reconnectionProperties) { + if (!instance || !this._xterm || this._hintWidget || !commandDetectionCapability || commandDetectionCapability.promptInputModel.value || !!instance.shellLaunchConfig.attachPersistentProcess) { return; } @@ -199,7 +215,8 @@ class TerminalInitialHintWidget extends Disposable { @IKeybindingService private readonly keybindingService: IKeybindingService, @ITelemetryService private readonly telemetryService: ITelemetryService, @IProductService private readonly productService: IProductService, - @ITerminalService private readonly terminalService: ITerminalService + @ITerminalService private readonly terminalService: ITerminalService, + @IStorageService private readonly _storageService: IStorageService ) { super(); this.toDispose.add(_instance.onDidFocus(() => { @@ -229,6 +246,7 @@ class TerminalInitialHintWidget extends Disposable { let ariaLabel = `Ask ${providerName} something or start typing to dismiss.`; const handleClick = () => { + this._storageService.store(Constants.InitialHintHideStorageKey, true, StorageScope.APPLICATION, StorageTarget.USER); this.telemetryService.publicLog2('workbenchActionExecuted', { id: 'terminalInlineChat.hintAction', from: 'hint' diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts index 33060d117ea..9e752e5f4ef 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.ts @@ -223,9 +223,11 @@ export class TreeProjection extends Disposable implements ITestTreeProjection { break; } - // The first element will cause the root to be hidden + // Removing the first element will cause the root to be hidden. + // Changing first-level elements will need the root to re-render if + // there are no other controllers with items. const parent = toRemove.parent; - const affectsRootElement = toRemove.depth === 1 && parent?.children.size === 1; + const affectsRootElement = toRemove.depth === 1 && (parent?.children.size === 1 || !Iterable.some(this.rootsWithChildren, (_, i) => i === 1)); this.changedParents.add(affectsRootElement ? null : parent); const queue: Iterable[] = [[toRemove]]; diff --git a/src/vs/workbench/contrib/testing/test/browser/explorerProjections/treeProjection.test.ts b/src/vs/workbench/contrib/testing/test/browser/explorerProjections/treeProjection.test.ts index 5414267c1d0..d59d15ef1f8 100644 --- a/src/vs/workbench/contrib/testing/test/browser/explorerProjections/treeProjection.test.ts +++ b/src/vs/workbench/contrib/testing/test/browser/explorerProjections/treeProjection.test.ts @@ -267,4 +267,52 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => { ]); }); + test('fixes #213316 (single root)', async () => { + harness.flush(); + assert.deepStrictEqual(harness.tree.getRendered(), [ + { e: 'a' }, { e: 'b' } + ]); + harness.pushDiff({ + op: TestDiffOpType.Remove, + itemId: new TestId(['ctrlId', 'id-a']).toString(), + }); + harness.flush(); + assert.deepStrictEqual(harness.tree.getRendered(), [ + { e: 'b' } + ]); + }); + + test('fixes #213316 (multi root)', async () => { + harness.pushDiff({ + op: TestDiffOpType.Add, + item: { controllerId: 'ctrl2', expand: TestItemExpandState.Expanded, item: new TestTestItem(new TestId(['ctrlId2']), 'c').toTestItem() }, + }, { + op: TestDiffOpType.Add, + item: { controllerId: 'ctrl2', expand: TestItemExpandState.NotExpandable, item: new TestTestItem(new TestId(['ctrlId2', 'id-c']), 'ca').toTestItem() }, + }); + harness.flush(); + assert.deepStrictEqual(harness.flush(), [ + { e: 'c', children: [{ e: 'ca' }] }, + { e: 'root', children: [{ e: 'a' }, { e: 'b' }] } + ]); + + harness.pushDiff({ + op: TestDiffOpType.Remove, + itemId: new TestId(['ctrlId', 'id-a']).toString(), + }); + harness.flush(); + assert.deepStrictEqual(harness.tree.getRendered(), [ + { e: 'c', children: [{ e: 'ca' }] }, + { e: 'root', children: [{ e: 'b' }] } + ]); + + harness.pushDiff({ + op: TestDiffOpType.Remove, + itemId: new TestId(['ctrlId', 'id-b']).toString(), + }); + harness.flush(); + assert.deepStrictEqual(harness.tree.getRendered(), [ + { e: 'ca' } + ]); + }); }); diff --git a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts index ec8f4a607cd..ae2c1c6cd0b 100644 --- a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts +++ b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts @@ -465,6 +465,6 @@ function handleParentFolder(key: string, selectors: string[]): string { } function escapeCSS(str: string) { - str = str.replace(/[\11\12\14\15\40]/g, '/'); // HTML class names can not contain certain whitespace characters, use / instead, which doesn't exist in file names. + str = str.replace(/[\x11\x12\x14\x15\x40]/g, '/'); // HTML class names can not contain certain whitespace characters, use / instead, which doesn't exist in file names. return mainWindow.CSS.escape(str); } diff --git a/src/vs/workbench/services/tunnel/electron-sandbox/tunnelService.ts b/src/vs/workbench/services/tunnel/electron-sandbox/tunnelService.ts index 17948851797..794fb8960ce 100644 --- a/src/vs/workbench/services/tunnel/electron-sandbox/tunnelService.ts +++ b/src/vs/workbench/services/tunnel/electron-sandbox/tunnelService.ts @@ -68,11 +68,11 @@ export class TunnelService extends AbstractTunnelService { super(logService, configurationService); // Destroy any shared process tunnels that might still be active - lifecycleService.onDidShutdown(() => { + this._register(lifecycleService.onDidShutdown(() => { this._activeSharedProcessTunnels.forEach((id) => { this._sharedProcessTunnelService.destroyTunnel(id); }); - }); + })); } public isPortPrivileged(port: number): boolean { diff --git a/src/vscode-dts/vscode.proposed.chatVariableResolver.d.ts b/src/vscode-dts/vscode.proposed.chatVariableResolver.d.ts index 1b404980e2c..62f07234bb1 100644 --- a/src/vscode-dts/vscode.proposed.chatVariableResolver.d.ts +++ b/src/vscode-dts/vscode.proposed.chatVariableResolver.d.ts @@ -19,15 +19,6 @@ declare module 'vscode' { * @param icon An icon to display when selecting context in the picker UI. */ export function registerChatVariableResolver(id: string, name: string, userDescription: string, modelDescription: string | undefined, isSlow: boolean | undefined, resolver: ChatVariableResolver, fullName?: string, icon?: ThemeIcon): Disposable; - - /** - * Attaches a chat context with the specified name, value, and location. - * - * @param name - The name of the chat context. - * @param value - The value of the chat context. - * @param location - The location of the chat context. - */ - export function attachContext(name: string, value: string | Uri | Location | unknown, location: ChatLocation.Panel): void; } export interface ChatVariableValue { diff --git a/yarn.lock b/yarn.lock index f2613ceef51..7cb89bdf1c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1982,40 +1982,40 @@ resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e" integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== -"@xterm/addon-image@0.9.0-beta.17": - version "0.9.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.9.0-beta.17.tgz#343d0665a6060d4f893b4f2d32de6ccbbd00bb63" - integrity sha512-g0r2hpBcLABY5as4llsMP36RHtkWooEn7tf+7U0/hTndJoCAvs4uGDqZNQigFgeAM3lJ4PnRYh4lfnEh9bGt8A== +"@xterm/addon-image@0.9.0-beta.19": + version "0.9.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.9.0-beta.19.tgz#3823382e5c55268998f0e0d8d77e8b7810925830" + integrity sha512-LX9g03po3mXYE/HZFoKbdnIRvdD56Qw84FpQ9LCJGDsyx9SFIf47DXLS+lXCEpJ2hjKIing46BQxP+MDEayXDw== -"@xterm/addon-search@0.16.0-beta.17": - version "0.16.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.16.0-beta.17.tgz#7cb01c7f498405909d37040884ee22d1889a36d2" - integrity sha512-wBfxmWOeqG6HHHE5mVamDJ75zBdHC35ERNy5/aTpQsQsyxrnV0Ks76c8ZVTaTu9wyBCAyx7UmZT42Ot80khY/g== +"@xterm/addon-search@0.16.0-beta.19": + version "0.16.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.16.0-beta.19.tgz#46b3374eb312a1bff974a5df188b1ebf777ff49d" + integrity sha512-iTJVUEsKSdL8SyhcDBqN6gYxhqv0wrwtP1QCUGLKNAAVDI7HKVgig3V9wToqRxYfOnu/anyU+u0qFUoKCRLnCg== -"@xterm/addon-serialize@0.14.0-beta.17": - version "0.14.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.17.tgz#1cb8e35c0d118060a807adb340624fa7f80dd9c5" - integrity sha512-/c3W39kdRgGGYDoYjXb5HrUC421qwPn6NryAT4WJuJWnyMtFbe2DPwKsTfHuCBPiPyovS3a9j950Md3O3YXDZA== +"@xterm/addon-serialize@0.14.0-beta.19": + version "0.14.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.19.tgz#c7a0a0e5f5b1bd94a35a775ec6224ba42282556c" + integrity sha512-D+BiXQfuxDb3azAIBq1RJTQGZlvo459V6U/2s/3dKpTAvRybqCRMazuf8cLoffUoNcjTb3uSWpii9+MVVvHIrQ== -"@xterm/addon-unicode11@0.9.0-beta.17": - version "0.9.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.17.tgz#b5558148029a796c6a6d78e2a8b7255f92a51530" - integrity sha512-z7v8uojFVrO1aLSWtnz5MzSrfWRT8phde7kh9ufqHLBv7YYtMHxlPVjSuW8PZ2h4eY1LOZf6icUAzrmyJmJ7Kg== +"@xterm/addon-unicode11@0.9.0-beta.19": + version "0.9.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.19.tgz#529d8b22d9378cff8c31df1b7e76250b2f8079c3" + integrity sha512-0Umiu9GkjwL/jaT85Rcfka9HVyJw3UhJsnOVOVZd/3YBZqMY2SZMHqz73W/qpXl5nz6vvyCWKbpkfddsJhpToA== -"@xterm/addon-webgl@0.19.0-beta.17": - version "0.19.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.17.tgz#68ad9e68dd1cf581b391971de33f5c04966b0d8e" - integrity sha512-X8ObRgoZl7UZTgdndM+mpSO3hLzAhWKoXXrGvUQg/7XabRKAPrQ2XvdyZm04nYwibE6Tpit2h5kkxjlVqupIig== +"@xterm/addon-webgl@0.19.0-beta.19": + version "0.19.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.19.tgz#655d1e27b1249c19352c65a8ea1d0bf319397b35" + integrity sha512-Y5efISx8X5hpFAsPOTza1Fp0xiD8x+l3MuH+mv68v1El8tpna/MW5EM4oX25qYOsPDZY00mpmkBmPbAT5loMEg== -"@xterm/headless@5.6.0-beta.17": - version "5.6.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/headless/-/headless-5.6.0-beta.17.tgz#bff1d67c9c061c57adff22571e733d54e3aba2b7" - integrity sha512-ehS7y/XRqX1ppx4RPiYc0vu0SdIQ91aA4lSN/2XNOf3IGdP0A38Q7a0T6mzqxRGZKiiyA0kTR1szr78wnY+wmA== +"@xterm/headless@5.6.0-beta.19": + version "5.6.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/headless/-/headless-5.6.0-beta.19.tgz#dbbd4dd420e24e9bdee6e533153f405bfc1ba89b" + integrity sha512-zFTcftonaaMEbMqfQnFwos1YQCmqWnvIzSNXwmfIymkEvSxhsB03oynEjFwm48dT2filTcJXpYT91io4qvR+3g== -"@xterm/xterm@5.6.0-beta.17": - version "5.6.0-beta.17" - resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.6.0-beta.17.tgz#67ce2e2ff45bd6cc9f26d455d5522c6c4a122ed9" - integrity sha512-+wAv8PhaGQSN9yXWIa8EFtT33pbrA4lZakMB1P05fr+DQ7zoH66QOAUoDY95uOf/4+S6Ihz8wzP2+FH8zETQEA== +"@xterm/xterm@5.6.0-beta.19": + version "5.6.0-beta.19" + resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.6.0-beta.19.tgz#2cc292fc93b25c7c655ed6d1f0425a636b36747d" + integrity sha512-mGoJxrUxAL4dueZEqw2e23KCrGNSvYaw5twTnccKqK7lITK/hDrosWCxb1jL1AjFf7bBzMxw9/dZdhWncKQQmw== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -6229,10 +6229,10 @@ js-yaml@^3.13.0: argparse "^1.0.7" esprima "^4.0.0" -jschardet@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" - integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== +jschardet@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.1.2.tgz#9bf4364deba0677fe9e3bd9e29eda57febf2e9db" + integrity sha512-mw3CBZGzW8nUBPYhFU2ztZ/kJ6NClQUQVpyzvFMfznZsoC///ZQ30J2RCUanNsr5yF22LqhgYr/lj807/ZleWA== jsdoc-type-pratt-parser@~4.0.0: version "4.0.0" @@ -10055,10 +10055,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.5.0-dev.20240521: - version "5.5.0-dev.20240521" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.0-dev.20240521.tgz#a53f71ad2f5e4c4401a56c35993474b77813364c" - integrity sha512-52WLKX9mbRmStK1lb30KM78dSo5ssgQT8WQERYiv8JihXir4HUgwlgTz4crExojzpsGjFGFJROL/bZrhXUiOEQ== +typescript@^5.5.0-dev.20240603: + version "5.5.0-dev.20240603" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.0-dev.20240603.tgz#a1b7311df5039a8abbaaa2213c21cac6ec547490" + integrity sha512-gdm3Sh1A+Pjj9ZlfBEJY3o2rs3tvpcSbu3vYqcCijMe09BePQBtZlsuShuPn+zCnP+qBLxdKjFiw5v1tkna3tA== typical@^4.0.0: version "4.0.0"