diff --git a/eslint.config.js b/eslint.config.js index 44453033c28..91a3284a61a 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -193,10 +193,6 @@ export default tseslint.config( 'extensions/git/src/blame.ts', 'extensions/github/src/links.ts', 'extensions/github-authentication/src/node/fetch.ts', - 'extensions/ipynb/src/deserializers.ts', - 'extensions/ipynb/src/notebookImagePaste.ts', - 'extensions/ipynb/src/serializers.ts', - 'extensions/notebook-renderers/src/index.ts', 'extensions/terminal-suggest/src/fig/figInterface.ts', 'extensions/terminal-suggest/src/fig/fig-autocomplete-shared/mixins.ts', 'extensions/terminal-suggest/src/fig/fig-autocomplete-shared/specMetadata.ts', @@ -266,8 +262,6 @@ export default tseslint.config( 'src/vs/workbench/browser/workbench.ts', 'src/vs/workbench/common/notifications.ts', 'src/vs/workbench/contrib/accessibility/browser/accessibleView.ts', - 'src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts', - 'src/vs/workbench/contrib/chat/browser/chat.ts', 'src/vs/workbench/contrib/chat/browser/chatAttachmentResolveService.ts', 'src/vs/workbench/contrib/chat/browser/chatContentParts/chatAttachmentsContentPart.ts', 'src/vs/workbench/contrib/chat/browser/chatContentParts/chatConfirmationWidget.ts', @@ -277,16 +271,11 @@ export default tseslint.config( 'src/vs/workbench/contrib/chat/browser/chatContentParts/toolInvocationParts/abstractToolConfirmationSubPart.ts', 'src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.ts', 'src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSessionStorage.ts', - 'src/vs/workbench/contrib/chat/browser/chatEditorInput.ts', - 'src/vs/workbench/contrib/chat/browser/chatFollowups.ts', 'src/vs/workbench/contrib/chat/browser/chatInlineAnchorWidget.ts', - 'src/vs/workbench/contrib/chat/browser/chatInputPart.ts', - 'src/vs/workbench/contrib/chat/browser/chatListRenderer.ts', 'src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.ts', 'src/vs/workbench/contrib/chat/browser/chatSessions/common.ts', 'src/vs/workbench/contrib/chat/browser/chatSessions/localChatSessionsProvider.ts', 'src/vs/workbench/contrib/chat/browser/chatSessions/view/sessionsTreeRenderer.ts', - 'src/vs/workbench/contrib/chat/browser/chatWidget.ts', 'src/vs/workbench/contrib/chat/browser/contrib/chatInputCompletions.ts', 'src/vs/workbench/contrib/chat/common/annotations.ts', 'src/vs/workbench/contrib/chat/common/chat.ts', @@ -321,17 +310,11 @@ export default tseslint.config( 'src/vs/workbench/contrib/mcp/common/mcpServerRequestHandler.ts', 'src/vs/workbench/contrib/mcp/test/common/mcpRegistryTypes.ts', 'src/vs/workbench/contrib/mcp/test/common/mcpServerRequestHandler.test.ts', - 'src/vs/workbench/contrib/notebook/browser/contrib/debug/notebookBreakpoints.ts', - 'src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts', 'src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts', 'src/vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution.ts', 'src/vs/workbench/contrib/notebook/browser/controller/coreActions.ts', - 'src/vs/workbench/contrib/notebook/browser/diff/diffElementViewModel.ts', - 'src/vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution.ts', 'src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts', 'src/vs/workbench/contrib/notebook/browser/viewParts/notebookKernelView.ts', - 'src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts', - 'src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts', 'src/vs/workbench/contrib/output/browser/outputView.ts', 'src/vs/workbench/contrib/preferences/browser/settingsTree.ts', 'src/vs/workbench/contrib/remoteTunnel/electron-browser/remoteTunnel.contribution.ts', @@ -391,7 +374,6 @@ export default tseslint.config( 'src/vs/base/node/processes.ts', 'src/vs/base/common/arrays.ts', 'src/vs/base/common/async.ts', - 'src/vs/base/common/cancellation.ts', 'src/vs/base/common/collections.ts', 'src/vs/base/common/console.ts', 'src/vs/base/common/controlFlow.ts', @@ -406,7 +388,6 @@ export default tseslint.config( 'src/vs/base/common/json.ts', 'src/vs/base/common/jsonSchema.ts', 'src/vs/base/common/lifecycle.ts', - 'src/vs/base/common/linkedList.ts', 'src/vs/base/common/map.ts', 'src/vs/base/common/marshalling.ts', 'src/vs/base/common/network.ts', @@ -416,9 +397,7 @@ export default tseslint.config( 'src/vs/base/common/platform.ts', 'src/vs/base/common/processes.ts', 'src/vs/base/common/resourceTree.ts', - 'src/vs/base/common/skipList.ts', 'src/vs/base/common/strings.ts', - 'src/vs/base/common/ternarySearchTree.ts', 'src/vs/base/common/types.ts', 'src/vs/base/common/uriIpc.ts', 'src/vs/base/common/verifier.ts', @@ -488,7 +467,6 @@ export default tseslint.config( 'src/vs/platform/contextkey/browser/contextKeyService.ts', 'src/vs/platform/contextkey/common/contextkey.ts', 'src/vs/platform/contextview/browser/contextView.ts', - 'src/vs/platform/contextview/browser/contextViewService.ts', 'src/vs/platform/debug/common/extensionHostDebugIpc.ts', 'src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts', 'src/vs/platform/diagnostics/common/diagnostics.ts', @@ -503,15 +481,12 @@ export default tseslint.config( 'src/vs/platform/extensionManagement/common/extensionManagementUtil.ts', 'src/vs/platform/extensionManagement/common/extensionNls.ts', 'src/vs/platform/extensionManagement/common/extensionStorage.ts', - 'src/vs/platform/extensionManagement/common/extensionTipsService.ts', 'src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts', 'src/vs/platform/extensionManagement/common/implicitActivationEvents.ts', 'src/vs/platform/extensionManagement/node/extensionManagementService.ts', 'src/vs/platform/extensionRecommendations/common/extensionRecommendationsIpc.ts', - 'src/vs/platform/extensions/common/extensionHostStarter.ts', 'src/vs/platform/extensions/common/extensionValidator.ts', 'src/vs/platform/extensions/common/extensions.ts', - 'src/vs/platform/extensions/electron-main/extensionHostStarter.ts', 'src/vs/platform/instantiation/common/descriptors.ts', 'src/vs/platform/instantiation/common/extensions.ts', 'src/vs/platform/instantiation/common/instantiation.ts', @@ -574,25 +549,15 @@ export default tseslint.config( 'src/vs/platform/userDataSync/common/extensionsSync.ts', 'src/vs/platform/userDataSync/common/globalStateMerge.ts', 'src/vs/platform/userDataSync/common/globalStateSync.ts', - 'src/vs/platform/userDataSync/common/ignoredExtensions.ts', 'src/vs/platform/userDataSync/common/settingsMerge.ts', 'src/vs/platform/userDataSync/common/settingsSync.ts', - 'src/vs/platform/userDataSync/common/userDataAutoSyncService.ts', 'src/vs/platform/userDataSync/common/userDataSync.ts', - 'src/vs/platform/userDataSync/common/userDataSyncAccount.ts', - 'src/vs/platform/userDataSync/common/userDataSyncEnablementService.ts', 'src/vs/platform/userDataSync/common/userDataSyncIpc.ts', - 'src/vs/platform/userDataSync/common/userDataSyncLocalStoreService.ts', - 'src/vs/platform/userDataSync/common/userDataSyncMachines.ts', - 'src/vs/platform/userDataSync/common/userDataSyncResourceProvider.ts', - 'src/vs/platform/userDataSync/common/userDataSyncService.ts', 'src/vs/platform/userDataSync/common/userDataSyncServiceIpc.ts', - 'src/vs/platform/userDataSync/common/userDataSyncStoreService.ts', 'src/vs/platform/webview/common/webviewManagerService.ts', 'src/vs/platform/configuration/test/common/testConfigurationService.ts', 'src/vs/platform/instantiation/test/common/instantiationServiceMock.ts', 'src/vs/platform/keybinding/test/common/mockKeybindingService.ts', - 'src/vs/platform/userDataSync/test/common/userDataSyncClient.ts', // Editor 'src/vs/editor/standalone/browser/standaloneEditor.ts', 'src/vs/editor/standalone/browser/standaloneLanguages.ts', @@ -603,8 +568,6 @@ export default tseslint.config( 'src/vs/editor/contrib/codeAction/browser/codeAction.ts', 'src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts', 'src/vs/editor/contrib/codeAction/common/types.ts', - 'src/vs/editor/contrib/codelens/browser/codelens.ts', - 'src/vs/editor/contrib/codelens/browser/codelensController.ts', 'src/vs/editor/contrib/colorPicker/browser/colorDetector.ts', 'src/vs/editor/contrib/diffEditorBreadcrumbs/browser/contribution.ts', 'src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution.ts', @@ -646,8 +609,6 @@ export default tseslint.config( 'src/vs/workbench/api/common/extHostConsoleForwarder.ts', 'src/vs/workbench/api/common/extHostDataChannels.ts', 'src/vs/workbench/api/common/extHostDebugService.ts', - 'src/vs/workbench/api/common/extHostDiagnostics.ts', - 'src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts', 'src/vs/workbench/api/common/extHostExtensionActivator.ts', 'src/vs/workbench/api/common/extHostExtensionService.ts', 'src/vs/workbench/api/common/extHostFileSystemConsumer.ts', @@ -761,7 +722,6 @@ export default tseslint.config( 'src/vs/workbench/contrib/debug/common/debugger.ts', 'src/vs/workbench/contrib/debug/common/replModel.ts', 'src/vs/workbench/contrib/debug/test/common/mockDebug.ts', - 'src/vs/workbench/contrib/editSessions/common/editSessionsStorageClient.ts', 'src/vs/workbench/contrib/editSessions/common/workspaceStateSync.ts', 'src/vs/workbench/contrib/editTelemetry/browser/helpers/documentWithAnnotatedEdits.ts', 'src/vs/workbench/contrib/editTelemetry/browser/helpers/utils.ts', @@ -888,15 +848,11 @@ export default tseslint.config( 'src/vs/workbench/contrib/terminal/common/terminal.ts', 'src/vs/workbench/contrib/terminalContrib/links/browser/links.ts', 'src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts', - 'src/vs/workbench/contrib/testing/browser/testExplorerActions.ts', - 'src/vs/workbench/contrib/testing/browser/testingExplorerView.ts', 'src/vs/workbench/contrib/testing/common/storedValue.ts', 'src/vs/workbench/contrib/testing/common/testItemCollection.ts', 'src/vs/workbench/contrib/testing/test/browser/testObjectTree.ts', 'src/vs/workbench/contrib/typeHierarchy/browser/typeHierarchy.contribution.ts', 'src/vs/workbench/contrib/typeHierarchy/common/typeHierarchy.ts', - 'src/vs/workbench/contrib/update/browser/update.ts', - 'src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts', 'src/vs/workbench/contrib/webview/browser/overlayWebview.ts', 'src/vs/workbench/contrib/webview/browser/webview.ts', 'src/vs/workbench/contrib/webview/browser/webviewElement.ts', @@ -907,76 +863,48 @@ export default tseslint.config( 'src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts', 'src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedAccessibleView.ts', 'src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts', - 'src/vs/workbench/contrib/welcomeViews/common/newFile.contribution.ts', 'src/vs/workbench/contrib/welcomeWalkthrough/browser/walkThroughPart.ts', - 'src/vs/workbench/services/accounts/common/defaultAccount.ts', - 'src/vs/workbench/services/assignment/common/assignmentFilters.ts', 'src/vs/workbench/services/authentication/common/authentication.ts', 'src/vs/workbench/services/authentication/test/browser/authenticationQueryServiceMocks.ts', 'src/vs/workbench/services/commands/common/commandService.ts', 'src/vs/workbench/services/configuration/browser/configuration.ts', 'src/vs/workbench/services/configuration/browser/configurationService.ts', 'src/vs/workbench/services/configuration/common/configurationModels.ts', - 'src/vs/workbench/services/configuration/common/jsonEditingService.ts', - 'src/vs/workbench/services/configuration/test/common/testServices.ts', - 'src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts', 'src/vs/workbench/services/configurationResolver/common/configurationResolver.ts', 'src/vs/workbench/services/configurationResolver/common/configurationResolverExpression.ts', - 'src/vs/workbench/services/configurationResolver/common/variableResolver.ts', 'src/vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.ts', 'src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts', - 'src/vs/workbench/services/extensions/common/extHostCustomers.ts', 'src/vs/workbench/services/extensions/common/extensionHostManager.ts', - 'src/vs/workbench/services/extensions/common/extensionHostProtocol.ts', - 'src/vs/workbench/services/extensions/common/extensionHostProxy.ts', 'src/vs/workbench/services/extensions/common/extensionsRegistry.ts', 'src/vs/workbench/services/extensions/common/lazyPromise.ts', 'src/vs/workbench/services/extensions/common/polyfillNestedWorker.protocol.ts', - 'src/vs/workbench/services/extensions/common/proxyIdentifier.ts', 'src/vs/workbench/services/extensions/common/rpcProtocol.ts', - 'src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts', - 'src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts', 'src/vs/workbench/services/extensions/worker/polyfillNestedWorker.ts', 'src/vs/workbench/services/keybinding/browser/keybindingService.ts', 'src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts', 'src/vs/workbench/services/keybinding/common/keybindingEditing.ts', - 'src/vs/workbench/services/keybinding/common/keybindingIO.ts', 'src/vs/workbench/services/keybinding/common/keymapInfo.ts', 'src/vs/workbench/services/language/common/languageService.ts', - 'src/vs/workbench/services/languageDetection/browser/languageDetectionWorker.protocol.ts', 'src/vs/workbench/services/outline/browser/outline.ts', 'src/vs/workbench/services/outline/browser/outlineService.ts', 'src/vs/workbench/services/preferences/common/preferences.ts', 'src/vs/workbench/services/preferences/common/preferencesModels.ts', 'src/vs/workbench/services/preferences/common/preferencesValidation.ts', 'src/vs/workbench/services/remote/common/tunnelModel.ts', - 'src/vs/workbench/services/search/common/localFileSearchWorkerTypes.ts', 'src/vs/workbench/services/search/common/replace.ts', 'src/vs/workbench/services/search/common/search.ts', 'src/vs/workbench/services/search/common/searchExtConversionTypes.ts', 'src/vs/workbench/services/search/common/searchExtTypes.ts', - 'src/vs/workbench/services/search/common/searchService.ts', 'src/vs/workbench/services/search/node/fileSearch.ts', 'src/vs/workbench/services/search/node/rawSearchService.ts', 'src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts', - 'src/vs/workbench/services/search/worker/localFileSearch.ts', - 'src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker.ts', - 'src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerHost.ts', - 'src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts', 'src/vs/workbench/services/textMate/common/TMGrammarFactory.ts', 'src/vs/workbench/services/themes/browser/fileIconThemeData.ts', 'src/vs/workbench/services/themes/browser/productIconThemeData.ts', - 'src/vs/workbench/services/themes/browser/workbenchThemeService.ts', 'src/vs/workbench/services/themes/common/colorThemeData.ts', 'src/vs/workbench/services/themes/common/plistParser.ts', 'src/vs/workbench/services/themes/common/themeExtensionPoints.ts', 'src/vs/workbench/services/themes/common/workbenchThemeService.ts', - 'src/vs/workbench/services/userActivity/common/userActivityRegistry.ts', - 'src/vs/workbench/services/userData/browser/userDataInit.ts', - 'src/vs/workbench/services/userDataProfile/browser/userDataProfileInit.ts', - 'src/vs/workbench/services/userDataSync/browser/userDataSyncInit.ts', - 'src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts', - 'src/vs/workbench/services/userDataSync/common/userDataSync.ts', 'src/vs/workbench/test/browser/workbenchTestServices.ts', 'src/vs/workbench/test/common/workbenchTestServices.ts', 'src/vs/workbench/test/electron-browser/workbenchTestServices.ts', @@ -1001,7 +929,7 @@ export default tseslint.config( '@typescript-eslint/no-explicit-any': [ 'warn', { - 'fixToUnknown': true + 'fixToUnknown': false } ] } diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index b6444f871cf..466a0e6510f 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -179,6 +179,10 @@ export class ApiRepository implements Repository { return this.#repository.diffIndexWithHEAD(path); } + diffIndexWithHEADShortStats(path?: string): Promise { + return this.#repository.diffIndexWithHEADShortStats(path); + } + diffIndexWith(ref: string): Promise; diffIndexWith(ref: string, path: string): Promise; diffIndexWith(ref: string, path?: string): Promise { diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 3e7b3c7a1c3..f4136483a87 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -242,6 +242,7 @@ export interface Repository { diffWith(ref: string, path: string): Promise; diffIndexWithHEAD(): Promise; diffIndexWithHEAD(path: string): Promise; + diffIndexWithHEADShortStats(path?: string): Promise; diffIndexWith(ref: string): Promise; diffIndexWith(ref: string, path: string): Promise; diffBlobs(object1: string, object2: string): Promise; diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index d14189465f7..a299df96e47 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1658,6 +1658,10 @@ export class Repository { return result.stdout; } + async diffIndexWithHEADShortStats(path?: string): Promise { + return this.diffFilesShortStat(undefined, { cached: true, path }); + } + diffIndexWith(ref: string): Promise; diffIndexWith(ref: string, path: string): Promise; diffIndexWith(ref: string, path?: string | undefined): Promise; diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 9e373b40056..6e61ef6f47d 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -1225,6 +1225,10 @@ export class Repository implements Disposable { return this.run(Operation.Diff, () => this.repository.diffIndexWithHEAD(path)); } + diffIndexWithHEADShortStats(path?: string): Promise { + return this.run(Operation.Diff, () => this.repository.diffIndexWithHEADShortStats(path)); + } + diffIndexWith(ref: string): Promise; diffIndexWith(ref: string, path: string): Promise; diffIndexWith(ref: string, path?: string | undefined): Promise; diff --git a/extensions/ipynb/src/common.ts b/extensions/ipynb/src/common.ts index dbd3ea1a618..f0330c88440 100644 --- a/extensions/ipynb/src/common.ts +++ b/extensions/ipynb/src/common.ts @@ -65,3 +65,36 @@ export interface CellMetadata { execution_count?: number | null; } + + +type KeysOfUnionType = T extends T ? keyof T : never; +type FilterType = T extends TTest ? T : never; +type MakeOptionalAndBool = { [K in keyof T]?: boolean }; + +/** + * Type guard that checks if an object has specific keys and narrows the type accordingly. + * + * @param x - The object to check + * @param key - An object with boolean values indicating which keys to check for + * @returns true if all specified keys exist in the object, false otherwise + * + * @example + * ```typescript + * type A = { a: string }; + * type B = { b: number }; + * const obj: A | B = getObject(); + * + * if (hasKey(obj, { a: true })) { + * // obj is now narrowed to type A + * console.log(obj.a); + * } + * ``` + */ +export function hasKey(x: T, key: TKeys & MakeOptionalAndBool): x is FilterType & keyof TKeys]: unknown }> { + for (const k in key) { + if (!(k in x)) { + return false; + } + } + return true; +} diff --git a/extensions/ipynb/src/deserializers.ts b/extensions/ipynb/src/deserializers.ts index 930092f6feb..b3a347cfe5c 100644 --- a/extensions/ipynb/src/deserializers.ts +++ b/extensions/ipynb/src/deserializers.ts @@ -151,7 +151,7 @@ function convertJupyterOutputToBuffer(mime: string, value: unknown): NotebookCel } } -function getNotebookCellMetadata(cell: nbformat.IBaseCell): { +function getNotebookCellMetadata(cell: nbformat.ICell): { [key: string]: any; } { // We put this only for VSC to display in diff view. @@ -169,7 +169,7 @@ function getNotebookCellMetadata(cell: nbformat.IBaseCell): { cellMetadata['metadata'] = JSON.parse(JSON.stringify(cell['metadata'])); } - if ('id' in cell && typeof cell.id === 'string') { + if (typeof cell.id === 'string') { cellMetadata.id = cell.id; } diff --git a/extensions/ipynb/src/notebookImagePaste.ts b/extensions/ipynb/src/notebookImagePaste.ts index 70a24e9bf2d..97c2ee73946 100644 --- a/extensions/ipynb/src/notebookImagePaste.ts +++ b/extensions/ipynb/src/notebookImagePaste.ts @@ -274,7 +274,7 @@ function buildAttachment( const filenameWithoutExt = basename(attachment.fileName, fileExt); let tempFilename = filenameWithoutExt + fileExt; - for (let appendValue = 2; tempFilename in cellMetadata.attachments; appendValue++) { + for (let appendValue = 2; cellMetadata.attachments[tempFilename]; appendValue++) { const objEntries = Object.entries(cellMetadata.attachments[tempFilename]); if (objEntries.length) { // check that mime:b64 are present const [mime, attachmentb64] = objEntries[0]; diff --git a/extensions/ipynb/src/serializers.ts b/extensions/ipynb/src/serializers.ts index a38ae39b6c7..39413b868df 100644 --- a/extensions/ipynb/src/serializers.ts +++ b/extensions/ipynb/src/serializers.ts @@ -5,7 +5,7 @@ import type * as nbformat from '@jupyterlab/nbformat'; import type { NotebookCell, NotebookCellData, NotebookCellOutput, NotebookData, NotebookDocument } from 'vscode'; -import { CellOutputMetadata, type CellMetadata } from './common'; +import { CellOutputMetadata, hasKey, type CellMetadata } from './common'; import { textMimeTypes, NotebookCellKindMarkup, CellOutputMimeTypes, defaultNotebookFormat } from './constants'; const textDecoder = new TextDecoder(); @@ -50,7 +50,7 @@ export function sortObjectPropertiesRecursively(obj: any): any { } export function getCellMetadata(options: { cell: NotebookCell | NotebookCellData } | { metadata?: { [key: string]: any } }): CellMetadata { - if ('cell' in options) { + if (hasKey(options, { cell: true })) { const cell = options.cell; const metadata = { execution_count: null, @@ -472,7 +472,7 @@ export function serializeNotebookToString(data: NotebookData): string { .map(cell => createJupyterCellFromNotebookCell(cell, preferredCellLanguage)) .map(pruneCell); - const indentAmount = data.metadata && 'indentAmount' in data.metadata && typeof data.metadata.indentAmount === 'string' ? + const indentAmount = data.metadata && typeof data.metadata.indentAmount === 'string' ? data.metadata.indentAmount : ' '; diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index 6c3205fa7b7..2cfa01024ee 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -76,8 +76,8 @@ const domEval = (container: Element) => { }; function getAltText(outputInfo: OutputItem) { - const metadata = outputInfo.metadata; - if (typeof metadata === 'object' && metadata && 'vscode_altText' in metadata && typeof metadata.vscode_altText === 'string') { + const metadata = outputInfo.metadata as Record | undefined; + if (typeof metadata === 'object' && metadata && typeof metadata.vscode_altText === 'string') { return metadata.vscode_altText; } return undefined; @@ -337,9 +337,9 @@ function findScrolledHeight(container: HTMLElement): number | undefined { } function scrollingEnabled(output: OutputItem, options: RenderOptions) { - const metadata = output.metadata; + const metadata = output.metadata as Record | undefined; return (typeof metadata === 'object' && metadata - && 'scrollable' in metadata && typeof metadata.scrollable === 'boolean') ? + && typeof metadata.scrollable === 'boolean') ? metadata.scrollable : options.outputScrolling; } diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/chat.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/chat.test.ts index b00389d4376..ff5b49d9b69 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/chat.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/chat.test.ts @@ -4,8 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import * as fs from 'fs'; +import { join } from 'path'; import 'mocha'; -import { ChatContext, ChatRequest, ChatRequestTurn, ChatRequestTurn2, ChatResult, Disposable, Event, EventEmitter, chat, commands, lm } from 'vscode'; +import { ChatContext, ChatRequest, ChatRequestTurn, ChatRequestTurn2, ChatResult, Disposable, env, Event, EventEmitter, chat, commands, lm, UIKind } from 'vscode'; import { DeferredPromise, asPromise, assertNoRpc, closeAllEditors, delay, disposeAll } from '../utils'; suite('chat', () => { @@ -214,4 +216,28 @@ suite('chat', () => { // Title provider was not called again assert.strictEqual(calls, 1); }); + + test('can access node-pty module', async function () { + // Required for copilot cli in chat extension. + if (env.uiKind === UIKind.Web) { + this.skip(); + } + const nodePtyModules = [ + join(env.appRoot, 'node_modules.asar', 'node-pty'), + join(env.appRoot, 'node_modules', 'node-pty') + ]; + + for (const modulePath of nodePtyModules) { + // try to stat and require module + try { + await fs.promises.stat(modulePath); + const nodePty = require(modulePath); + assert.ok(nodePty, `Successfully required node-pty from ${modulePath}`); + return; + } catch (err) { + // failed to require, try next + } + } + assert.fail('Failed to find and require node-pty module'); + }); }); diff --git a/src/vs/base/browser/ui/toolbar/toolbar.ts b/src/vs/base/browser/ui/toolbar/toolbar.ts index 343761f6e6a..e2286ab838a 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.ts +++ b/src/vs/base/browser/ui/toolbar/toolbar.ts @@ -51,9 +51,11 @@ export interface IToolBarOptions { label?: boolean; /** - * Hiding actions that are not visible + * Controls the responsive behavior of the primary group of the toolbar. + * - `enabled`: Whether the responsive behavior is enabled. + * - `minItems`: The minimum number of items that should always be visible. */ - responsive?: boolean; + responsiveBehavior?: { enabled: boolean; minItems?: number }; } /** @@ -75,7 +77,7 @@ export class ToolBar extends Disposable { private hiddenActions: { action: IAction; size: number }[] = []; private readonly disposables = this._register(new DisposableStore()); - constructor(container: HTMLElement, contextMenuProvider: IContextMenuProvider, options: IToolBarOptions = { orientation: ActionsOrientation.HORIZONTAL }) { + constructor(private readonly container: HTMLElement, contextMenuProvider: IContextMenuProvider, options: IToolBarOptions = { orientation: ActionsOrientation.HORIZONTAL }) { super(); options.hoverDelegate = options.hoverDelegate ?? this._register(createInstantHoverDelegate()); @@ -154,11 +156,11 @@ export class ToolBar extends Disposable { })); // Responsive support - if (this.options.responsive) { + if (this.options.responsiveBehavior?.enabled) { this.element.classList.add('responsive'); const observer = new ResizeObserver(() => { - this.setToolbarMaxWidth(this.element.getBoundingClientRect().width); + this.updateActions(this.element.getBoundingClientRect().width); }); observer.observe(this.element); this._store.add(toDisposable(() => observer.disconnect())); @@ -237,12 +239,31 @@ export class ToolBar extends Disposable { this.actionBar.push(action, { icon: this.options.icon ?? true, label: this.options.label ?? false, keybinding: this.getKeybindingLabel(action) }); }); - if (this.options.responsive) { + if (this.options.responsiveBehavior?.enabled) { // Reset hidden actions this.hiddenActions.length = 0; - // Update toolbar to fit with container width - this.setToolbarMaxWidth(this.element.getBoundingClientRect().width); + // Set the minimum width + if (this.options.responsiveBehavior?.minItems !== undefined) { + let itemCount = this.options.responsiveBehavior.minItems; + + // Account for overflow menu + if ( + this.originalSecondaryActions.length > 0 || + itemCount < this.originalPrimaryActions.length + ) { + itemCount += 1; + } + + this.container.style.minWidth = `${itemCount * ACTION_MIN_WIDTH}px`; + this.element.style.minWidth = `${itemCount * ACTION_MIN_WIDTH}px`; + } else { + this.container.style.minWidth = `${ACTION_MIN_WIDTH}px`; + this.element.style.minWidth = `${ACTION_MIN_WIDTH}px`; + } + + // Update toolbar actions to fit with container width + this.updateActions(this.element.getBoundingClientRect().width); } } @@ -256,24 +277,36 @@ export class ToolBar extends Disposable { return key?.getLabel() ?? undefined; } - private getItemsWidthResponsive(): number { - // Each action is assumed to have a minimum width so that actions with a label - // can shrink to the action's minimum width. We do this so that action visibility - // takes precedence over the action label. - return this.actionBar.length() * ACTION_MIN_WIDTH; - } - - private setToolbarMaxWidth(maxWidth: number) { - if ( - this.actionBar.isEmpty() || - (this.getItemsWidthResponsive() <= maxWidth && this.hiddenActions.length === 0) - ) { + private updateActions(containerWidth: number) { + // Actions bar is empty + if (this.actionBar.isEmpty()) { return; } - if (this.getItemsWidthResponsive() > maxWidth) { + // Each action is assumed to have a minimum width so that actions with a label + // can shrink to the action's minimum width. We do this so that action visibility + // takes precedence over the action label. + const actionBarWidth = () => this.actionBar.length() * ACTION_MIN_WIDTH; + + // Action bar fits and there are no hidden actions to show + if (actionBarWidth() <= containerWidth && this.hiddenActions.length === 0) { + return; + } + + if (actionBarWidth() > containerWidth) { + // Check for max items limit + if (this.options.responsiveBehavior?.minItems !== undefined) { + const primaryActionsCount = this.actionBar.hasAction(this.toggleMenuAction) + ? this.actionBar.length() - 1 + : this.actionBar.length(); + + if (primaryActionsCount <= this.options.responsiveBehavior.minItems) { + return; + } + } + // Hide actions from the right - while (this.getItemsWidthResponsive() > maxWidth && this.actionBar.length() > 0) { + while (actionBarWidth() > containerWidth && this.actionBar.length() > 0) { const index = this.originalPrimaryActions.length - this.hiddenActions.length - 1; if (index < 0) { break; @@ -302,7 +335,7 @@ export class ToolBar extends Disposable { // Show actions from the top of the toggle menu while (this.hiddenActions.length > 0) { const entry = this.hiddenActions.shift()!; - if (this.getItemsWidthResponsive() + entry.size > maxWidth) { + if (actionBarWidth() + entry.size > containerWidth) { // Not enough space to show the action this.hiddenActions.unshift(entry); break; diff --git a/src/vs/base/browser/webWorkerFactory.ts b/src/vs/base/browser/webWorkerFactory.ts index 83c587f16f1..4d0a4f32776 100644 --- a/src/vs/base/browser/webWorkerFactory.ts +++ b/src/vs/base/browser/webWorkerFactory.ts @@ -33,7 +33,7 @@ export function createBlobWorker(blobUrl: string, options?: WorkerOptions): Work return new Worker(ttPolicy ? ttPolicy.createScriptURL(blobUrl) as unknown as string : blobUrl, { ...options, type: 'module' }); } -function getWorker(descriptor: IWebWorkerDescriptor, id: number): Worker | Promise { +function getWorker(descriptor: WebWorkerDescriptor, id: number): Worker | Promise { const label = descriptor.label || 'anonymous' + id; // Option for hosts to overwrite the worker script (used in the standalone editor) @@ -48,9 +48,9 @@ function getWorker(descriptor: IWebWorkerDescriptor, id: number): Worker | Promi } } - const esmWorkerLocation = descriptor.esmModuleLocation; + const esmWorkerLocation = descriptor.getUrl(); if (esmWorkerLocation) { - const workerUrl = getWorkerBootstrapUrl(label, esmWorkerLocation.toString(true)); + const workerUrl = getWorkerBootstrapUrl(label, esmWorkerLocation); const worker = new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label, type: 'module' }); return whenESMWorkerReady(worker); } @@ -128,7 +128,7 @@ class WebWorker extends Disposable implements IWebWorker { private readonly _onError = this._register(new Emitter()); public readonly onError = this._onError.event; - constructor(descriptorOrWorker: IWebWorkerDescriptor | Worker | Promise) { + constructor(descriptorOrWorker: WebWorkerDescriptor | Worker | Promise) { super(); this.id = ++WebWorker.LAST_WORKER_ID; const workerOrPromise = ( @@ -184,21 +184,29 @@ class WebWorker extends Disposable implements IWebWorker { } } -export interface IWebWorkerDescriptor { - readonly esmModuleLocation: URI | undefined; - readonly label: string | undefined; +export class WebWorkerDescriptor { + public readonly esmModuleLocation: URI | (() => URI) | undefined; + public readonly label: string | undefined; + + constructor(args: { + /** The location of the esm module after transpilation */ + esmModuleLocation?: URI | (() => URI); + label?: string; + }) { + this.esmModuleLocation = args.esmModuleLocation; + this.label = args.label; + } + + getUrl(): string | undefined { + if (this.esmModuleLocation) { + const esmWorkerLocation = typeof this.esmModuleLocation === 'function' ? this.esmModuleLocation() : this.esmModuleLocation; + return esmWorkerLocation.toString(true); + } + + return undefined; + } } -export class WebWorkerDescriptor implements IWebWorkerDescriptor { - constructor( - public readonly esmModuleLocation: URI, - public readonly label: string | undefined, - ) { } -} - -export function createWebWorker(esmModuleLocation: URI, label: string | undefined): IWebWorkerClient; -export function createWebWorker(workerDescriptor: IWebWorkerDescriptor | Worker | Promise): IWebWorkerClient; -export function createWebWorker(arg0: URI | IWebWorkerDescriptor | Worker | Promise, arg1?: string | undefined): IWebWorkerClient { - const workerDescriptorOrWorker = (URI.isUri(arg0) ? new WebWorkerDescriptor(arg0, arg1) : arg0); - return new WebWorkerClient(new WebWorker(workerDescriptorOrWorker)); +export function createWebWorker(workerDescriptor: WebWorkerDescriptor | Worker | Promise): IWebWorkerClient { + return new WebWorkerClient(new WebWorker(workerDescriptor)); } diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 287b1a227d1..1af1865d8ab 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -109,7 +109,16 @@ export function binarySearch2(length: number, compareToKey: (index: number) => n type Compare = (a: T, b: T) => number; - +/** + * Finds the nth smallest element in the array using quickselect algorithm. + * The data does not need to be sorted. + * + * @param nth The zero-based index of the element to find (0 = smallest, 1 = second smallest, etc.) + * @param data The unsorted array + * @param compare A comparator function that defines the sort order + * @returns The nth smallest element + * @throws TypeError if nth is >= data.length + */ export function quickSelect(nth: number, data: T[], compare: Compare): T { nth = nth | 0; diff --git a/src/vs/base/common/cancellation.ts b/src/vs/base/common/cancellation.ts index 3be4a90a103..e04c9277b85 100644 --- a/src/vs/base/common/cancellation.ts +++ b/src/vs/base/common/cancellation.ts @@ -21,10 +21,10 @@ export interface CancellationToken { * * @event */ - readonly onCancellationRequested: (listener: (e: any) => any, thisArgs?: any, disposables?: IDisposable[]) => IDisposable; + readonly onCancellationRequested: (listener: (e: void) => unknown, thisArgs?: unknown, disposables?: IDisposable[]) => IDisposable; } -const shortcutEvent: Event = Object.freeze(function (callback, context?): IDisposable { +const shortcutEvent: Event = Object.freeze(function (callback, context?): IDisposable { const handle = setTimeout(callback.bind(context), 0); return { dispose() { clearTimeout(handle); } }; }); @@ -60,7 +60,7 @@ export namespace CancellationToken { class MutableToken implements CancellationToken { private _isCancelled: boolean = false; - private _emitter: Emitter | null = null; + private _emitter: Emitter | null = null; public cancel() { if (!this._isCancelled) { @@ -76,12 +76,12 @@ class MutableToken implements CancellationToken { return this._isCancelled; } - get onCancellationRequested(): Event { + get onCancellationRequested(): Event { if (this._isCancelled) { return shortcutEvent; } if (!this._emitter) { - this._emitter = new Emitter(); + this._emitter = new Emitter(); } return this._emitter.event; } diff --git a/src/vs/base/common/linkedList.ts b/src/vs/base/common/linkedList.ts index 9e6d3333e32..b436c611717 100644 --- a/src/vs/base/common/linkedList.ts +++ b/src/vs/base/common/linkedList.ts @@ -5,11 +5,11 @@ class Node { - static readonly Undefined = new Node(undefined); + static readonly Undefined = new Node(undefined); element: E; - next: Node; - prev: Node; + next: Node | typeof Node.Undefined; + prev: Node | typeof Node.Undefined; constructor(element: E) { this.element = element; @@ -20,8 +20,8 @@ class Node { export class LinkedList { - private _first: Node = Node.Undefined; - private _last: Node = Node.Undefined; + private _first: Node | typeof Node.Undefined = Node.Undefined; + private _last: Node | typeof Node.Undefined = Node.Undefined; private _size: number = 0; get size(): number { @@ -91,7 +91,7 @@ export class LinkedList { } else { const res = this._first.element; this._remove(this._first); - return res; + return res as E; } } @@ -101,7 +101,7 @@ export class LinkedList { } else { const res = this._last.element; this._remove(this._last); - return res; + return res as E; } } @@ -110,11 +110,11 @@ export class LinkedList { return undefined; } else { const res = this._last.element; - return res; + return res as E; } } - private _remove(node: Node): void { + private _remove(node: Node | typeof Node.Undefined): void { if (node.prev !== Node.Undefined && node.next !== Node.Undefined) { // middle const anchor = node.prev; @@ -144,7 +144,7 @@ export class LinkedList { *[Symbol.iterator](): Iterator { let node = this._first; while (node !== Node.Undefined) { - yield node.element; + yield node.element as E; node = node.next; } } diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index 377e37e6ea1..0eb115b0df0 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -116,7 +116,7 @@ export class ResourceMap implements Map { return this.map.delete(this.toKey(resource)); } - forEach(clb: (value: T, key: URI, map: Map) => void, thisArg?: any): void { + forEach(clb: (value: T, key: URI, map: Map) => void, thisArg?: object): void { if (typeof thisArg !== 'undefined') { clb = clb.bind(thisArg); } @@ -185,7 +185,7 @@ export class ResourceSet implements Set { return this._map.delete(value); } - forEach(callbackfn: (value: URI, value2: URI, set: Set) => void, thisArg?: any): void { + forEach(callbackfn: (value: URI, value2: URI, set: Set) => void, thisArg?: unknown): void { this._map.forEach((_value, key) => callbackfn.call(thisArg, key, key, this)); } @@ -340,7 +340,7 @@ export class LinkedMap implements Map { return item.value; } - forEach(callbackfn: (value: V, key: K, map: LinkedMap) => void, thisArg?: any): void { + forEach(callbackfn: (value: V, key: K, map: LinkedMap) => void, thisArg?: unknown): void { const state = this._state; let current = this._head; while (current) { @@ -789,7 +789,7 @@ export class BidirectionalMap { return true; } - forEach(callbackfn: (value: V, key: K, map: BidirectionalMap) => void, thisArg?: any): void { + forEach(callbackfn: (value: V, key: K, map: BidirectionalMap) => void, thisArg?: unknown): void { this._m1.forEach((value, key) => { callbackfn.call(thisArg, value, key, this); }); diff --git a/src/vs/base/common/skipList.ts b/src/vs/base/common/skipList.ts index 295adb603fe..b88184f9935 100644 --- a/src/vs/base/common/skipList.ts +++ b/src/vs/base/common/skipList.ts @@ -35,8 +35,8 @@ export class SkipList implements Map { capacity: number = 2 ** 16 ) { this._maxLevel = Math.max(1, Math.log2(capacity) | 0); - // eslint-disable-next-line local/code-no-any-casts - this._header = new Node(this._maxLevel, NIL, NIL); + + this._header = new Node(this._maxLevel, NIL, NIL); } get size(): number { @@ -44,8 +44,8 @@ export class SkipList implements Map { } clear(): void { - // eslint-disable-next-line local/code-no-any-casts - this._header = new Node(this._maxLevel, NIL, NIL); + + this._header = new Node(this._maxLevel, NIL, NIL); this._size = 0; } @@ -74,7 +74,7 @@ export class SkipList implements Map { // --- iteration - forEach(callbackfn: (value: V, key: K, map: Map) => void, thisArg?: any): void { + forEach(callbackfn: (value: V, key: K, map: Map) => void, thisArg?: unknown): void { let node = this._header.forward[0]; while (node) { callbackfn.call(thisArg, node.value, node.key, this); @@ -169,7 +169,7 @@ export class SkipList implements Map { } } - private static _randomLevel(list: SkipList, p: number = 0.5): number { + private static _randomLevel(list: SkipList, p: number = 0.5): number { let lvl = 1; while (Math.random() < p && lvl < list._maxLevel) { lvl += 1; diff --git a/src/vs/base/common/ternarySearchTree.ts b/src/vs/base/common/ternarySearchTree.ts index 0364b263f69..d184ed1765e 100644 --- a/src/vs/base/common/ternarySearchTree.ts +++ b/src/vs/base/common/ternarySearchTree.ts @@ -781,7 +781,7 @@ export class TernarySearchTree { // for debug/testing _isBalanced(): boolean { - const nodeIsBalanced = (node: TernarySearchTreeNode | undefined): boolean => { + const nodeIsBalanced = (node: TernarySearchTreeNode | undefined): boolean => { if (!node) { return true; } diff --git a/src/vs/editor/browser/config/elementSizeObserver.ts b/src/vs/editor/browser/config/elementSizeObserver.ts index f6c6ac5e926..c1f886e2c35 100644 --- a/src/vs/editor/browser/config/elementSizeObserver.ts +++ b/src/vs/editor/browser/config/elementSizeObserver.ts @@ -47,10 +47,10 @@ export class ElementSizeObserver extends Disposable { // Otherwise we will postpone to the next animation frame. // We'll use `observeContentRect` to store the content rect we received. - let observedDimenstion: IDimension | null = null; + let observedDimension: IDimension | null = null; const observeNow = () => { - if (observedDimenstion) { - this.observe({ width: observedDimenstion.width, height: observedDimenstion.height }); + if (observedDimension) { + this.observe({ width: observedDimension.width, height: observedDimension.height }); } else { this.observe(); } @@ -76,9 +76,9 @@ export class ElementSizeObserver extends Disposable { this._resizeObserver = new ResizeObserver((entries) => { if (entries && entries[0] && entries[0].contentRect) { - observedDimenstion = { width: entries[0].contentRect.width, height: entries[0].contentRect.height }; + observedDimension = { width: entries[0].contentRect.width, height: entries[0].contentRect.height }; } else { - observedDimenstion = null; + observedDimension = null; } shouldObserve = true; update(); diff --git a/src/vs/editor/browser/config/fontMeasurements.ts b/src/vs/editor/browser/config/fontMeasurements.ts index d9a5cb897d9..759add4ccc8 100644 --- a/src/vs/editor/browser/config/fontMeasurements.ts +++ b/src/vs/editor/browser/config/fontMeasurements.ts @@ -271,7 +271,7 @@ class FontMeasurementsCache { this._values[itemId] = value; } - public remove(item: BareFontInfo): void { + public remove(item: FontInfo): void { const itemId = item.getId(); delete this._keys[itemId]; delete this._values[itemId]; diff --git a/src/vs/editor/browser/config/tabFocus.ts b/src/vs/editor/browser/config/tabFocus.ts index 6d821bc2725..4cf0b237248 100644 --- a/src/vs/editor/browser/config/tabFocus.ts +++ b/src/vs/editor/browser/config/tabFocus.ts @@ -4,10 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { Emitter, Event } from '../../../base/common/event.js'; +import { Disposable } from '../../../base/common/lifecycle.js'; -class TabFocusImpl { +class TabFocusImpl extends Disposable { private _tabFocus: boolean = false; - private readonly _onDidChangeTabFocus = new Emitter(); + private readonly _onDidChangeTabFocus = this._register(new Emitter()); public readonly onDidChangeTabFocus: Event = this._onDidChangeTabFocus.event; public getTabFocusMode(): boolean { diff --git a/src/vs/editor/browser/coreCommands.ts b/src/vs/editor/browser/coreCommands.ts index 5669797012b..a1d6137f875 100644 --- a/src/vs/editor/browser/coreCommands.ts +++ b/src/vs/editor/browser/coreCommands.ts @@ -1323,8 +1323,7 @@ export namespace CoreNavigationCommands { EditorScroll_.Unit.WrappedLine, EditorScroll_.Unit.Page, EditorScroll_.Unit.HalfPage, - EditorScroll_.Unit.Editor, - EditorScroll_.Unit.Column + EditorScroll_.Unit.Editor ]; const horizontalDirections = [EditorScroll_.Direction.Left, EditorScroll_.Direction.Right]; const verticalDirections = [EditorScroll_.Direction.Up, EditorScroll_.Direction.Down]; diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index c2cb0d3d596..25cddf41a98 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -272,7 +272,7 @@ export interface IOverlayWidgetPosition { * When set, stacks with other overlay widgets with the same preference, * in an order determined by the ordinal value. */ - stackOridinal?: number; + stackOrdinal?: number; } /** * An overlay widgets renders on top of the text. diff --git a/src/vs/editor/browser/services/editorWorkerService.ts b/src/vs/editor/browser/services/editorWorkerService.ts index d8cd71a153f..48aacd34819 100644 --- a/src/vs/editor/browser/services/editorWorkerService.ts +++ b/src/vs/editor/browser/services/editorWorkerService.ts @@ -7,7 +7,7 @@ import { timeout } from '../../../base/common/async.js'; import { Disposable, IDisposable } from '../../../base/common/lifecycle.js'; import { URI } from '../../../base/common/uri.js'; import { logOnceWebWorkerWarning, IWebWorkerClient, Proxied } from '../../../base/common/worker/webWorker.js'; -import { createWebWorker, IWebWorkerDescriptor } from '../../../base/browser/webWorkerFactory.js'; +import { createWebWorker, WebWorkerDescriptor } from '../../../base/browser/webWorkerFactory.js'; import { Position } from '../../common/core/position.js'; import { IRange, Range } from '../../common/core/range.js'; import { ITextModel } from '../../common/model.js'; @@ -52,7 +52,7 @@ function canSyncModel(modelService: IModelService, resource: URI): boolean { return true; } -export abstract class EditorWorkerService extends Disposable implements IEditorWorkerService { +export class EditorWorkerService extends Disposable implements IEditorWorkerService { declare readonly _serviceBrand: undefined; @@ -61,7 +61,7 @@ export abstract class EditorWorkerService extends Disposable implements IEditorW private readonly _logService: ILogService; constructor( - workerDescriptor: IWebWorkerDescriptor, + workerDescriptor: WebWorkerDescriptor, @IModelService modelService: IModelService, @ITextResourceConfigurationService configurationService: ITextResourceConfigurationService, @ILogService logService: ILogService, @@ -330,7 +330,7 @@ class WorkerManager extends Disposable { private _lastWorkerUsedTime: number; constructor( - private readonly _workerDescriptor: IWebWorkerDescriptor, + private readonly _workerDescriptor: WebWorkerDescriptor, @IModelService modelService: IModelService ) { super(); @@ -427,7 +427,7 @@ export class EditorWorkerClient extends Disposable implements IEditorWorkerClien private _disposed = false; constructor( - private readonly _workerDescriptorOrWorker: IWebWorkerDescriptor | Worker | Promise, + private readonly _workerDescriptorOrWorker: WebWorkerDescriptor | Worker | Promise, keepIdleModels: boolean, @IModelService modelService: IModelService, ) { diff --git a/src/vs/editor/browser/view/domLineBreaksComputer.ts b/src/vs/editor/browser/view/domLineBreaksComputer.ts index 6eed0a076be..881275f34af 100644 --- a/src/vs/editor/browser/view/domLineBreaksComputer.ts +++ b/src/vs/editor/browser/view/domLineBreaksComputer.ts @@ -130,7 +130,7 @@ function createLineBreaks(targetWindow: Window, requests: string[], fontInfo: Fo containerDomNode.innerHTML = trustedhtml as string; containerDomNode.style.position = 'absolute'; - containerDomNode.style.top = '10000'; + containerDomNode.style.top = '10000px'; if (wordBreak === 'keepAll') { // word-break: keep-all; overflow-wrap: anywhere containerDomNode.style.wordBreak = 'keep-all'; diff --git a/src/vs/editor/browser/view/renderingContext.ts b/src/vs/editor/browser/view/renderingContext.ts index fdb24034701..1ed624ecfe4 100644 --- a/src/vs/editor/browser/view/renderingContext.ts +++ b/src/vs/editor/browser/view/renderingContext.ts @@ -87,7 +87,7 @@ export class RenderingContext extends RestrictedRenderingContext { public linesVisibleRangesForRange(range: Range, includeNewLines: boolean): LineVisibleRanges[] | null { const domRanges = this._viewLines.linesVisibleRangesForRange(range, includeNewLines); if (!this._viewLinesGpu) { - return domRanges ?? null; + return domRanges; } const gpuRanges = this._viewLinesGpu.linesVisibleRangesForRange(range, includeNewLines); if (!domRanges) { diff --git a/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts b/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts index dd565eac9e4..875311054f8 100644 --- a/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts +++ b/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts @@ -94,8 +94,7 @@ export abstract class DedupOverlay extends DynamicViewOverlay { let prevClassName: string | null = null; let prevEndLineIndex = 0; - for (let i = 0, len = decorations.length; i < len; i++) { - const d = decorations[i]; + for (const d of decorations) { const className = d.className; const zIndex = d.zIndex; let startLineIndex = Math.max(d.startLineNumber, visibleStartLineNumber) - visibleStartLineNumber; @@ -110,8 +109,8 @@ export abstract class DedupOverlay extends DynamicViewOverlay { prevEndLineIndex = endLineIndex; } - for (let i = startLineIndex; i <= prevEndLineIndex; i++) { - output[i].add(new LineDecorationToRender(className, zIndex, d.tooltip)); + for (let lineIndex = startLineIndex; lineIndex <= prevEndLineIndex; lineIndex++) { + output[lineIndex].add(new LineDecorationToRender(className, zIndex, d.tooltip)); } } diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index 6fb1f36868b..ad53e1e16c1 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -1663,7 +1663,7 @@ class InnerMinimap extends Disposable { continue; } highlightedLines.set(line, true); - const y = layout.getYForLineNumber(startLineNumber, minimapLineHeight); + const y = layout.getYForLineNumber(line, minimapLineHeight); canvasContext.fillRect(MINIMAP_GUTTER_WIDTH, y, canvasContext.canvas.width, minimapLineHeight); } } diff --git a/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts b/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts index a84da6b2b1d..d286e3b2074 100644 --- a/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts +++ b/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts @@ -124,7 +124,7 @@ export class ViewOverlayWidgets extends ViewPart { public setWidgetPosition(widget: IOverlayWidget, position: IOverlayWidgetPosition | null): boolean { const widgetData = this._widgets[widget.getId()]; const preference = position ? position.preference : null; - const stack = position?.stackOridinal; + const stack = position?.stackOrdinal; if (widgetData.preference === preference && widgetData.stack === stack) { this._updateMaxMinWidth(); return false; diff --git a/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts b/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts index 11292eb56a1..2c9deddd77c 100644 --- a/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts +++ b/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts @@ -136,7 +136,7 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler { private _renderOneLane(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], width: number): void { - let currentColorId = 0; + let currentColorId = 0; // will never match a real color id which is > 0 let currentFrom = 0; let currentTo = 0; @@ -147,7 +147,9 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler { const zoneTo = zone.to; if (zoneColorId !== currentColorId) { - ctx.fillRect(0, currentFrom, width, currentTo - currentFrom); + if (currentColorId !== 0) { + ctx.fillRect(0, currentFrom, width, currentTo - currentFrom); + } currentColorId = zoneColorId; ctx.fillStyle = id2Color[currentColorId]; diff --git a/src/vs/editor/browser/viewParts/rulers/rulers.ts b/src/vs/editor/browser/viewParts/rulers/rulers.ts index c0a46927d17..f34f20f43a9 100644 --- a/src/vs/editor/browser/viewParts/rulers/rulers.ts +++ b/src/vs/editor/browser/viewParts/rulers/rulers.ts @@ -66,13 +66,11 @@ export class Rulers extends ViewPart { } if (currentCount < desiredCount) { - const { tabSize } = this._context.viewModel.model.getOptions(); - const rulerWidth = tabSize; let addCount = desiredCount - currentCount; while (addCount > 0) { const node = createFastDomNode(document.createElement('div')); node.setClassName('view-ruler'); - node.setWidth(rulerWidth); + node.setWidth('1px'); this.domNode.appendChild(node); this._renderedRulers.push(node); addCount--; diff --git a/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts b/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts index 71a9a7605c7..dc5dc300709 100644 --- a/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts +++ b/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts @@ -9,7 +9,7 @@ import { ViewPart } from '../../view/viewPart.js'; import { RenderingContext, RestrictedRenderingContext } from '../../view/renderingContext.js'; import { ViewContext } from '../../../common/viewModel/viewContext.js'; import * as viewEvents from '../../../common/viewEvents.js'; -import { EditorOption } from '../../../common/config/editorOptions.js'; +import { EditorOption, RenderMinimap } from '../../../common/config/editorOptions.js'; export class ScrollDecorationViewPart extends ViewPart { @@ -56,7 +56,7 @@ export class ScrollDecorationViewPart extends ViewPart { const options = this._context.configuration.options; const layoutInfo = options.get(EditorOption.layoutInfo); - if (layoutInfo.minimap.renderMinimap === 0 || (layoutInfo.minimap.minimapWidth > 0 && layoutInfo.minimap.minimapLeft === 0)) { + if (layoutInfo.minimap.renderMinimap === RenderMinimap.None || (layoutInfo.minimap.minimapWidth > 0 && layoutInfo.minimap.minimapLeft === 0)) { this._width = layoutInfo.width; } else { this._width = layoutInfo.width - layoutInfo.verticalScrollbarWidth; diff --git a/src/vs/editor/browser/viewParts/viewLines/domReadingContext.ts b/src/vs/editor/browser/viewParts/viewLines/domReadingContext.ts index 1a11700242e..c336dacbcf7 100644 --- a/src/vs/editor/browser/viewParts/viewLines/domReadingContext.ts +++ b/src/vs/editor/browser/viewParts/viewLines/domReadingContext.ts @@ -20,7 +20,8 @@ export class DomReadingContext { const rect = this._domNode.getBoundingClientRect(); this.markDidDomLayout(); this._clientRectDeltaLeft = rect.left; - this._clientRectScale = rect.width / this._domNode.offsetWidth; + const offsetWidth = this._domNode.offsetWidth; + this._clientRectScale = offsetWidth > 0 ? rect.width / offsetWidth : 1; } } diff --git a/src/vs/editor/browser/viewParts/viewLines/viewLines.ts b/src/vs/editor/browser/viewParts/viewLines/viewLines.ts index ccf5bc01ef1..a55c710a568 100644 --- a/src/vs/editor/browser/viewParts/viewLines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/viewLines/viewLines.ts @@ -245,12 +245,10 @@ export class ViewLines extends ViewPart implements IViewLines { return r; } public override onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean { - if (true/*e.inlineDecorationsChanged*/) { - const rendStartLineNumber = this._visibleLines.getStartLineNumber(); - const rendEndLineNumber = this._visibleLines.getEndLineNumber(); - for (let lineNumber = rendStartLineNumber; lineNumber <= rendEndLineNumber; lineNumber++) { - this._visibleLines.getVisibleLine(lineNumber).onDecorationsChanged(); - } + const rendStartLineNumber = this._visibleLines.getStartLineNumber(); + const rendEndLineNumber = this._visibleLines.getEndLineNumber(); + for (let lineNumber = rendStartLineNumber; lineNumber <= rendEndLineNumber; lineNumber++) { + this._visibleLines.getVisibleLine(lineNumber).onDecorationsChanged(); } return true; } @@ -541,7 +539,7 @@ export class ViewLines extends ViewPart implements IViewLines { // only proceed if we just did a layout return; } - if (this._asyncUpdateLineWidths.isScheduled()) { + if (!this._asyncUpdateLineWidths.isScheduled()) { // reading widths is not scheduled => widths are up-to-date return; } diff --git a/src/vs/editor/browser/viewParts/whitespace/whitespace.ts b/src/vs/editor/browser/viewParts/whitespace/whitespace.ts index 5e4aaddb3da..546d268130c 100644 --- a/src/vs/editor/browser/viewParts/whitespace/whitespace.ts +++ b/src/vs/editor/browser/viewParts/whitespace/whitespace.ts @@ -90,14 +90,6 @@ export class WhitespaceOverlay extends DynamicViewOverlay { return; } - const startLineNumber = ctx.visibleRange.startLineNumber; - const endLineNumber = ctx.visibleRange.endLineNumber; - const lineCount = endLineNumber - startLineNumber + 1; - const needed = new Array(lineCount); - for (let i = 0; i < lineCount; i++) { - needed[i] = true; - } - this._renderResult = []; for (let lineNumber = ctx.viewportData.startLineNumber; lineNumber <= ctx.viewportData.endLineNumber; lineNumber++) { const lineIndex = lineNumber - ctx.viewportData.startLineNumber; diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 779dfd9a7b9..5836aadf7ff 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -45,7 +45,7 @@ export class ReplaceOvertypeCommand implements ICommand { } public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { - const intialStartPosition = this._range.getStartPosition(); + const initialStartPosition = this._range.getStartPosition(); const initialEndPosition = this._range.getEndPosition(); const initialEndLineNumber = initialEndPosition.lineNumber; const offsetDelta = this._text.length + (this._range.isEmpty() ? 0 : -1); @@ -53,7 +53,7 @@ export class ReplaceOvertypeCommand implements ICommand { if (endPosition.lineNumber > initialEndLineNumber) { endPosition = new Position(initialEndLineNumber, model.getLineMaxColumn(initialEndLineNumber)); } - const replaceRange = Range.fromPositions(intialStartPosition, endPosition); + const replaceRange = Range.fromPositions(initialStartPosition, endPosition); builder.addTrackedEditOperation(replaceRange, this._text); } diff --git a/src/vs/editor/contrib/codelens/browser/codelens.ts b/src/vs/editor/contrib/codelens/browser/codelens.ts index c91c3092043..fdbcf259f18 100644 --- a/src/vs/editor/contrib/codelens/browser/codelens.ts +++ b/src/vs/editor/contrib/codelens/browser/codelens.ts @@ -112,7 +112,7 @@ CommandsRegistry.registerCommand('_executeCodeLensProvider', function (accessor, return getCodeLensModel(codeLensProvider, model, CancellationToken.None).then(value => { disposables.add(value); - const resolve: Promise[] = []; + const resolve: Promise[] = []; for (const item of value.lenses) { if (itemResolveCount === undefined || itemResolveCount === null || Boolean(item.symbol.command)) { diff --git a/src/vs/editor/contrib/codelens/browser/codelensController.ts b/src/vs/editor/contrib/codelens/browser/codelensController.ts index f34e88a4d24..3a3877a2664 100644 --- a/src/vs/editor/contrib/codelens/browser/codelensController.ts +++ b/src/vs/editor/contrib/codelens/browser/codelensController.ts @@ -42,7 +42,7 @@ export class CodeLensContribution implements IEditorContribution { private _getCodeLensModelPromise: CancelablePromise | undefined; private readonly _oldCodeLensModels = new DisposableStore(); private _currentCodeLensModel: CodeLensModel | undefined; - private _resolveCodeLensesPromise: CancelablePromise | undefined; + private _resolveCodeLensesPromise: CancelablePromise | undefined; constructor( private readonly _editor: ICodeEditor, diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts index 74235c230cc..d8d2bf9e050 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts @@ -435,7 +435,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { getPosition(): IOverlayWidgetPosition | null { return { preference: OverlayWidgetPositionPreference.TOP_CENTER, - stackOridinal: 10, + stackOrdinal: 10, }; } diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index 9ffecaa15ec..36f7ed208ac 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -97,7 +97,7 @@ import { onUnexpectedError } from '../../../base/common/errors.js'; import { ExtensionKind, IEnvironmentService, IExtensionHostDebugParams } from '../../../platform/environment/common/environment.js'; import { mainWindow } from '../../../base/browser/window.js'; import { ResourceMap } from '../../../base/common/map.js'; -import { IWebWorkerDescriptor } from '../../../base/browser/webWorkerFactory.js'; +import { WebWorkerDescriptor } from '../../../base/browser/webWorkerFactory.js'; import { ITreeSitterLibraryService } from '../../common/services/treeSitter/treeSitterLibraryService.js'; import { StandaloneTreeSitterLibraryService } from './standaloneTreeSitterLibraryService.js'; import { IDataChannelService, NullDataChannelService } from '../../../platform/dataChannel/common/dataChannel.js'; @@ -1075,10 +1075,10 @@ class StandaloneContextMenuService extends ContextMenuService { } } -const standaloneEditorWorkerDescriptor: IWebWorkerDescriptor = { +const standaloneEditorWorkerDescriptor = new WebWorkerDescriptor({ esmModuleLocation: undefined, label: 'editorWorkerService' -}; +}); class StandaloneEditorWorkerService extends EditorWorkerService { constructor( diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 986248861e7..0c65323c6b5 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -103,7 +103,7 @@ declare namespace monaco { * * @event */ - readonly onCancellationRequested: (listener: (e: any) => any, thisArgs?: any, disposables?: IDisposable[]) => IDisposable; + readonly onCancellationRequested: (listener: (e: void) => unknown, thisArgs?: unknown, disposables?: IDisposable[]) => IDisposable; } /** * Uniform Resource Identifier (Uri) http://tools.ietf.org/html/rfc3986. @@ -5677,7 +5677,7 @@ declare namespace monaco.editor { * When set, stacks with other overlay widgets with the same preference, * in an order determined by the ordinal value. */ - stackOridinal?: number; + stackOrdinal?: number; } /** diff --git a/src/vs/platform/contextview/browser/contextViewService.ts b/src/vs/platform/contextview/browser/contextViewService.ts index 734a1f32603..1ca549dc76c 100644 --- a/src/vs/platform/contextview/browser/contextViewService.ts +++ b/src/vs/platform/contextview/browser/contextViewService.ts @@ -61,7 +61,7 @@ export class ContextViewHandler extends Disposable implements IContextViewProvid this.contextView.layout(); } - hideContextView(data?: any): void { + hideContextView(data?: unknown): void { this.contextView.hide(data); this.openContextView = undefined; } diff --git a/src/vs/platform/extensionManagement/common/extensionTipsService.ts b/src/vs/platform/extensionManagement/common/extensionTipsService.ts index f63a4b7b21f..82e2c8ba923 100644 --- a/src/vs/platform/extensionManagement/common/extensionTipsService.ts +++ b/src/vs/platform/extensionManagement/common/extensionTipsService.ts @@ -27,7 +27,7 @@ import { ITelemetryService } from '../../telemetry/common/telemetry.js'; export class ExtensionTipsService extends Disposable implements IExtensionTipsService { - _serviceBrand: any; + _serviceBrand: undefined; private readonly allConfigBasedTips: Map = new Map(); diff --git a/src/vs/platform/extensions/common/extensionHostStarter.ts b/src/vs/platform/extensions/common/extensionHostStarter.ts index 1d0d3fe5878..3560e56c19c 100644 --- a/src/vs/platform/extensions/common/extensionHostStarter.ts +++ b/src/vs/platform/extensions/common/extensionHostStarter.ts @@ -25,7 +25,7 @@ export interface IExtensionHostStarter { onDynamicStdout(id: string): Event; onDynamicStderr(id: string): Event; - onDynamicMessage(id: string): Event; + onDynamicMessage(id: string): Event; onDynamicExit(id: string): Event<{ code: number; signal: string }>; createExtensionHost(): Promise<{ id: string }>; diff --git a/src/vs/platform/extensions/electron-main/extensionHostStarter.ts b/src/vs/platform/extensions/electron-main/extensionHostStarter.ts index cd9c209c99d..96cdf66125c 100644 --- a/src/vs/platform/extensions/electron-main/extensionHostStarter.ts +++ b/src/vs/platform/extensions/electron-main/extensionHostStarter.ts @@ -61,7 +61,7 @@ export class ExtensionHostStarter extends Disposable implements IDisposable, IEx return this._getExtHost(id).onStderr; } - onDynamicMessage(id: string): Event { + onDynamicMessage(id: string): Event { return this._getExtHost(id).onMessage; } diff --git a/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerService.ts b/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerService.ts index 1edace6dcaf..c837b9b937d 100644 --- a/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerService.ts +++ b/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ -import { createWebWorker } from '../../../base/browser/webWorkerFactory.js'; +import { createWebWorker, WebWorkerDescriptor } from '../../../base/browser/webWorkerFactory.js'; import { URI } from '../../../base/common/uri.js'; import { Proxied } from '../../../base/common/worker/webWorker.js'; import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js'; @@ -49,8 +49,10 @@ class ProfileAnalysisWorkerService implements IProfileAnalysisWorkerService { private async _withWorker(callback: (worker: Proxied) => Promise): Promise { const worker = createWebWorker( - FileAccess.asBrowserUri('vs/platform/profiling/electron-browser/profileAnalysisWorkerMain.js'), - 'CpuProfileAnalysisWorker' + new WebWorkerDescriptor({ + esmModuleLocation: FileAccess.asBrowserUri('vs/platform/profiling/electron-browser/profileAnalysisWorkerMain.js'), + label: 'CpuProfileAnalysisWorker' + }) ); try { diff --git a/src/vs/platform/theme/common/colors/editorColors.ts b/src/vs/platform/theme/common/colors/editorColors.ts index b4064b3cb2d..d4e26b6c66e 100644 --- a/src/vs/platform/theme/common/colors/editorColors.ts +++ b/src/vs/platform/theme/common/colors/editorColors.ts @@ -94,11 +94,11 @@ export const editorInfoBackground = registerColor('editorInfo.background', nls.localize('editorInfo.background', 'Background color of info text in the editor. The color must not be opaque so as not to hide underlying decorations.'), true); export const editorInfoForeground = registerColor('editorInfo.foreground', - { dark: '#3794FF', light: '#1a85ff', hcDark: '#3794FF', hcLight: '#1a85ff' }, + { dark: '#59a4f9', light: '#0063d3', hcDark: '#59a4f9', hcLight: '#0063d3' }, nls.localize('editorInfo.foreground', 'Foreground color of info squigglies in the editor.')); export const editorInfoBorder = registerColor('editorInfo.border', - { dark: null, light: null, hcDark: Color.fromHex('#3794FF').transparent(0.8), hcLight: '#292929' }, + { dark: null, light: null, hcDark: Color.fromHex('#59a4f9').transparent(0.8), hcLight: '#292929' }, nls.localize('infoBorder', 'If set, color of double underlines for infos in the editor.')); diff --git a/src/vs/platform/userDataSync/common/ignoredExtensions.ts b/src/vs/platform/userDataSync/common/ignoredExtensions.ts index 58e7f35f6ec..3d1afd7156a 100644 --- a/src/vs/platform/userDataSync/common/ignoredExtensions.ts +++ b/src/vs/platform/userDataSync/common/ignoredExtensions.ts @@ -10,7 +10,7 @@ import { createDecorator } from '../../instantiation/common/instantiation.js'; export const IIgnoredExtensionsManagementService = createDecorator('IIgnoredExtensionsManagementService'); export interface IIgnoredExtensionsManagementService { - readonly _serviceBrand: any; + readonly _serviceBrand: undefined; getIgnoredExtensions(installed: ILocalExtension[]): string[]; diff --git a/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts b/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts index 123b2655127..502d5fcf106 100644 --- a/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts +++ b/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts @@ -28,7 +28,7 @@ const productQualityKey = 'sync.productQuality'; export class UserDataAutoSyncService extends Disposable implements IUserDataAutoSyncService { - _serviceBrand: any; + _serviceBrand: undefined; private readonly autoSync = this._register(new MutableDisposable()); private successiveFailures: number = 0; diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index e85295de3db..c929e49dea2 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -545,7 +545,7 @@ export function getEnablementKey(resource: SyncResource) { return `sync.enable.$ // #region User Data Sync Services export const IUserDataSyncEnablementService = createDecorator('IUserDataSyncEnablementService'); export interface IUserDataSyncEnablementService { - _serviceBrand: any; + _serviceBrand: undefined; readonly onDidChangeEnablement: Event; isEnabled(): boolean; @@ -580,7 +580,7 @@ export interface IUserDataManualSyncTask { export const IUserDataSyncService = createDecorator('IUserDataSyncService'); export interface IUserDataSyncService { - _serviceBrand: any; + _serviceBrand: undefined; readonly status: SyncStatus; readonly onDidChangeStatus: Event; @@ -617,7 +617,7 @@ export interface IUserDataSyncService { export const IUserDataSyncResourceProviderService = createDecorator('IUserDataSyncResourceProviderService'); export interface IUserDataSyncResourceProviderService { - _serviceBrand: any; + _serviceBrand: undefined; getRemoteSyncedProfiles(): Promise; getLocalSyncedProfiles(location?: URI): Promise; getRemoteSyncResourceHandles(syncResource: SyncResource, profile?: ISyncUserDataProfile): Promise; @@ -633,7 +633,7 @@ export type SyncOptions = { immediately?: boolean; skipIfSyncedRecently?: boolea export const IUserDataAutoSyncService = createDecorator('IUserDataAutoSyncService'); export interface IUserDataAutoSyncService { - _serviceBrand: any; + _serviceBrand: undefined; readonly onError: Event; turnOn(): Promise; turnOff(everywhere: boolean): Promise; diff --git a/src/vs/platform/userDataSync/common/userDataSyncAccount.ts b/src/vs/platform/userDataSync/common/userDataSyncAccount.ts index 1de4b5a9220..9ab1f7dd0c0 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncAccount.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncAccount.ts @@ -26,7 +26,7 @@ export interface IUserDataSyncAccountService { export class UserDataSyncAccountService extends Disposable implements IUserDataSyncAccountService { - _serviceBrand: any; + _serviceBrand: undefined; private _account: IUserDataSyncAccount | undefined; get account(): IUserDataSyncAccount | undefined { return this._account; } diff --git a/src/vs/platform/userDataSync/common/userDataSyncEnablementService.ts b/src/vs/platform/userDataSync/common/userDataSyncEnablementService.ts index 85968813907..fef99758ee1 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncEnablementService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncEnablementService.ts @@ -14,7 +14,7 @@ const enablementKey = 'sync.enable'; export class UserDataSyncEnablementService extends Disposable implements IUserDataSyncEnablementService { - _serviceBrand: any; + _serviceBrand: undefined; private _onDidChangeEnablement = new Emitter(); readonly onDidChangeEnablement: Event = this._onDidChangeEnablement.event; diff --git a/src/vs/platform/userDataSync/common/userDataSyncLocalStoreService.ts b/src/vs/platform/userDataSync/common/userDataSyncLocalStoreService.ts index 53acee377e0..46f1af8ca85 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncLocalStoreService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncLocalStoreService.ts @@ -17,7 +17,7 @@ import { ALL_SYNC_RESOURCES, IResourceRefHandle, IUserDataSyncLocalStoreService, export class UserDataSyncLocalStoreService extends Disposable implements IUserDataSyncLocalStoreService { - _serviceBrand: any; + _serviceBrand: undefined; constructor( @IEnvironmentService private readonly environmentService: IEnvironmentService, diff --git a/src/vs/platform/userDataSync/common/userDataSyncMachines.ts b/src/vs/platform/userDataSync/common/userDataSyncMachines.ts index c91c8447973..d4233e01d9d 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncMachines.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncMachines.ts @@ -32,7 +32,7 @@ export type IUserDataSyncMachine = Readonly & { readonly isCurrent export const IUserDataSyncMachinesService = createDecorator('IUserDataSyncMachinesService'); export interface IUserDataSyncMachinesService { - _serviceBrand: any; + _serviceBrand: undefined; readonly onDidChange: Event; @@ -79,7 +79,7 @@ export class UserDataSyncMachinesService extends Disposable implements IUserData private static readonly VERSION = 1; private static readonly RESOURCE = 'machines'; - _serviceBrand: any; + _serviceBrand: undefined; private readonly _onDidChange = this._register(new Emitter()); readonly onDidChange = this._onDidChange.event; diff --git a/src/vs/platform/userDataSync/common/userDataSyncResourceProvider.ts b/src/vs/platform/userDataSync/common/userDataSyncResourceProvider.ts index 1c68b537b6a..498d7571514 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncResourceProvider.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncResourceProvider.ts @@ -41,7 +41,7 @@ interface ISyncResourceUriInfo { export class UserDataSyncResourceProviderService implements IUserDataSyncResourceProviderService { - _serviceBrand: any; + _serviceBrand: undefined; private static readonly NOT_EXISTING_RESOURCE = 'not-existing-resource'; private static readonly REMOTE_BACKUP_AUTHORITY = 'remote-backup'; diff --git a/src/vs/platform/userDataSync/common/userDataSyncService.ts b/src/vs/platform/userDataSync/common/userDataSyncService.ts index c2250886621..aadb842c0dd 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncService.ts @@ -63,7 +63,7 @@ const LAST_SYNC_TIME_KEY = 'sync.lastSyncTime'; export class UserDataSyncService extends Disposable implements IUserDataSyncService { - _serviceBrand: any; + _serviceBrand: undefined; private _status: SyncStatus = SyncStatus.Uninitialized; get status(): SyncStatus { return this._status; } @@ -903,7 +903,7 @@ class ProfileSynchronizer extends Disposable { } } -function canBailout(e: any): boolean { +function canBailout(e: unknown): boolean { if (e instanceof UserDataSyncError) { switch (e.code) { case UserDataSyncErrorCode.MethodNotFound: diff --git a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts index 427dd90253e..e5642bc2b8c 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts @@ -52,7 +52,7 @@ type UserDataSyncStore = IUserDataSyncStore & { defaultType: UserDataSyncStoreTy export abstract class AbstractUserDataSyncStoreManagementService extends Disposable implements IUserDataSyncStoreManagementService { - _serviceBrand: any; + _serviceBrand: undefined; private readonly _onDidChangeUserDataSyncStore = this._register(new Emitter()); readonly onDidChangeUserDataSyncStore = this._onDidChangeUserDataSyncStore.event; @@ -702,7 +702,7 @@ export class UserDataSyncStoreClient extends Disposable { export class UserDataSyncStoreService extends UserDataSyncStoreClient implements IUserDataSyncStoreService { - _serviceBrand: any; + _serviceBrand: undefined; constructor( @IUserDataSyncStoreManagementService userDataSyncStoreManagementService: IUserDataSyncStoreManagementService, diff --git a/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts b/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts index 26a65ed6a9a..818f7d1f69b 100644 --- a/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts +++ b/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts @@ -176,7 +176,7 @@ const ALL_SERVER_RESOURCES: ServerResource[] = [...ALL_SYNC_RESOURCES, 'machines export class UserDataSyncTestServer implements IRequestService { - _serviceBrand: any; + _serviceBrand: undefined; readonly url: string = 'http://host:3000'; private session: string | null = null; @@ -366,7 +366,7 @@ export class UserDataSyncTestServer implements IRequestService { export class TestUserDataSyncUtilService implements IUserDataSyncUtilService { - _serviceBrand: any; + _serviceBrand: undefined; async resolveDefaultCoreIgnoredSettings(): Promise { return getDefaultIgnoredSettings(); diff --git a/src/vs/platform/windows/electron-main/windowImpl.ts b/src/vs/platform/windows/electron-main/windowImpl.ts index 20c81027b7f..126e639c407 100644 --- a/src/vs/platform/windows/electron-main/windowImpl.ts +++ b/src/vs/platform/windows/electron-main/windowImpl.ts @@ -1042,6 +1042,16 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { private onConfigurationUpdated(e?: IConfigurationChangeEvent): void { + // Swipe command support (macOS) + if (isMacintosh && (!e || e.affectsConfiguration('workbench.editor.swipeToNavigate'))) { + const swipeToNavigate = this.configurationService.getValue('workbench.editor.swipeToNavigate'); + if (swipeToNavigate) { + this.registerSwipeListener(); + } else { + this.swipeListenerDisposable.clear(); + } + } + // Menubar if (!e || e.affectsConfiguration(MenuSettings.MenuBarVisibility)) { const newMenuBarVisibility = this.getMenuBarVisibility(); @@ -1085,6 +1095,22 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { } } + private readonly swipeListenerDisposable = this._register(new MutableDisposable()); + + private registerSwipeListener(): void { + this.swipeListenerDisposable.value = Event.fromNodeEventEmitter(this._win, 'swipe', (event: Electron.Event, cmd: string) => cmd)(cmd => { + if (!this.isReady) { + return; // window must be ready + } + + if (cmd === 'left') { + this.send('vscode:runAction', { id: 'workbench.action.openPreviousRecentlyUsedEditor', from: 'mouse' }); + } else if (cmd === 'right') { + this.send('vscode:runAction', { id: 'workbench.action.openNextRecentlyUsedEditor', from: 'mouse' }); + } + }); + } + addTabbedWindow(window: ICodeWindow): void { if (isMacintosh && window.win) { this._win.addTabbedWindow(window.win); diff --git a/src/vs/workbench/api/common/extHostDiagnostics.ts b/src/vs/workbench/api/common/extHostDiagnostics.ts index fe0367ccad6..d3e84c8d05f 100644 --- a/src/vs/workbench/api/common/extHostDiagnostics.ts +++ b/src/vs/workbench/api/common/extHostDiagnostics.ts @@ -186,7 +186,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { this.#proxy?.$clear(this._owner); } - forEach(callback: (uri: URI, diagnostics: ReadonlyArray, collection: DiagnosticCollection) => any, thisArg?: any): void { + forEach(callback: (uri: URI, diagnostics: ReadonlyArray, collection: DiagnosticCollection) => unknown, thisArg?: unknown): void { this._checkDisposed(); for (const [uri, values] of this) { callback.call(thisArg, uri, values, this); diff --git a/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts b/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts index f46aa4b4686..ef4941c549e 100644 --- a/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts +++ b/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts @@ -17,7 +17,7 @@ import { ILogService } from '../../../platform/log/common/log.js'; import { IExtensionDescription } from '../../../platform/extensions/common/extensions.js'; import { SerializableObjectWithBuffers } from '../../services/extensions/common/proxyIdentifier.js'; -type Listener = [Function, any, IExtensionDescription]; +type Listener = [Function, unknown, IExtensionDescription]; export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSaveParticipantShape { @@ -62,8 +62,8 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic break; } const document = this._documents.getDocument(resource); - // eslint-disable-next-line local/code-no-any-casts - const success = await this._deliverEventAsyncAndBlameBadListeners(listener, { document, reason: TextDocumentSaveReason.to(reason) }); + + const success = await this._deliverEventAsyncAndBlameBadListeners(listener, { document, reason: TextDocumentSaveReason.to(reason) }); results.push(success); } } finally { @@ -72,7 +72,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic return results; } - private _deliverEventAsyncAndBlameBadListeners([listener, thisArg, extension]: Listener, stubEvent: vscode.TextDocumentWillSaveEvent): Promise { + private _deliverEventAsyncAndBlameBadListeners([listener, thisArg, extension]: Listener, stubEvent: Pick): Promise { const errors = this._badListeners.get(listener); if (typeof errors === 'number' && errors > this._thresholds.errors) { // bad listener - ignore @@ -100,7 +100,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic }); } - private _deliverEventAsync(extension: IExtensionDescription, listener: Function, thisArg: any, stubEvent: vscode.TextDocumentWillSaveEvent): Promise { + private _deliverEventAsync(extension: IExtensionDescription, listener: Function, thisArg: unknown, stubEvent: Pick): Promise { const promises: Promise[] = []; @@ -111,6 +111,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic const event = Object.freeze({ document, reason, + // eslint-disable-next-line @typescript-eslint/no-explicit-any waitUntil(p: Promise) { if (Object.isFrozen(promises)) { throw illegalState('waitUntil can not be called async'); diff --git a/src/vs/workbench/browser/actions/media/actions.css b/src/vs/workbench/browser/actions/media/actions.css index 3fe27d61027..7c6dce32a59 100644 --- a/src/vs/workbench/browser/actions/media/actions.css +++ b/src/vs/workbench/browser/actions/media/actions.css @@ -3,8 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.monaco-workbench .quick-input-list .quick-input-list-entry.has-actions:hover .quick-input-list-entry-action-bar .action-label.dirty-workspace::before { - /* Close icon flips between black dot and "X" for dirty workspaces */ +.monaco-workbench .quick-input-list .quick-input-list-entry.has-actions:hover .quick-input-list-entry-action-bar .action-label.dirty-workspace::before, +.monaco-workbench .quick-input-list .quick-input-list-entry.has-actions:hover .quick-input-list-entry-action-bar .action-label.opened-workspace::before { + /* Close icon flips between black dot and "X" some entries in the recently opened picker */ content: var(--vscode-icon-x-content); font-family: var(--vscode-icon-x-font-family); } diff --git a/src/vs/workbench/browser/actions/windowActions.ts b/src/vs/workbench/browser/actions/windowActions.ts index 808d5e717ca..8ece6702060 100644 --- a/src/vs/workbench/browser/actions/windowActions.ts +++ b/src/vs/workbench/browser/actions/windowActions.ts @@ -13,7 +13,7 @@ import { IsMacNativeContext, IsDevelopmentContext, IsWebContext, IsIOSContext } import { Categories } from '../../../platform/action/common/actionCommonCategories.js'; import { KeybindingsRegistry, KeybindingWeight } from '../../../platform/keybinding/common/keybindingsRegistry.js'; import { IQuickInputButton, IQuickInputService, IQuickPickSeparator, IKeyMods, IQuickPickItem } from '../../../platform/quickinput/common/quickInput.js'; -import { IWorkspaceContextService, IWorkspaceIdentifier } from '../../../platform/workspace/common/workspace.js'; +import { IWorkspaceContextService, IWorkspaceIdentifier, isWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from '../../../platform/workspace/common/workspace.js'; import { ILabelService, Verbosity } from '../../../platform/label/common/label.js'; import { IKeybindingService } from '../../../platform/keybinding/common/keybinding.js'; import { IModelService } from '../../../editor/common/services/model.js'; @@ -62,6 +62,17 @@ abstract class BaseOpenRecentAction extends Action2 { tooltip: localize('dirtyRecentlyOpenedWorkspace', "Workspace With Unsaved Files"), }; + private readonly windowOpenedRecentlyOpenedFolder: IQuickInputButton = { + iconClass: 'opened-workspace ' + ThemeIcon.asClassName(Codicon.window), + tooltip: localize('openedRecentlyOpenedFolder', "Folder Opened in a Window"), + alwaysVisible: true + }; + + private readonly windowOpenedRecentlyOpenedWorkspace: IQuickInputButton = { + ...this.windowOpenedRecentlyOpenedFolder, + tooltip: localize('openedRecentlyOpenedWorkspace', "Workspace Opened in a Window"), + }; + protected abstract isQuickNavigate(): boolean; override async run(accessor: ServicesAccessor): Promise { @@ -75,8 +86,11 @@ abstract class BaseOpenRecentAction extends Action2 { const hostService = accessor.get(IHostService); const dialogService = accessor.get(IDialogService); - const recentlyOpened = await workspacesService.getRecentlyOpened(); - const dirtyWorkspacesAndFolders = await workspacesService.getDirtyWorkspaces(); + const [mainWindows, recentlyOpened, dirtyWorkspacesAndFolders] = await Promise.all([ + hostService.getWindows({ includeAuxiliaryWindows: false }), + workspacesService.getRecentlyOpened(), + workspacesService.getDirtyWorkspaces() + ]); let hasWorkspaces = false; @@ -92,6 +106,16 @@ abstract class BaseOpenRecentAction extends Action2 { } } + // Identify all folders and workspaces opened in main windows + const openedInWindows = new ResourceMap(); + for (const window of mainWindows) { + if (isSingleFolderWorkspaceIdentifier(window.workspace)) { + openedInWindows.set(window.workspace.uri, true); + } else if (isWorkspaceIdentifier(window.workspace)) { + openedInWindows.set(window.workspace.configPath, true); + } + } + // Identify all recently opened folders and workspaces const recentFolders = new ResourceMap(); const recentWorkspaces = new ResourceMap(); @@ -108,20 +132,21 @@ abstract class BaseOpenRecentAction extends Action2 { const workspacePicks: IRecentlyOpenedPick[] = []; for (const recent of recentlyOpened.workspaces) { const isDirty = isRecentFolder(recent) ? dirtyFolders.has(recent.folderUri) : dirtyWorkspaces.has(recent.workspace.configPath); + const isOpenedInWindow = isRecentFolder(recent) ? openedInWindows.has(recent.folderUri) : openedInWindows.has(recent.workspace.configPath); - workspacePicks.push(this.toQuickPick(modelService, languageService, labelService, recent, isDirty)); + workspacePicks.push(this.toQuickPick(modelService, languageService, labelService, recent, { isDirty, isOpenedInWindow })); } // Fill any backup workspace that is not yet shown at the end for (const dirtyWorkspaceOrFolder of dirtyWorkspacesAndFolders) { if (isFolderBackupInfo(dirtyWorkspaceOrFolder) && !recentFolders.has(dirtyWorkspaceOrFolder.folderUri)) { - workspacePicks.push(this.toQuickPick(modelService, languageService, labelService, dirtyWorkspaceOrFolder, true)); + workspacePicks.push(this.toQuickPick(modelService, languageService, labelService, dirtyWorkspaceOrFolder, { isDirty: true, isOpenedInWindow: false })); } else if (isWorkspaceBackupInfo(dirtyWorkspaceOrFolder) && !recentWorkspaces.has(dirtyWorkspaceOrFolder.workspace.configPath)) { - workspacePicks.push(this.toQuickPick(modelService, languageService, labelService, dirtyWorkspaceOrFolder, true)); + workspacePicks.push(this.toQuickPick(modelService, languageService, labelService, dirtyWorkspaceOrFolder, { isDirty: true, isOpenedInWindow: false })); } } - const filePicks = recentlyOpened.files.map(p => this.toQuickPick(modelService, languageService, labelService, p, false)); + const filePicks = recentlyOpened.files.map(p => this.toQuickPick(modelService, languageService, labelService, p, { isDirty: false, isOpenedInWindow: false })); // focus second entry if the first recent workspace is the current workspace const firstEntry = recentlyOpened.workspaces[0]; @@ -145,7 +170,7 @@ abstract class BaseOpenRecentAction extends Action2 { onDidTriggerItemButton: async context => { // Remove - if (context.button === this.removeFromRecentlyOpened) { + if (context.button === this.removeFromRecentlyOpened || context.button === this.windowOpenedRecentlyOpenedFolder || context.button === this.windowOpenedRecentlyOpenedWorkspace) { await workspacesService.removeRecentlyOpened([context.item.resource]); context.removeItem(); } @@ -179,7 +204,7 @@ abstract class BaseOpenRecentAction extends Action2 { } } - private toQuickPick(modelService: IModelService, languageService: ILanguageService, labelService: ILabelService, recent: IRecent, isDirty: boolean): IRecentlyOpenedPick { + private toQuickPick(modelService: IModelService, languageService: ILanguageService, labelService: ILabelService, recent: IRecent, kind: { isDirty: boolean; isOpenedInWindow: boolean }): IRecentlyOpenedPick { let openable: IWindowOpenable | undefined; let iconClasses: string[]; let fullLabel: string | undefined; @@ -213,12 +238,21 @@ abstract class BaseOpenRecentAction extends Action2 { const { name, parentPath } = splitRecentLabel(fullLabel); + const buttons: IQuickInputButton[] = []; + if (kind.isDirty) { + buttons.push(isWorkspace ? this.dirtyRecentlyOpenedWorkspace : this.dirtyRecentlyOpenedFolder); + } else if (kind.isOpenedInWindow) { + buttons.push(isWorkspace ? this.windowOpenedRecentlyOpenedWorkspace : this.windowOpenedRecentlyOpenedFolder); + } else { + buttons.push(this.removeFromRecentlyOpened); + } + return { iconClasses, label: name, - ariaLabel: isDirty ? isWorkspace ? localize('recentDirtyWorkspaceAriaLabel', "{0}, workspace with unsaved changes", name) : localize('recentDirtyFolderAriaLabel', "{0}, folder with unsaved changes", name) : name, + ariaLabel: kind.isDirty ? isWorkspace ? localize('recentDirtyWorkspaceAriaLabel', "{0}, workspace with unsaved changes", name) : localize('recentDirtyFolderAriaLabel', "{0}, folder with unsaved changes", name) : name, description: parentPath, - buttons: isDirty ? [isWorkspace ? this.dirtyRecentlyOpenedWorkspace : this.dirtyRecentlyOpenedFolder] : [this.removeFromRecentlyOpened], + buttons, openable, resource, remoteAuthority: recent.remoteAuthority diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index c517d4fbd29..7d0fcca60ea 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -3050,7 +3050,18 @@ class LayoutStateModel extends Disposable { } private loadKeyFromStorage(key: WorkbenchLayoutStateKey): T | undefined { - const value = this.storageService.get(`${LayoutStateModel.STORAGE_PREFIX}${key.name}`, key.scope); + let value = this.storageService.get(`${LayoutStateModel.STORAGE_PREFIX}${key.name}`, key.scope); + + // TODO@bpasero remove this code in 1y when "pre-AI" workspaces have migrated + // Refs: https://github.com/microsoft/vscode-internalbacklog/issues/6168 + if ( + key.scope === StorageScope.WORKSPACE && + key.name === LayoutStateKeys.AUXILIARYBAR_HIDDEN.name && + this.configurationService.getValue('workbench.secondarySideBar.enableDefaultVisibilityInOldWorkspace') === true && + this.storageService.get('workbench.panel.chat.numberOfVisibleViews', StorageScope.WORKSPACE) === undefined + ) { + value = undefined; + } if (value !== undefined) { this.isNew[key.scope] = false; // remember that we had previous state for this scope diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 9cb6048294f..6ad27655a91 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -64,6 +64,7 @@ export const DEFAULT_EDITOR_PART_OPTIONS: IEditorPartOptions = { scrollToSwitchTabs: false, enablePreviewFromCodeNavigation: false, closeOnFileDelete: false, + swipeToNavigate: false, mouseBackForwardToNavigate: true, restoreViewState: true, splitInGroupLayout: 'horizontal', @@ -137,6 +138,7 @@ function validateEditorPartOptions(options: IEditorPartOptions): IEditorPartOpti 'closeOnFileDelete': new BooleanVerifier(DEFAULT_EDITOR_PART_OPTIONS['closeOnFileDelete']), 'closeEmptyGroups': new BooleanVerifier(DEFAULT_EDITOR_PART_OPTIONS['closeEmptyGroups']), 'revealIfOpen': new BooleanVerifier(DEFAULT_EDITOR_PART_OPTIONS['revealIfOpen']), + 'swipeToNavigate': new BooleanVerifier(DEFAULT_EDITOR_PART_OPTIONS['swipeToNavigate']), 'mouseBackForwardToNavigate': new BooleanVerifier(DEFAULT_EDITOR_PART_OPTIONS['mouseBackForwardToNavigate']), 'restoreViewState': new BooleanVerifier(DEFAULT_EDITOR_PART_OPTIONS['restoreViewState']), 'splitOnDragAndDrop': new BooleanVerifier(DEFAULT_EDITOR_PART_OPTIONS['splitOnDragAndDrop']), diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index a971e7e18c7..6d4fd38070c 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -348,6 +348,12 @@ const registry = Registry.as(ConfigurationExtensions.Con 'description': localize('revealIfOpen', "Controls whether an editor is revealed in any of the visible groups if opened. If disabled, an editor will prefer to open in the currently active editor group. If enabled, an already opened editor will be revealed instead of opened again in the currently active editor group. Note that there are some cases where this setting is ignored, such as when forcing an editor to open in a specific group or to the side of the currently active group."), 'default': false }, + 'workbench.editor.swipeToNavigate': { + 'type': 'boolean', + 'description': localize('swipeToNavigate', "Navigate between open files using three-finger swipe horizontally. Note that System Preferences > Trackpad > More Gestures must be set to 'Swipe with two or three fingers'."), + 'default': false, + 'included': isMacintosh && !isWeb + }, 'workbench.editor.mouseBackForwardToNavigate': { 'type': 'boolean', 'description': localize('mouseBackForwardToNavigate', "Enables the use of mouse buttons four and five for commands 'Go Back' and 'Go Forward'."), @@ -568,6 +574,15 @@ const registry = Registry.as(ConfigurationExtensions.Con localize('workbench.secondarySideBar.defaultVisibility.maximized', "The secondary side bar is visible and maximized by default.") ] }, + 'workbench.secondarySideBar.enableDefaultVisibilityInOldWorkspace': { + 'type': 'boolean', + 'default': false, + 'description': localize('enableDefaultVisibilityInOldWorkspace', "Enables the default secondary sidebar visibility in older workspaces before we had default visibility support."), + 'tags': ['advanced'], + 'experiment': { + 'mode': 'auto' + } + }, 'workbench.secondarySideBar.showLabels': { 'type': 'boolean', 'default': true, diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 56a84dc5c87..eded82c1171 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -1254,6 +1254,7 @@ interface IEditorPartConfiguration { closeEmptyGroups?: boolean; autoLockGroups?: Set; revealIfOpen?: boolean; + swipeToNavigate?: boolean; mouseBackForwardToNavigate?: boolean; labelFormat?: 'default' | 'short' | 'medium' | 'long'; restoreViewState?: boolean; diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts index 117d84e18d3..96d3eda8f36 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts @@ -45,6 +45,7 @@ import { getEditingSessionContext } from '../chatEditing/chatEditingActions.js'; import { ACTION_ID_NEW_CHAT, CHAT_CATEGORY, handleCurrentEditingSession, handleModeSwitch } from './chatActions.js'; import { ctxHasEditorModification } from '../chatEditing/chatEditingEditorContextKeys.js'; import { chatSessionResourceToId } from '../../common/chatUri.js'; +import { isITextModel } from '../../../../../editor/common/model.js'; export interface IVoiceChatExecuteActionContext { readonly disableTimeout?: boolean; @@ -822,7 +823,7 @@ export class CreateRemoteAgentJobAction extends Action2 { if (activeEditor) { const model = activeEditor.getModel(); let activeEditorUri: URI | undefined = undefined; - if (model && 'uri' in model) { + if (model && isITextModel(model)) { activeEditorUri = model.uri as URI; } const selection = activeEditor.getSelection(); diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.ts b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.ts new file mode 100644 index 00000000000..5a5b4b8cf91 --- /dev/null +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.ts @@ -0,0 +1,104 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import './media/agentsessionsactions.css'; +import { localize } from '../../../../../nls.js'; +import { IAgentSessionViewModel } from './agentSessionViewModel.js'; +import { Action, IAction } from '../../../../../base/common/actions.js'; +import { ActionViewItem, IActionViewItemOptions } from '../../../../../base/browser/ui/actionbar/actionViewItems.js'; +import { ICommandService } from '../../../../../platform/commands/common/commands.js'; +import { EventHelper, h, hide, show } from '../../../../../base/browser/dom.js'; +import { assertReturnsDefined } from '../../../../../base/common/types.js'; + +//#region Diff Statistics Action + +export class AgentSessionShowDiffAction extends Action { + + static ID = 'agentSession.showDiff'; + + constructor( + private readonly session: IAgentSessionViewModel + ) { + super(AgentSessionShowDiffAction.ID, localize('showDiff', "Open Changes"), undefined, true); + } + + override async run(): Promise { + // This will be handled by the action view item + } + + getSession(): IAgentSessionViewModel { + return this.session; + } +} + +export class AgentSessionDiffActionViewItem extends ActionViewItem { + + override get action(): AgentSessionShowDiffAction { + return super.action as AgentSessionShowDiffAction; + } + + constructor( + action: IAction, + options: IActionViewItemOptions, + @ICommandService private readonly commandService: ICommandService + ) { + super(null, action, options); + } + + override render(container: HTMLElement): void { + super.render(container); + + const label = assertReturnsDefined(this.label); + label.textContent = ''; + + const session = this.action.getSession(); + const diff = session.statistics; + if (!diff) { + return; + } + + const elements = h( + 'div.agent-session-diff-container@diffContainer', + [ + h('span.agent-session-diff-files@filesSpan'), + h('span.agent-session-diff-added@addedSpan'), + h('span.agent-session-diff-removed@removedSpan') + ] + ); + + if (diff.files > 0) { + elements.filesSpan.textContent = `${diff.files}`; + show(elements.filesSpan); + } else { + hide(elements.filesSpan); + } + + if (diff.insertions > 0) { + elements.addedSpan.textContent = `+${diff.insertions}`; + show(elements.addedSpan); + } else { + hide(elements.addedSpan); + } + + if (diff.deletions > 0) { + elements.removedSpan.textContent = `-${diff.deletions}`; + show(elements.removedSpan); + } else { + hide(elements.removedSpan); + } + + label.appendChild(elements.diffContainer); + } + + override onClick(event: MouseEvent): void { + EventHelper.stop(event, true); + + const session = this.action.getSession(); + + this.commandService.executeCommand(`agentSession.${session.provider.chatSessionType}.openChanges`, this.action.getSession().resource); + } +} + +//#endregion diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts index 59422d1203b..8d76b30ceaa 100644 --- a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts @@ -35,6 +35,8 @@ import { IViewDescriptorService, ViewContainerLocation } from '../../../../commo import { IHoverService } from '../../../../../platform/hover/browser/hover.js'; import { AGENT_SESSIONS_VIEW_ID } from './agentSessions.js'; import { IntervalTimer } from '../../../../../base/common/async.js'; +import { ActionBar } from '../../../../../base/browser/ui/actionbar/actionbar.js'; +import { AgentSessionDiffActionViewItem, AgentSessionShowDiffAction } from './agentSessionsActions.js'; interface IAgentSessionItemTemplate { readonly element: HTMLElement; @@ -44,10 +46,7 @@ interface IAgentSessionItemTemplate { // Column 2 Row 1 readonly title: IconLabel; - - readonly diffFiles: HTMLElement; - readonly diffAdded: HTMLElement; - readonly diffRemoved: HTMLElement; + readonly toolbar: ActionBar; // Column 2 Row 2 readonly description: HTMLElement; @@ -69,6 +68,7 @@ export class AgentSessionRenderer implements ICompressibleTreeRenderer { + if (action.id === AgentSessionShowDiffAction.ID) { + return this.instantiationService.createInstance(AgentSessionDiffActionViewItem, action, options); + } + + return undefined; + }, + })); + return { element: elements.item, icon: elements.icon, title: disposables.add(new IconLabel(elements.title, { supportHighlights: true, supportIcons: true })), description: elements.description, - diffFiles: elements.diffFiles, - diffAdded: elements.diffAdded, - diffRemoved: elements.diffRemoved, + toolbar, status: elements.status, elementDisposable, disposables @@ -127,17 +131,20 @@ export class AgentSessionRenderer implements ICompressibleTreeRenderer 0 ? `${diff.files}` : ''; - template.diffAdded.textContent = diff?.insertions && diff.insertions > 0 ? `+${diff.insertions}` : ''; - template.diffRemoved.textContent = diff?.deletions && diff.deletions > 0 ? `-${diff.deletions}` : ''; + if (diff && (diff.files > 0 || diff.insertions > 0 || diff.deletions > 0)) { + const diffAction = template.elementDisposable.add(new AgentSessionShowDiffAction(session.element)); + template.toolbar.push([diffAction], { icon: false, label: true }); + } // Description if (typeof session.element.description === 'string') { template.description.textContent = session.element.description; } else { - template.elementDisposable.add(this.markdownRendererService.render(session.element.description, { + const descriptionMarkdown = this.markdownRendererService.render(session.element.description, { sanitizerConfig: { replaceWithPlaintext: true, allowedTags: { @@ -145,14 +152,19 @@ export class AgentSessionRenderer implements ICompressibleTreeRenderer e.stopPropagation())); - template.elementDisposable.add(addDisposableListener(template.description, EventType.CLICK, e => e.stopPropagation())); - template.elementDisposable.add(addDisposableListener(template.description, EventType.AUXCLICK, e => e.stopPropagation())); + // Prevent link clicks from opening the session itself + // by stopping propagation of mouse events from links + // within (TODO@bpasero revisit this in the future). + // eslint-disable-next-line no-restricted-syntax + const anchors = descriptionMarkdown.element.querySelectorAll('a'); + for (const anchor of anchors) { + template.elementDisposable.add(addDisposableListener(anchor, EventType.MOUSE_DOWN, e => e.stopPropagation())); + template.elementDisposable.add(addDisposableListener(anchor, EventType.CLICK, e => e.stopPropagation())); + template.elementDisposable.add(addDisposableListener(anchor, EventType.AUXCLICK, e => e.stopPropagation())); + } } // Status (updated every minute) diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsactions.css b/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsactions.css new file mode 100644 index 00000000000..9d5a967ce23 --- /dev/null +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsactions.css @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.agent-sessions-viewer .agent-session-item .agent-session-toolbar { + + .monaco-action-bar .actions-container .action-item .action-label { + padding: 0; + } + + .agent-session-diff-container { + font-size: 12px; + font-weight: 500; + display: flex; + gap: 4px; + padding: 0 4px; /* to make space for hover effect */ + } + + .agent-session-diff-files { + color: var(--vscode-descriptionForeground); + } + + .agent-session-diff-added { + color: var(--vscode-chat-linesAddedForeground); + } + + .agent-session-diff-removed { + color: var(--vscode-chat-linesRemovedForeground); + } +} + +.monaco-list-row.selected .agent-session-item .agent-session-toolbar { + + .agent-session-diff-files, + .agent-session-diff-added, + .agent-session-diff-removed { + color: unset; + } +} diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsviewer.css b/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsviewer.css index 976ba9735ab..16017adb600 100644 --- a/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsviewer.css +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsviewer.css @@ -9,10 +9,7 @@ display: none !important; } - .monaco-list-row.selected .agent-session-details-row, - .monaco-list-row.selected span.agent-session-diff-files, - .monaco-list-row.selected span.agent-session-diff-added, - .monaco-list-row.selected span.agent-session-diff-removed { + .monaco-list-row.selected .agent-session-details-row { color: unset; .rendered-markdown { @@ -37,7 +34,7 @@ .agent-session-icon-col { display: flex; align-items: flex-start; - padding-top: 4px; + padding-top: 5px; .agent-session-icon { flex-shrink: 0; @@ -56,7 +53,6 @@ display: flex; align-items: center; line-height: 20px; /* ends up as 22px with the padding below */ - gap: 6px; } .agent-session-title-row { @@ -92,26 +88,8 @@ overflow: hidden; } - /* #region Diff Styling */ - - .agent-session-diff { - font-size: 12px; - display: flex; - gap: 4px; + .agent-session-status { + padding: 0 4px 0 0; /* to align with diff area above */ } - - span.agent-session-diff-files { - color: var(--vscode-descriptionForeground); - } - - span.agent-session-diff-added { - color: var(--vscode-chat-linesAddedForeground); - } - - span.agent-session-diff-removed { - color: var(--vscode-chat-linesRemovedForeground); - } - - /* #endregion */ } } diff --git a/src/vs/workbench/contrib/chat/browser/chat.ts b/src/vs/workbench/contrib/chat/browser/chat.ts index ef3cd80dee3..bbe78b7c869 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.ts @@ -56,7 +56,7 @@ export interface IChatWidgetService { } export async function showChatWidgetInViewOrEditor(accessor: ServicesAccessor, widget: IChatWidget) { - if ('viewId' in widget.viewContext) { + if (isIChatViewViewContext(widget.viewContext)) { await accessor.get(IViewsService).openView(widget.viewContext.viewId); } else { const sessionResource = widget.viewModel?.sessionResource; @@ -185,11 +185,19 @@ export interface IChatViewViewContext { viewId: string; } +export function isIChatViewViewContext(context: IChatWidgetViewContext): context is IChatViewViewContext { + return typeof (context as IChatViewViewContext).viewId === 'string'; +} + export interface IChatResourceViewContext { isQuickChat?: boolean; isInlineChat?: boolean; } +export function isIChatResourceViewContext(context: IChatWidgetViewContext): context is IChatResourceViewContext { + return !isIChatViewViewContext(context); +} + export type IChatWidgetViewContext = IChatViewViewContext | IChatResourceViewContext | {}; export interface IChatAcceptInputOptions { diff --git a/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.ts b/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.ts index a1ec84829ab..0c447d85f15 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.ts @@ -744,7 +744,7 @@ class DiffHunkWidget implements IOverlayWidget, IModifiedFileEntryChangeHunk { const scrollTop = this._editor.getScrollTop(); this._position = { - stackOridinal: 1, + stackOrdinal: 1, preference: { top: this._editor.getTopForLineNumber(startLineNumber) - scrollTop - (lineHeight * this._lineDelta), left: contentLeft + contentWidth - (2 * verticalScrollbarWidth + getTotalWidth(this._domNode)) @@ -814,7 +814,7 @@ class AccessibleDiffViewContainer implements IOverlayWidget { getPosition(): IOverlayWidgetPosition | null { return { preference: { top: 0, left: 0 }, - stackOridinal: 1 + stackOrdinal: 1 }; } } diff --git a/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts b/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts index bf9fcb14a89..1bbebee9f85 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts @@ -271,7 +271,7 @@ export class ChatEditorInput extends EditorInput implements IEditorCloseHandler ?? this.chatService.startSession(ChatAgentLocation.Chat, CancellationToken.None, undefined, { canUseTools: false }); } else if (!this.options.target) { this.model = this.chatService.startSession(ChatAgentLocation.Chat, CancellationToken.None, undefined, { canUseTools: !inputType }); - } else if ('data' in this.options.target) { + } else if (this.options.target.data) { this.model = this.chatService.loadSessionFromContent(this.options.target.data); } diff --git a/src/vs/workbench/contrib/chat/browser/chatFollowups.ts b/src/vs/workbench/contrib/chat/browser/chatFollowups.ts index f4d55df96e4..2c2bd77a0c6 100644 --- a/src/vs/workbench/contrib/chat/browser/chatFollowups.ts +++ b/src/vs/workbench/contrib/chat/browser/chatFollowups.ts @@ -47,7 +47,7 @@ export class ChatFollowups extends Disposable { : followup.title; const message = followup.kind === 'reply' ? followup.message : followup.title; const tooltip = (tooltipPrefix + - ('tooltip' in followup && followup.tooltip || message)).trim(); + (followup.tooltip || message)).trim(); const button = this._register(new Button(container, { ...this.options, title: tooltip })); if (followup.kind === 'reply') { button.element.classList.add('interactive-followup-reply'); diff --git a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts index d7d71a24dda..4caa5ea693a 100644 --- a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts @@ -37,7 +37,6 @@ import { CodeEditorWidget } from '../../../../editor/browser/widget/codeEditor/c import { EditorOptions, IEditorOptions } from '../../../../editor/common/config/editorOptions.js'; import { IDimension } from '../../../../editor/common/core/2d/dimension.js'; import { IPosition } from '../../../../editor/common/core/position.js'; -import { Range } from '../../../../editor/common/core/range.js'; import { isLocation } from '../../../../editor/common/languages.js'; import { ITextModel } from '../../../../editor/common/model.js'; import { IModelService } from '../../../../editor/common/services/model.js'; @@ -1616,8 +1615,8 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge this.promptFileAttached.set(this.hasPromptFileAttachments); for (const [index, attachment] of attachments) { - const resource = URI.isUri(attachment.value) ? attachment.value : attachment.value && typeof attachment.value === 'object' && 'uri' in attachment.value && URI.isUri(attachment.value.uri) ? attachment.value.uri : undefined; - const range = attachment.value && typeof attachment.value === 'object' && 'range' in attachment.value && Range.isIRange(attachment.value.range) ? attachment.value.range : undefined; + const resource = URI.isUri(attachment.value) ? attachment.value : isLocation(attachment.value) ? attachment.value.uri : undefined; + const range = isLocation(attachment.value) ? attachment.value.range : undefined; const shouldFocusClearButton = index === Math.min(this._indexOfLastAttachedContextDeletedWithKeyboard, this.attachmentModel.size - 1) && this._indexOfLastAttachedContextDeletedWithKeyboard > -1; let attachmentWidget; diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index 765f0018b0c..7ecf0160dce 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -53,7 +53,7 @@ import { IChatAgentMetadata } from '../common/chatAgents.js'; import { ChatContextKeys } from '../common/chatContextKeys.js'; import { IChatTextEditGroup } from '../common/chatModel.js'; import { chatSubcommandLeader } from '../common/chatParserTypes.js'; -import { ChatAgentVoteDirection, ChatAgentVoteDownReason, ChatErrorLevel, IChatChangesSummary, IChatConfirmation, IChatContentReference, IChatElicitationRequest, IChatExtensionsContent, IChatFollowup, IChatMarkdownContent, IChatMcpServersStarting, IChatMultiDiffData, IChatPullRequestContent, IChatTask, IChatTaskSerialized, IChatThinkingPart, IChatToolInvocation, IChatToolInvocationSerialized, IChatTreeData, IChatUndoStop } from '../common/chatService.js'; +import { ChatAgentVoteDirection, ChatAgentVoteDownReason, ChatErrorLevel, IChatChangesSummary, IChatConfirmation, IChatContentReference, IChatElicitationRequest, IChatExtensionsContent, IChatFollowup, IChatMarkdownContent, IChatMcpServersStarting, IChatMultiDiffData, IChatPullRequestContent, IChatTask, IChatTaskSerialized, IChatThinkingPart, IChatToolInvocation, IChatToolInvocationSerialized, IChatTreeData, IChatUndoStop, isChatFollowup } from '../common/chatService.js'; import { IChatRequestVariableEntry } from '../common/chatVariableEntries.js'; import { IChatChangesSummaryPart, IChatCodeCitations, IChatErrorDetailsPart, IChatReferences, IChatRendererContent, IChatRequestViewModel, IChatResponseViewModel, IChatViewModel, isRequestVM, isResponseVM } from '../common/chatViewModel.js'; import { getNWords } from '../common/chatWordCounter.js'; @@ -835,7 +835,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer { getHeight(element: ChatTreeItem): number { const kind = isRequestVM(element) ? 'request' : 'response'; - const height = ('currentRenderedHeight' in element ? element.currentRenderedHeight : undefined) ?? this.defaultElementHeight; + const height = element.currentRenderedHeight ?? this.defaultElementHeight; this._traceLayout('getHeight', `${kind}, height=${height}`); return height; } diff --git a/src/vs/workbench/contrib/chat/browser/chatManagement/chatManagement.contribution.ts b/src/vs/workbench/contrib/chat/browser/chatManagement/chatManagement.contribution.ts index 993c3dd1b73..5c56d963413 100644 --- a/src/vs/workbench/contrib/chat/browser/chatManagement/chatManagement.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chatManagement/chatManagement.contribution.ts @@ -119,7 +119,7 @@ registerAction2(class extends Action2 { async run(accessor: ServicesAccessor, args: string | IOpenManageCopilotEditorActionOptions) { const editorGroupsService = accessor.get(IEditorGroupsService); args = sanitizeOpenManageCopilotEditorArgs(args); - return editorGroupsService.activeGroup.openEditor(new ModelsManagementEditorInput()); + return editorGroupsService.activeGroup.openEditor(new ModelsManagementEditorInput(), { pinned: true }); } }); diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index c43cee531e5..d55fa80b899 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -84,7 +84,7 @@ import { PromptsType } from '../common/promptSyntax/promptTypes.js'; import { IHandOff, ParsedPromptFile, PromptHeader, Target } from '../common/promptSyntax/promptFileParser.js'; import { IPromptsService } from '../common/promptSyntax/service/promptsService.js'; import { handleModeSwitch } from './actions/chatActions.js'; -import { ChatTreeItem, ChatViewId, IChatAcceptInputOptions, IChatAccessibilityService, IChatCodeBlockInfo, IChatFileTreeInfo, IChatListItemRendererOptions, IChatWidget, IChatWidgetService, IChatWidgetViewContext, IChatWidgetViewOptions } from './chat.js'; +import { ChatTreeItem, ChatViewId, IChatAcceptInputOptions, IChatAccessibilityService, IChatCodeBlockInfo, IChatFileTreeInfo, IChatListItemRendererOptions, IChatWidget, IChatWidgetService, IChatWidgetViewContext, IChatWidgetViewOptions, isIChatResourceViewContext, isIChatViewViewContext } from './chat.js'; import { ChatAccessibilityProvider } from './chatAccessibilityProvider.js'; import { ChatAttachmentModel } from './chatAttachmentModel.js'; import { ChatSuggestNextWidget } from './chatContentParts/chatSuggestNextWidget.js'; @@ -140,11 +140,11 @@ export interface IChatWidgetLocationOptions { } export function isQuickChat(widget: IChatWidget): boolean { - return 'viewContext' in widget && 'isQuickChat' in widget.viewContext && Boolean(widget.viewContext.isQuickChat); + return isIChatResourceViewContext(widget.viewContext) && Boolean(widget.viewContext.isQuickChat); } export function isInlineChat(widget: IChatWidget): boolean { - return 'viewContext' in widget && 'isInlineChat' in widget.viewContext && Boolean(widget.viewContext.isInlineChat); + return isIChatResourceViewContext(widget.viewContext) && Boolean(widget.viewContext.isInlineChat); } interface IChatHistoryListItem { @@ -790,7 +790,7 @@ export class ChatWidget extends Disposable implements IChatWidget { } render(parent: HTMLElement): void { - const viewId = 'viewId' in this.viewContext ? this.viewContext.viewId : undefined; + const viewId = isIChatViewViewContext(this.viewContext) ? this.viewContext.viewId : undefined; this.editorOptions = this._register(this.instantiationService.createInstance(ChatEditorOptions, viewId, this.styles.listForeground, this.styles.inputEditorBackground, this.styles.resultEditorBackground)); const renderInputOnTop = this.viewOptions.renderInputOnTop ?? false; const renderFollowups = this.viewOptions.renderFollowups ?? !renderInputOnTop; @@ -2061,7 +2061,7 @@ export class ChatWidget extends Disposable implements IChatWidget { private getWidgetViewKindTag(): string { if (!this.viewContext) { return 'editor'; - } else if ('viewId' in this.viewContext) { + } else if (isIChatViewViewContext(this.viewContext)) { return 'view'; } else { return 'quick'; diff --git a/src/vs/workbench/contrib/chat/common/chatService.ts b/src/vs/workbench/contrib/chat/common/chatService.ts index a5d2c6bcc08..68677b268e8 100644 --- a/src/vs/workbench/contrib/chat/common/chatService.ts +++ b/src/vs/workbench/contrib/chat/common/chatService.ts @@ -672,6 +672,15 @@ export interface IChatFollowup { tooltip?: string; } +export function isChatFollowup(obj: unknown): obj is IChatFollowup { + return ( + !!obj && + (obj as IChatFollowup).kind === 'reply' && + typeof (obj as IChatFollowup).message === 'string' && + typeof (obj as IChatFollowup).agentId === 'string' + ); +} + export enum ChatAgentVoteDirection { Down = 0, Up = 1 diff --git a/src/vs/workbench/contrib/codeEditor/browser/workbenchEditorWorkerService.ts b/src/vs/workbench/contrib/codeEditor/browser/workbenchEditorWorkerService.ts index b74d233147b..1b7f70b39f2 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/workbenchEditorWorkerService.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/workbenchEditorWorkerService.ts @@ -20,7 +20,11 @@ export class WorkbenchEditorWorkerService extends EditorWorkerService { @ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService, @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService, ) { - const workerDescriptor = new WebWorkerDescriptor(FileAccess.asBrowserUri('vs/editor/common/services/editorWebWorkerMain.js'), 'TextEditorWorker'); + const workerDescriptor = new WebWorkerDescriptor({ + esmModuleLocation: FileAccess.asBrowserUri('vs/editor/common/services/editorWebWorkerMain.js'), + label: 'TextEditorWorker', + }); + super(workerDescriptor, modelService, configurationService, logService, languageConfigurationService, languageFeaturesService); } } diff --git a/src/vs/workbench/contrib/comments/browser/commentsController.ts b/src/vs/workbench/contrib/comments/browser/commentsController.ts index d3c673e4eb7..9de143e39b6 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsController.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsController.ts @@ -1084,7 +1084,7 @@ export class CommentController implements IEditorContribution { } private onEditorMouseDown(e: IEditorMouseEvent): void { - this.mouseDownInfo = this._activeEditorHasCommentingRange.get() ? parseMouseDownInfoFromEvent(e) : null; + this.mouseDownInfo = (e.target.element?.className.indexOf('comment-range-glyph') ?? -1) >= 0 ? parseMouseDownInfoFromEvent(e) : null; } private onEditorMouseUp(e: IEditorMouseEvent): void { diff --git a/src/vs/workbench/contrib/editSessions/common/editSessionsStorageClient.ts b/src/vs/workbench/contrib/editSessions/common/editSessionsStorageClient.ts index 35c1b74c29d..55748620d94 100644 --- a/src/vs/workbench/contrib/editSessions/common/editSessionsStorageClient.ts +++ b/src/vs/workbench/contrib/editSessions/common/editSessionsStorageClient.ts @@ -6,5 +6,5 @@ import { UserDataSyncStoreClient } from '../../../../platform/userDataSync/common/userDataSyncStoreService.js'; export class EditSessionsStoreClient extends UserDataSyncStoreClient { - _serviceBrand: any; + _serviceBrand: undefined; } diff --git a/src/vs/workbench/contrib/editSessions/common/workspaceStateSync.ts b/src/vs/workbench/contrib/editSessions/common/workspaceStateSync.ts index 46acc992b99..70caed204d6 100644 --- a/src/vs/workbench/contrib/editSessions/common/workspaceStateSync.ts +++ b/src/vs/workbench/contrib/editSessions/common/workspaceStateSync.ts @@ -36,7 +36,7 @@ class NullBackupStoreService implements IUserDataSyncLocalStoreService { } class NullEnablementService implements IUserDataSyncEnablementService { - _serviceBrand: any; + _serviceBrand: undefined; private _onDidChangeEnablement = new Emitter(); readonly onDidChangeEnablement: Event = this._onDidChangeEnablement.event; diff --git a/src/vs/workbench/contrib/files/browser/media/explorerviewlet.css b/src/vs/workbench/contrib/files/browser/media/explorerviewlet.css index a08c3754676..db5712fe9b0 100644 --- a/src/vs/workbench/contrib/files/browser/media/explorerviewlet.css +++ b/src/vs/workbench/contrib/files/browser/media/explorerviewlet.css @@ -9,10 +9,6 @@ height: 100%; } -.explorer-folders-view .monaco-list-row { - padding-left: 4px; /* align top level twistie with `Explorer` title label */ -} - .explorer-folders-view .explorer-folders-view.highlight .monaco-list .explorer-item:not(.explorer-item-edited), .explorer-folders-view .explorer-folders-view.highlight .monaco-list .monaco-tl-twistie { opacity: 0.3; diff --git a/src/vs/workbench/contrib/files/browser/views/media/openeditors.css b/src/vs/workbench/contrib/files/browser/views/media/openeditors.css index 344f9790e52..d933ff97043 100644 --- a/src/vs/workbench/contrib/files/browser/views/media/openeditors.css +++ b/src/vs/workbench/contrib/files/browser/views/media/openeditors.css @@ -63,7 +63,7 @@ } .open-editors .monaco-list .monaco-list-row { - padding-left: 22px; + padding-left: 8px; display: flex; } diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/debug/notebookBreakpoints.ts b/src/vs/workbench/contrib/notebook/browser/contrib/debug/notebookBreakpoints.ts index 29b503e2639..a049be3d2c5 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/debug/notebookBreakpoints.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/debug/notebookBreakpoints.ts @@ -16,6 +16,7 @@ import { CellUri, NotebookCellsChangeType } from '../../../common/notebookCommon import { INotebookService } from '../../../common/notebookService.js'; import { IEditorService } from '../../../../../services/editor/common/editorService.js'; import { LifecyclePhase } from '../../../../../services/lifecycle/common/lifecycle.js'; +import { hasKey } from '../../../../../../base/common/types.js'; class NotebookBreakpoints extends Disposable implements IWorkbenchContribution { constructor( @@ -58,7 +59,7 @@ class NotebookBreakpoints extends Disposable implements IWorkbenchContribution { })); this._register(this._debugService.getModel().onDidChangeBreakpoints(e => { - const newCellBp = e?.added?.find(bp => 'uri' in bp && bp.uri.scheme === Schemas.vscodeNotebookCell) as IBreakpoint | undefined; + const newCellBp = e?.added?.find(bp => hasKey(bp, { uri: true }) && bp.uri.scheme === Schemas.vscodeNotebookCell) as IBreakpoint | undefined; if (newCellBp) { const parsed = CellUri.parse(newCellBp.uri); if (!parsed) { diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts b/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts index 072ba66abf4..ae53643d6d7 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts @@ -18,6 +18,7 @@ import { CellEditState, CellFindMatchWithIndex, CellWebviewFindMatch, ICellViewM import { NotebookViewModel } from '../../viewModel/notebookViewModelImpl.js'; import { NotebookTextModel } from '../../../common/model/notebookTextModel.js'; import { CellKind, INotebookFindOptions, NotebookCellsChangeType } from '../../../common/notebookCommon.js'; +import { hasKey } from '../../../../../../base/common/types.js'; export class CellFindMatchModel implements CellFindMatchWithIndex { readonly cell: ICellViewModel; @@ -239,14 +240,14 @@ export class FindModel extends Disposable { // let currCell; if (!this._findMatchesStarts) { this.set(this._findMatches, true); - if ('index' in option) { + if (hasKey(option, { index: true })) { this._currentMatch = option.index; } } else { // const currIndex = this._findMatchesStarts!.getIndexOf(this._currentMatch); // currCell = this._findMatches[currIndex.index].cell; const totalVal = this._findMatchesStarts.getTotalSum(); - if ('index' in option) { + if (hasKey(option, { index: true })) { this._currentMatch = option.index; } else if (this._currentMatch === -1) { diff --git a/src/vs/workbench/contrib/notebook/browser/diff/diffElementViewModel.ts b/src/vs/workbench/contrib/notebook/browser/diff/diffElementViewModel.ts index cd153dbe702..f9e3ac054d0 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/diffElementViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/diffElementViewModel.ts @@ -745,7 +745,7 @@ export class SideBySideDiffElementViewModel extends DiffElementCellViewModelBase const modifiedMedataRaw = Object.assign({}, this.modified.metadata); const originalCellMetadata = this.original.metadata; for (const key of cellMetadataKeys) { - if (key in originalCellMetadata) { + if (Object.hasOwn(originalCellMetadata, key)) { modifiedMedataRaw[key] = originalCellMetadata[key]; } } diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookWorkerServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookWorkerServiceImpl.ts index 8086431811b..622692d670a 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookWorkerServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookWorkerServiceImpl.ts @@ -6,7 +6,7 @@ import { Disposable, DisposableStore, dispose, IDisposable, toDisposable } from '../../../../../base/common/lifecycle.js'; import { URI } from '../../../../../base/common/uri.js'; import { IWebWorkerClient, Proxied } from '../../../../../base/common/worker/webWorker.js'; -import { createWebWorker } from '../../../../../base/browser/webWorkerFactory.js'; +import { createWebWorker, WebWorkerDescriptor } from '../../../../../base/browser/webWorkerFactory.js'; import { NotebookCellTextModel } from '../../common/model/notebookCellTextModel.js'; import { CellUri, IMainCellDto, INotebookDiffResult, NotebookCellsChangeType, NotebookRawContentEventDto } from '../../common/notebookCommon.js'; import { INotebookService } from '../../common/notebookService.js'; @@ -274,8 +274,10 @@ class NotebookWorkerClient extends Disposable { if (!this._worker) { try { this._worker = this._register(createWebWorker( - FileAccess.asBrowserUri('vs/workbench/contrib/notebook/common/services/notebookWebWorkerMain.js'), - 'NotebookEditorWorker' + new WebWorkerDescriptor({ + esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/contrib/notebook/common/services/notebookWebWorkerMain.js'), + label: 'NotebookEditorWorker' + }) )); } catch (err) { throw (err); diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution.ts index 6b4ba9c20bd..b8e9d472870 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution.ts @@ -16,6 +16,7 @@ import { INotebookExecutionStateService } from '../../../common/notebookExecutio import { executingStateIcon } from '../../notebookIcons.js'; import { renderLabelWithIcons } from '../../../../../../base/browser/ui/iconLabel/iconLabels.js'; import { CellViewModelStateChangeEvent } from '../../notebookViewEvents.js'; +import { hasKey } from '../../../../../../base/common/types.js'; const UPDATE_EXECUTION_ORDER_GRACE_PERIOD = 200; @@ -38,7 +39,7 @@ export class CellExecutionPart extends CellContentPart { // Add a method to watch for cell execution state changes this._register(this._notebookExecutionStateService.onDidChangeExecution(e => { - if (this.currentCell && 'affectsCell' in e && e.affectsCell(this.currentCell.uri)) { + if (this.currentCell && hasKey(e, { affectsCell: true }) && e.affectsCell(this.currentCell.uri)) { this._updatePosition(); } })); diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts index ceb9a5bee0e..98bc59a29b2 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts @@ -10,7 +10,7 @@ import { Disposable, dispose, IDisposable } from '../../../../../base/common/lif import { Schemas } from '../../../../../base/common/network.js'; import { filter } from '../../../../../base/common/objects.js'; import { isEqual } from '../../../../../base/common/resources.js'; -import { isDefined } from '../../../../../base/common/types.js'; +import { hasKey, isDefined } from '../../../../../base/common/types.js'; import { URI } from '../../../../../base/common/uri.js'; import { Position } from '../../../../../editor/common/core/position.js'; import { Range } from '../../../../../editor/common/core/range.js'; @@ -436,11 +436,11 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel } private _getCellIndexWithOutputIdHandleFromEdits(outputId: string, rawEdits: ICellEditOperation[]) { - const edit = rawEdits.find(e => 'outputs' in e && e.outputs.some(o => o.outputId === outputId)); + const edit = rawEdits.find(e => hasKey(e, { outputs: true }) && e.outputs.some(o => o.outputId === outputId)); if (edit) { - if ('index' in edit) { + if (hasKey(edit, { index: true })) { return edit.index; - } else if ('handle' in edit) { + } else if (hasKey(edit, { handle: true })) { const cellIndex = this._getCellIndexByHandle(edit.handle); this._assertIndex(cellIndex); return cellIndex; @@ -621,10 +621,10 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel return false; } - if (('index' in edit) && !this.newCellsFromLastEdit.has(this.cells[edit.index].handle)) { + if (hasKey(edit, { index: true }) && !this.newCellsFromLastEdit.has(this.cells[edit.index].handle)) { return false; } - if ('handle' in edit && !this.newCellsFromLastEdit.has(edit.handle)) { + if (hasKey(edit, { handle: true }) && !this.newCellsFromLastEdit.has(edit.handle)) { return false; } } @@ -675,12 +675,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel private _doApplyEdits(rawEdits: ICellEditOperation[], synchronous: boolean, computeUndoRedo: boolean, beginSelectionState: ISelectionState | undefined, undoRedoGroup: UndoRedoGroup | undefined): void { const editsWithDetails = rawEdits.map((edit, index) => { let cellIndex: number = -1; - if ('index' in edit) { + if (hasKey(edit, { index: true })) { cellIndex = edit.index; - } else if ('handle' in edit) { + } else if (hasKey(edit, { handle: true })) { cellIndex = this._getCellIndexByHandle(edit.handle); this._assertIndex(cellIndex); - } else if ('outputId' in edit) { + } else if (hasKey(edit, { outputId: true })) { cellIndex = this._getCellIndexWithOutputIdHandle(edit.outputId); if (this._indexIsInvalid(cellIndex)) { // The referenced output may have been created in this batch of edits diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts index 53ad06b5e3c..5ce068885bb 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts @@ -10,7 +10,7 @@ import { Emitter, Event } from '../../../../base/common/event.js'; import { IMarkdownString } from '../../../../base/common/htmlContent.js'; import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js'; import { Schemas } from '../../../../base/common/network.js'; -import { assertType } from '../../../../base/common/types.js'; +import { assertType, hasKey } from '../../../../base/common/types.js'; import { URI } from '../../../../base/common/uri.js'; import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js'; import { IWriteFileOptions, IFileStatWithMetadata, FileOperationError, FileOperationResult } from '../../../../platform/files/common/files.js'; @@ -111,7 +111,7 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE } get hasErrorState(): boolean { - if (this._workingCopy && 'hasState' in this._workingCopy) { + if (this._workingCopy && hasKey(this._workingCopy, { hasState: true })) { return this._workingCopy.hasState(StoredFileWorkingCopyState.ERROR); } diff --git a/src/vs/workbench/contrib/output/browser/outputLinkProvider.ts b/src/vs/workbench/contrib/output/browser/outputLinkProvider.ts index 9fe87b7af5e..6a291ecb3ff 100644 --- a/src/vs/workbench/contrib/output/browser/outputLinkProvider.ts +++ b/src/vs/workbench/contrib/output/browser/outputLinkProvider.ts @@ -12,7 +12,7 @@ import { OUTPUT_MODE_ID, LOG_MODE_ID } from '../../../services/output/common/out import { OutputLinkComputer } from '../common/outputLinkComputer.js'; import { IDisposable, dispose, Disposable } from '../../../../base/common/lifecycle.js'; import { ILanguageFeaturesService } from '../../../../editor/common/services/languageFeatures.js'; -import { createWebWorker } from '../../../../base/browser/webWorkerFactory.js'; +import { createWebWorker, WebWorkerDescriptor } from '../../../../base/browser/webWorkerFactory.js'; import { IWebWorkerClient } from '../../../../base/common/worker/webWorker.js'; import { WorkerTextModelSyncClient } from '../../../../editor/common/services/textModelSync/textModelSync.impl.js'; import { FileAccess } from '../../../../base/common/network.js'; @@ -99,8 +99,10 @@ class OutputLinkWorkerClient extends Disposable { ) { super(); this._workerClient = this._register(createWebWorker( - FileAccess.asBrowserUri('vs/workbench/contrib/output/common/outputLinkComputerMain.js'), - 'OutputLinkDetectionWorker' + new WebWorkerDescriptor({ + esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/contrib/output/common/outputLinkComputerMain.js'), + label: 'OutputLinkDetectionWorker' + }) )); this._workerTextModelSyncClient = this._register(WorkerTextModelSyncClient.create(this._workerClient, modelService)); this._initializeBarrier = this._ensureWorkspaceFolders(); diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 086580f3db6..8bda78a5b4b 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -360,7 +360,8 @@ export class SettingsEditor2 extends EditorPane { * Returns true if: * - The setting is not tagged as advanced, OR * - The setting matches an ID filter (@id:settingKey), OR - * - The setting key appears in the search query + * - The setting key appears in the search query, OR + * - The @hasPolicy filter is active (policy settings should always be shown when filtering by policy) */ private shouldShowSetting(setting: ISetting): boolean { if (!setting.tags?.includes(ADVANCED_SETTING_TAG)) { @@ -372,6 +373,9 @@ export class SettingsEditor2 extends EditorPane { if (this.viewState.query?.toLowerCase().includes(setting.key.toLowerCase())) { return true; } + if (this.viewState.tagFilters?.has(POLICY_SETTING_TAG)) { + return true; + } return false; } diff --git a/src/vs/workbench/contrib/scm/browser/scmRepositoryRenderer.ts b/src/vs/workbench/contrib/scm/browser/scmRepositoryRenderer.ts index 2eb4daa3b53..13422b2f5c1 100644 --- a/src/vs/workbench/contrib/scm/browser/scmRepositoryRenderer.ts +++ b/src/vs/workbench/contrib/scm/browser/scmRepositoryRenderer.ts @@ -100,7 +100,7 @@ export class RepositoryRenderer implements ICompressibleTreeRenderer provider.classList.toggle('active', e)); diff --git a/src/vs/workbench/contrib/testing/browser/codeCoverageDecorations.ts b/src/vs/workbench/contrib/testing/browser/codeCoverageDecorations.ts index 422c4978530..63fa40bc3cc 100644 --- a/src/vs/workbench/contrib/testing/browser/codeCoverageDecorations.ts +++ b/src/vs/workbench/contrib/testing/browser/codeCoverageDecorations.ts @@ -672,7 +672,7 @@ class CoverageToolbarWidget extends Disposable implements IOverlayWidget { public getPosition(): IOverlayWidgetPosition | null { return { preference: OverlayWidgetPositionPreference.TOP_CENTER, - stackOridinal: 9, + stackOrdinal: 9, }; } diff --git a/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts b/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts index e2bf7c6fd05..7eb05f139d6 100644 --- a/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts +++ b/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts @@ -219,7 +219,7 @@ export class RunUsingProfileAction extends Action2 { }); } - public override async run(acessor: ServicesAccessor, ...elements: TestItemTreeElement[]): Promise { + public override async run(acessor: ServicesAccessor, ...elements: TestItemTreeElement[]): Promise { const commandService = acessor.get(ICommandService); const testService = acessor.get(ITestService); const profile: ITestRunProfile | undefined = await commandService.executeCommand('vscode.pickTestProfile', { @@ -295,7 +295,7 @@ export class ContinuousRunTestAction extends Action2 { }); } - public override async run(accessor: ServicesAccessor, ...elements: TestItemTreeElement[]): Promise { + public override async run(accessor: ServicesAccessor, ...elements: TestItemTreeElement[]): Promise { const crService = accessor.get(ITestingContinuousRunService); for (const element of elements) { const id = element.test.item.extId; @@ -329,7 +329,7 @@ export class ContinuousRunUsingProfileTestAction extends Action2 { }); } - public override async run(accessor: ServicesAccessor, ...elements: TestItemTreeElement[]): Promise { + public override async run(accessor: ServicesAccessor, ...elements: TestItemTreeElement[]): Promise { const crService = accessor.get(ITestingContinuousRunService); const profileService = accessor.get(ITestProfileService); const notificationService = accessor.get(INotificationService); diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts index ac41fe2000c..6b371cab5c7 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts @@ -1364,7 +1364,7 @@ class TestExplorerActionRunner extends ActionRunner { super(); } - protected override async runAction(action: IAction, context: TestExplorerTreeElement): Promise { + protected override async runAction(action: IAction, context: TestExplorerTreeElement): Promise { if (!(action instanceof MenuItemAction)) { return super.runAction(action, context); } diff --git a/src/vs/workbench/contrib/update/browser/update.ts b/src/vs/workbench/contrib/update/browser/update.ts index a20d7aea012..cc12ca62fbb 100644 --- a/src/vs/workbench/contrib/update/browser/update.ts +++ b/src/vs/workbench/contrib/update/browser/update.ts @@ -587,7 +587,7 @@ export class SwitchProductQualityContribution extends Disposable implements IWor }); if (res.confirmed) { - const promises: Promise[] = []; + const promises: Promise[] = []; // If sync is happening wait until it is finished before reload if (userDataSyncService.status === SyncStatus.Syncing) { diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts index dc9f6e90a81..5f8afce3071 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts @@ -787,7 +787,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo }] }); } - async run(): Promise { + async run(): Promise { return that.turnOn(); } })); @@ -813,7 +813,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo }] }); } - async run(): Promise { } + async run(): Promise { } })); } @@ -833,7 +833,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo } }); } - async run(): Promise { + async run(): Promise { return that.userDataSyncWorkbenchService.turnoff(false); } })); @@ -856,7 +856,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo } }); } - async run(): Promise { + async run(): Promise { try { await that.userDataSyncWorkbenchService.signIn(); } catch (e) { @@ -903,7 +903,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo }] }); } - async run(): Promise { + async run(): Promise { return that.userDataSyncWorkbenchService.showConflicts(); } }); @@ -1013,7 +1013,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo } }); } - run(accessor: ServicesAccessor): Promise { + run(accessor: ServicesAccessor): Promise { return that.userDataSyncWorkbenchService.syncNow(); } })); @@ -1033,7 +1033,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo }, }); } - async run(): Promise { + async run(): Promise { try { await that.turnOff(); } catch (e) { diff --git a/src/vs/workbench/contrib/welcomeViews/common/newFile.contribution.ts b/src/vs/workbench/contrib/welcomeViews/common/newFile.contribution.ts index b443285e3c2..a92f90bc9b0 100644 --- a/src/vs/workbench/contrib/welcomeViews/common/newFile.contribution.ts +++ b/src/vs/workbench/contrib/welcomeViews/common/newFile.contribution.ts @@ -47,7 +47,7 @@ registerAction2(class extends Action2 { } }); -type NewFileItem = { commandID: string; title: string; from: string; group: string; commandArgs?: any }; +type NewFileItem = { commandID: string; title: string; from: string; group: string; commandArgs?: unknown }; class NewFileTemplatesManager extends Disposable { static Instance: NewFileTemplatesManager | undefined; diff --git a/src/vs/workbench/services/accounts/common/defaultAccount.ts b/src/vs/workbench/services/accounts/common/defaultAccount.ts index feb482006f6..35e26fcda1f 100644 --- a/src/vs/workbench/services/accounts/common/defaultAccount.ts +++ b/src/vs/workbench/services/accounts/common/defaultAccount.ts @@ -7,7 +7,7 @@ import { createDecorator } from '../../../../platform/instantiation/common/insta import { Emitter, Event } from '../../../../base/common/event.js'; import { Disposable } from '../../../../base/common/lifecycle.js'; import { IProductService } from '../../../../platform/product/common/productService.js'; -import { IAuthenticationService } from '../../authentication/common/authentication.js'; +import { AuthenticationSession, IAuthenticationService } from '../../authentication/common/authentication.js'; import { asJson, IRequestService } from '../../../../platform/request/common/request.js'; import { CancellationToken } from '../../../../base/common/cancellation.js'; import { IExtensionService } from '../../extensions/common/extensions.js'; @@ -441,7 +441,7 @@ export class DefaultAccountManagementContribution extends Disposable implements title: localize('sign in', "Sign in"), }); } - run(): Promise { + run(): Promise { return that.authenticationService.createSession(authProviderId, scopes); } })); diff --git a/src/vs/workbench/services/assignment/common/assignmentFilters.ts b/src/vs/workbench/services/assignment/common/assignmentFilters.ts index 57535dbd67d..3ee5904b34b 100644 --- a/src/vs/workbench/services/assignment/common/assignmentFilters.ts +++ b/src/vs/workbench/services/assignment/common/assignmentFilters.ts @@ -175,8 +175,8 @@ export class CopilotAssignmentFilterProvider extends Disposable implements IExpe } } - getFilters(): Map { - const filters: Map = new Map(); + getFilters(): Map { + const filters = new Map(); const filterValues = Object.values(ExtensionsFilter); for (const value of filterValues) { filters.set(value, this.getFilterValue(value)); diff --git a/src/vs/workbench/services/configuration/common/jsonEditingService.ts b/src/vs/workbench/services/configuration/common/jsonEditingService.ts index 13872df9537..d9d71001707 100644 --- a/src/vs/workbench/services/configuration/common/jsonEditingService.ts +++ b/src/vs/workbench/services/configuration/common/jsonEditingService.ts @@ -49,7 +49,7 @@ export class JSONEditingService implements IJSONEditingService { } } - private async writeToBuffer(model: ITextModel, values: IJSONValue[]): Promise { + private async writeToBuffer(model: ITextModel, values: IJSONValue[]): Promise { let disposable: IDisposable | undefined; try { // Optimization: we apply edits to a text model and save it @@ -69,6 +69,8 @@ export class JSONEditingService implements IJSONEditingService { } finally { disposable?.dispose(); } + + return undefined; } private applyEditsToBuffer(edit: Edit, model: ITextModel): boolean { diff --git a/src/vs/workbench/services/configuration/test/common/testServices.ts b/src/vs/workbench/services/configuration/test/common/testServices.ts index 61ba62b5134..6a842e2a4cb 100644 --- a/src/vs/workbench/services/configuration/test/common/testServices.ts +++ b/src/vs/workbench/services/configuration/test/common/testServices.ts @@ -7,7 +7,7 @@ import { URI } from '../../../../../base/common/uri.js'; import { IJSONEditingService, IJSONValue } from '../../common/jsonEditing.js'; export class TestJSONEditingService implements IJSONEditingService { - _serviceBrand: any; + _serviceBrand: undefined; async write(resource: URI, values: IJSONValue[], save: boolean): Promise { } } diff --git a/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts index 4952f8f2128..9277723a595 100644 --- a/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts @@ -143,7 +143,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR this.resolvableVariables.add('input'); } - override async resolveWithInteractionReplace(folder: IWorkspaceFolderData | undefined, config: unknown, section?: string, variables?: IStringDictionary, target?: ConfigurationTarget): Promise { + override async resolveWithInteractionReplace(folder: IWorkspaceFolderData | undefined, config: unknown, section?: string, variables?: IStringDictionary, target?: ConfigurationTarget): Promise { const parsed = ConfigurationResolverExpression.parse(config); await this.resolveWithInteraction(folder, parsed, section, variables, target); @@ -225,7 +225,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR } - inputs ??= this.configurationService.getValue(section, overrides)?.inputs; + inputs ??= this.configurationService.getValue<{ inputs?: ConfiguredInput[] }>(section, overrides)?.inputs; return inputs; } diff --git a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts index 0daf72b7086..610809eacd0 100644 --- a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts @@ -93,11 +93,11 @@ export abstract class AbstractVariableResolverService implements IConfigurationR return expr.toObject() as (T extends ConfigurationResolverExpression ? R : T); } - public resolveWithInteractionReplace(folder: IWorkspaceFolderData | undefined, config: any): Promise { + public resolveWithInteractionReplace(folder: IWorkspaceFolderData | undefined, config: unknown): Promise { throw new Error('resolveWithInteractionReplace not implemented.'); } - public resolveWithInteraction(folder: IWorkspaceFolderData | undefined, config: any): Promise | undefined> { + public resolveWithInteraction(folder: IWorkspaceFolderData | undefined, config: unknown): Promise | undefined> { throw new Error('resolveWithInteraction not implemented.'); } diff --git a/src/vs/workbench/services/extensionManagement/electron-browser/extensionGalleryManifestService.ts b/src/vs/workbench/services/extensionManagement/electron-browser/extensionGalleryManifestService.ts index ade3bd512f5..aebeabba799 100644 --- a/src/vs/workbench/services/extensionManagement/electron-browser/extensionGalleryManifestService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-browser/extensionGalleryManifestService.ts @@ -43,7 +43,7 @@ export class WorkbenchExtensionGalleryManifestService extends ExtensionGalleryMa @IProductService productService: IProductService, @IEnvironmentService environmentService: IEnvironmentService, @IFileService fileService: IFileService, - @ITelemetryService telemetryService: ITelemetryService, + @ITelemetryService private readonly telemetryService: ITelemetryService, @IStorageService storageService: IStorageService, @IRemoteAgentService remoteAgentService: IRemoteAgentService, @ISharedProcessService sharedProcessService: ISharedProcessService, @@ -119,6 +119,12 @@ export class WorkbenchExtensionGalleryManifestService extends ExtensionGalleryMa try { const manifest = await this.getExtensionGalleryManifestFromServiceUrl(configuredServiceUrl); this.update(manifest); + this.telemetryService.publicLog2< + {}, + { + owner: 'sandy081'; + comment: 'Reports when a user successfully accesses a custom marketplace'; + }>('galleryservice:custom:marketplace'); } catch (error) { this.logService.error('[Marketplace] Error retrieving enterprise gallery manifest', error); this.update(null, ExtensionGalleryManifestStatus.AccessDenied); diff --git a/src/vs/workbench/services/extensions/common/extHostCustomers.ts b/src/vs/workbench/services/extensions/common/extHostCustomers.ts index a61dbcff6e6..763dbdc6ec1 100644 --- a/src/vs/workbench/services/extensions/common/extHostCustomers.ts +++ b/src/vs/workbench/services/extensions/common/extHostCustomers.ts @@ -18,7 +18,7 @@ export interface IExtHostContext extends IRPCProtocol { export interface IInternalExtHostContext extends IExtHostContext { readonly internalExtensionService: IInternalExtensionService; _setExtensionHostProxy(extensionHostProxy: IExtensionHostProxy): void; - _setAllMainProxyIdentifiers(mainProxyIdentifiers: ProxyIdentifier[]): void; + _setAllMainProxyIdentifiers(mainProxyIdentifiers: ProxyIdentifier[]): void; } export type IExtHostNamedCustomer = [ProxyIdentifier, IExtHostCustomerCtor]; @@ -50,8 +50,8 @@ class ExtHostCustomersRegistryImpl { public static readonly INSTANCE = new ExtHostCustomersRegistryImpl(); - private _namedCustomers: IExtHostNamedCustomer[]; - private _customers: IExtHostCustomerCtor[]; + private _namedCustomers: IExtHostNamedCustomer[]; + private _customers: IExtHostCustomerCtor[]; constructor() { this._namedCustomers = []; @@ -62,14 +62,14 @@ class ExtHostCustomersRegistryImpl { const entry: IExtHostNamedCustomer = [id, ctor]; this._namedCustomers.push(entry); } - public getNamedCustomers(): IExtHostNamedCustomer[] { + public getNamedCustomers(): IExtHostNamedCustomer[] { return this._namedCustomers; } public registerCustomer(ctor: IExtHostCustomerCtor): void { this._customers.push(ctor); } - public getCustomers(): IExtHostCustomerCtor[] { + public getCustomers(): IExtHostCustomerCtor[] { return this._customers; } } diff --git a/src/vs/workbench/services/extensions/common/extensionHostProtocol.ts b/src/vs/workbench/services/extensions/common/extensionHostProtocol.ts index e7e9645ba98..f23c5a48592 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostProtocol.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostProtocol.ts @@ -83,9 +83,9 @@ export interface IStaticWorkspaceData { } export interface MessagePortLike { - postMessage(message: any, transfer?: any[]): void; - addEventListener(type: 'message', listener: (e: any) => unknown): void; - removeEventListener(type: 'message', listener: (e: any) => unknown): void; + postMessage(message: unknown, transfer?: Transferable[]): void; + addEventListener(type: 'message', listener: (e: MessageEvent) => unknown): void; + removeEventListener(type: 'message', listener: (e: MessageEvent) => unknown): void; start(): void; } diff --git a/src/vs/workbench/services/extensions/common/extensionHostProxy.ts b/src/vs/workbench/services/extensions/common/extensionHostProxy.ts index fc549732650..3d4cda24de6 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostProxy.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostProxy.ts @@ -15,7 +15,7 @@ export interface IResolveAuthorityErrorResult { error: { message: string | undefined; code: RemoteAuthorityResolverErrorCode; - detail: any; + detail: unknown; }; } diff --git a/src/vs/workbench/services/extensions/common/proxyIdentifier.ts b/src/vs/workbench/services/extensions/common/proxyIdentifier.ts index fa4d9772b2a..06eb2aa7747 100644 --- a/src/vs/workbench/services/extensions/common/proxyIdentifier.ts +++ b/src/vs/workbench/services/extensions/common/proxyIdentifier.ts @@ -20,7 +20,7 @@ export interface IRPCProtocol { /** * Assert these identifiers are already registered via `.set`. */ - assertRegistered(identifiers: ProxyIdentifier[]): void; + assertRegistered(identifiers: ProxyIdentifier[]): void; /** * Wait for the write buffer (if applicable) to become empty. @@ -43,7 +43,7 @@ export class ProxyIdentifier { } } -const identifiers: ProxyIdentifier[] = []; +const identifiers: ProxyIdentifier[] = []; export function createProxyIdentifier(identifier: string): ProxyIdentifier { const result = new ProxyIdentifier(identifier); diff --git a/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts b/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts index 3a5903733d8..34e70d6f7ea 100644 --- a/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts +++ b/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts @@ -23,7 +23,7 @@ export class CachedExtensionScanner { public readonly scannedExtensions: Promise; private _scannedExtensionsResolve!: (result: IExtensionDescription[]) => void; - private _scannedExtensionsReject!: (err: any) => void; + private _scannedExtensionsReject!: (err: unknown) => void; constructor( @INotificationService private readonly _notificationService: INotificationService, diff --git a/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts index d949dcf5648..62b774f0d2b 100644 --- a/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts @@ -59,7 +59,7 @@ export class ExtensionHostProcess { return this._extensionHostStarter.onDynamicStderr(this._id); } - public get onMessage(): Event { + public get onMessage(): Event { return this._extensionHostStarter.onDynamicMessage(this._id); } diff --git a/src/vs/workbench/services/host/browser/browserHostService.ts b/src/vs/workbench/services/host/browser/browserHostService.ts index 02e6d4591aa..974646d0f95 100644 --- a/src/vs/workbench/services/host/browser/browserHostService.ts +++ b/src/vs/workbench/services/host/browser/browserHostService.ts @@ -9,13 +9,13 @@ import { InstantiationType, registerSingleton } from '../../../../platform/insta import { ILayoutService } from '../../../../platform/layout/browser/layoutService.js'; import { IEditorService } from '../../editor/common/editorService.js'; import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js'; -import { IWindowSettings, IWindowOpenable, IOpenWindowOptions, isFolderToOpen, isWorkspaceToOpen, isFileToOpen, IOpenEmptyWindowOptions, IPathData, IFileToOpen } from '../../../../platform/window/common/window.js'; +import { IWindowSettings, IWindowOpenable, IOpenWindowOptions, isFolderToOpen, isWorkspaceToOpen, isFileToOpen, IOpenEmptyWindowOptions, IPathData, IFileToOpen, IOpenedMainWindow, IOpenedAuxiliaryWindow } from '../../../../platform/window/common/window.js'; import { isResourceEditorInput, pathsToEditors } from '../../../common/editor.js'; import { whenEditorClosed } from '../../../browser/editor.js'; import { IWorkspace, IWorkspaceProvider } from '../../../browser/web.api.js'; import { IFileService } from '../../../../platform/files/common/files.js'; import { ILabelService, Verbosity } from '../../../../platform/label/common/label.js'; -import { EventType, ModifierKeyEmitter, addDisposableListener, addDisposableThrottledListener, detectFullscreen, disposableWindowInterval, getActiveDocument, getWindowId, onDidRegisterWindow, trackFocus } from '../../../../base/browser/dom.js'; +import { EventType, ModifierKeyEmitter, addDisposableListener, addDisposableThrottledListener, detectFullscreen, disposableWindowInterval, getActiveDocument, getActiveWindow, getWindowId, onDidRegisterWindow, trackFocus, getWindows as getDOMWindows } from '../../../../base/browser/dom.js'; import { Disposable, DisposableStore, toDisposable } from '../../../../base/common/lifecycle.js'; import { IBrowserWorkbenchEnvironmentService } from '../../environment/browser/environmentService.js'; import { memoize } from '../../../../base/common/decorators.js'; @@ -32,7 +32,7 @@ import Severity from '../../../../base/common/severity.js'; import { IDialogService } from '../../../../platform/dialogs/common/dialogs.js'; import { DomEmitter } from '../../../../base/browser/event.js'; import { isUndefined } from '../../../../base/common/types.js'; -import { isTemporaryWorkspace, IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js'; +import { isTemporaryWorkspace, IWorkspaceContextService, toWorkspaceIdentifier } from '../../../../platform/workspace/common/workspace.js'; import { ServicesAccessor } from '../../../../editor/browser/editorExtensions.js'; import { Schemas } from '../../../../base/common/network.js'; import { ITextEditorOptions } from '../../../../platform/editor/common/editor.js'; @@ -572,6 +572,37 @@ export class BrowserHostService extends Disposable implements IHostService { return undefined; } + getWindows(options: { includeAuxiliaryWindows: true }): Promise>; + getWindows(options: { includeAuxiliaryWindows: false }): Promise>; + async getWindows(options: { includeAuxiliaryWindows: boolean }): Promise> { + const activeWindow = getActiveWindow(); + const activeWindowId = getWindowId(activeWindow); + + // Main window + const result: Array = [{ + id: activeWindowId, + title: activeWindow.document.title, + workspace: toWorkspaceIdentifier(this.contextService.getWorkspace()), + dirty: false + }]; + + // Auxiliary windows + if (options.includeAuxiliaryWindows) { + for (const { window } of getDOMWindows()) { + const windowId = getWindowId(window); + if (windowId !== activeWindowId && isAuxiliaryWindow(window)) { + result.push({ + id: windowId, + title: window.document.title, + parentId: activeWindowId + }); + } + } + } + + return result; + } + //#endregion //#region Lifecycle diff --git a/src/vs/workbench/services/host/browser/host.ts b/src/vs/workbench/services/host/browser/host.ts index f83c4b79e84..4ac35c9240c 100644 --- a/src/vs/workbench/services/host/browser/host.ts +++ b/src/vs/workbench/services/host/browser/host.ts @@ -7,7 +7,7 @@ import { VSBuffer } from '../../../../base/common/buffer.js'; import { Event } from '../../../../base/common/event.js'; import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; import { FocusMode } from '../../../../platform/native/common/native.js'; -import { IWindowOpenable, IOpenWindowOptions, IOpenEmptyWindowOptions, IPoint, IRectangle } from '../../../../platform/window/common/window.js'; +import { IWindowOpenable, IOpenWindowOptions, IOpenEmptyWindowOptions, IPoint, IRectangle, IOpenedMainWindow, IOpenedAuxiliaryWindow } from '../../../../platform/window/common/window.js'; export const IHostService = createDecorator('hostService'); @@ -93,6 +93,12 @@ export interface IHostService { */ getCursorScreenPoint(): Promise<{ readonly point: IPoint; readonly display: IRectangle } | undefined>; + /** + * Get the list of opened windows, optionally including auxiliary windows. + */ + getWindows(options: { includeAuxiliaryWindows: true }): Promise>; + getWindows(options: { includeAuxiliaryWindows: false }): Promise>; + //#endregion //#region Lifecycle diff --git a/src/vs/workbench/services/host/electron-browser/nativeHostService.ts b/src/vs/workbench/services/host/electron-browser/nativeHostService.ts index e0e7d669aa2..9ca38b24286 100644 --- a/src/vs/workbench/services/host/electron-browser/nativeHostService.ts +++ b/src/vs/workbench/services/host/electron-browser/nativeHostService.ts @@ -9,7 +9,7 @@ import { FocusMode, INativeHostService } from '../../../../platform/native/commo import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; import { ILabelService, Verbosity } from '../../../../platform/label/common/label.js'; import { IWorkbenchEnvironmentService } from '../../environment/common/environmentService.js'; -import { IWindowOpenable, IOpenWindowOptions, isFolderToOpen, isWorkspaceToOpen, IOpenEmptyWindowOptions, IPoint, IRectangle } from '../../../../platform/window/common/window.js'; +import { IWindowOpenable, IOpenWindowOptions, isFolderToOpen, isWorkspaceToOpen, IOpenEmptyWindowOptions, IPoint, IRectangle, IOpenedAuxiliaryWindow, IOpenedMainWindow } from '../../../../platform/window/common/window.js'; import { Disposable } from '../../../../base/common/lifecycle.js'; import { NativeHostService } from '../../../../platform/native/common/nativeHostService.js'; import { INativeWorkbenchEnvironmentService } from '../../environment/electron-browser/environmentService.js'; @@ -162,6 +162,16 @@ class WorkbenchHostService extends Disposable implements IHostService { return this.nativeHostService.getCursorScreenPoint(); } + getWindows(options: { includeAuxiliaryWindows: true }): Promise>; + getWindows(options: { includeAuxiliaryWindows: false }): Promise>; + getWindows(options: { includeAuxiliaryWindows: boolean }): Promise> { + if (options.includeAuxiliaryWindows === false) { + return this.nativeHostService.getWindows({ includeAuxiliaryWindows: false }); + } + + return this.nativeHostService.getWindows({ includeAuxiliaryWindows: true }); + } + //#endregion //#region Lifecycle diff --git a/src/vs/workbench/services/keybinding/common/keybindingIO.ts b/src/vs/workbench/services/keybinding/common/keybindingIO.ts index 91726a3e752..df8e1b3c9b8 100644 --- a/src/vs/workbench/services/keybinding/common/keybindingIO.ts +++ b/src/vs/workbench/services/keybinding/common/keybindingIO.ts @@ -11,7 +11,7 @@ import { ResolvedKeybindingItem } from '../../../../platform/keybinding/common/r export interface IUserKeybindingItem { keybinding: Keybinding | null; command: string | null; - commandArgs?: any; + commandArgs?: unknown; when: ContextKeyExpression | undefined; _sourceKey: string | undefined; /** captures `key` field from `keybindings.json`; `this.keybinding !== null` implies `_sourceKey !== null` */ } diff --git a/src/vs/workbench/services/keybinding/test/browser/keybindingIO.test.ts b/src/vs/workbench/services/keybinding/test/browser/keybindingIO.test.ts index 77e0d26860f..e3bceda70b0 100644 --- a/src/vs/workbench/services/keybinding/test/browser/keybindingIO.test.ts +++ b/src/vs/workbench/services/keybinding/test/browser/keybindingIO.test.ts @@ -156,6 +156,6 @@ suite('keybindingIO', () => { const strJSON = `[{ "key": "ctrl+k ctrl+f", "command": "firstcommand", "when": [], "args": { "text": "theText" } }]`; const userKeybinding = JSON.parse(strJSON)[0]; const keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding); - assert.strictEqual(keybindingItem.commandArgs.text, 'theText'); + assert.strictEqual((keybindingItem.commandArgs as unknown as { text: string }).text, 'theText'); }); }); diff --git a/src/vs/workbench/services/languageDetection/browser/languageDetectionWorker.protocol.ts b/src/vs/workbench/services/languageDetection/browser/languageDetectionWorker.protocol.ts index bf255e19c08..a7a46c3506e 100644 --- a/src/vs/workbench/services/languageDetection/browser/languageDetectionWorker.protocol.ts +++ b/src/vs/workbench/services/languageDetection/browser/languageDetectionWorker.protocol.ts @@ -10,7 +10,7 @@ export abstract class LanguageDetectionWorkerHost { public static getChannel(workerServer: IWebWorkerServer): LanguageDetectionWorkerHost { return workerServer.getChannel(LanguageDetectionWorkerHost.CHANNEL_NAME); } - public static setChannel(workerClient: IWebWorkerClient, obj: LanguageDetectionWorkerHost): void { + public static setChannel(workerClient: IWebWorkerClient, obj: LanguageDetectionWorkerHost): void { workerClient.setChannel(LanguageDetectionWorkerHost.CHANNEL_NAME, obj); } diff --git a/src/vs/workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl.ts b/src/vs/workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl.ts index 5a2459918f4..9fc668b5cb0 100644 --- a/src/vs/workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl.ts +++ b/src/vs/workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl.ts @@ -22,7 +22,7 @@ import { IStorageService, StorageScope, StorageTarget } from '../../../../platfo import { LRUCache } from '../../../../base/common/map.js'; import { ILogService } from '../../../../platform/log/common/log.js'; import { canASAR } from '../../../../amdX.js'; -import { createWebWorker } from '../../../../base/browser/webWorkerFactory.js'; +import { createWebWorker, WebWorkerDescriptor } from '../../../../base/browser/webWorkerFactory.js'; import { WorkerTextModelSyncClient } from '../../../../editor/common/services/textModelSync/textModelSync.impl.js'; import { ILanguageDetectionWorker, LanguageDetectionWorkerHost } from './languageDetectionWorker.protocol.js'; @@ -201,8 +201,10 @@ export class LanguageDetectionWorkerClient extends Disposable { } { if (!this.worker) { const workerClient = this._register(createWebWorker( - FileAccess.asBrowserUri('vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain.js'), - 'LanguageDetectionWorker' + new WebWorkerDescriptor({ + esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain.js'), + label: 'LanguageDetectionWorker' + }) )); LanguageDetectionWorkerHost.setChannel(workerClient, { $getIndexJsUri: async () => this.getIndexJsUri(), diff --git a/src/vs/workbench/services/search/browser/searchService.ts b/src/vs/workbench/services/search/browser/searchService.ts index 5d1dc405a68..5c1ad04633e 100644 --- a/src/vs/workbench/services/search/browser/searchService.ts +++ b/src/vs/workbench/services/search/browser/searchService.ts @@ -16,7 +16,7 @@ import { SearchService } from '../common/searchService.js'; import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js'; import { IWebWorkerClient, logOnceWebWorkerWarning } from '../../../../base/common/worker/webWorker.js'; import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js'; -import { createWebWorker } from '../../../../base/browser/webWorkerFactory.js'; +import { createWebWorker, WebWorkerDescriptor } from '../../../../base/browser/webWorkerFactory.js'; import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; import { ILocalFileSearchWorker, LocalFileSearchWorkerHost } from '../common/localFileSearchWorkerTypes.js'; import { memoize } from '../../../../base/common/decorators.js'; @@ -188,8 +188,10 @@ export class LocalFileSearchWorkerClient extends Disposable implements ISearchRe if (!this._worker) { try { this._worker = this._register(createWebWorker( - FileAccess.asBrowserUri('vs/workbench/services/search/worker/localFileSearchMain.js'), - 'LocalFileSearchWorker' + new WebWorkerDescriptor({ + esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/services/search/worker/localFileSearchMain.js'), + label: 'LocalFileSearchWorker' + }) )); LocalFileSearchWorkerHost.setChannel(this._worker, { $sendTextSearchMatch: (match, queryId) => { diff --git a/src/vs/workbench/services/search/common/localFileSearchWorkerTypes.ts b/src/vs/workbench/services/search/common/localFileSearchWorkerTypes.ts index 36f559acb48..31dad764d6e 100644 --- a/src/vs/workbench/services/search/common/localFileSearchWorkerTypes.ts +++ b/src/vs/workbench/services/search/common/localFileSearchWorkerTypes.ts @@ -53,7 +53,7 @@ export abstract class LocalFileSearchWorkerHost { public static getChannel(workerServer: IWebWorkerServer): LocalFileSearchWorkerHost { return workerServer.getChannel(LocalFileSearchWorkerHost.CHANNEL_NAME); } - public static setChannel(workerClient: IWebWorkerClient, obj: LocalFileSearchWorkerHost): void { + public static setChannel(workerClient: IWebWorkerClient, obj: LocalFileSearchWorkerHost): void { workerClient.setChannel(LocalFileSearchWorkerHost.CHANNEL_NAME, obj); } diff --git a/src/vs/workbench/services/search/common/searchService.ts b/src/vs/workbench/services/search/common/searchService.ts index 857a37c465c..c18343455a9 100644 --- a/src/vs/workbench/services/search/common/searchService.ts +++ b/src/vs/workbench/services/search/common/searchService.ts @@ -175,7 +175,7 @@ export class SearchService extends Disposable implements ISearchService { const schemesInQuery = this.getSchemesInQuery(query); - const providerActivations: Promise[] = [Promise.resolve(null)]; + const providerActivations: Promise[] = [Promise.resolve(null)]; schemesInQuery.forEach(scheme => providerActivations.push(this.extensionService.activateByEvent(`onSearch:${scheme}`))); providerActivations.push(this.extensionService.activateByEvent('onSearch:file')); diff --git a/src/vs/workbench/services/search/worker/localFileSearch.ts b/src/vs/workbench/services/search/worker/localFileSearch.ts index df350c5cede..b01a1cea40c 100644 --- a/src/vs/workbench/services/search/worker/localFileSearch.ts +++ b/src/vs/workbench/services/search/worker/localFileSearch.ts @@ -173,7 +173,7 @@ export class LocalFileSearchWorker implements ILocalFileSearchWorker, IWebWorker } - private async walkFolderQuery(handle: IWorkerFileSystemDirectoryHandle, queryProps: ICommonQueryProps, folderQuery: IFolderQuery, extUri: ExtUri, onFile: (file: FileNode) => any, token: CancellationToken): Promise { + private async walkFolderQuery(handle: IWorkerFileSystemDirectoryHandle, queryProps: ICommonQueryProps, folderQuery: IFolderQuery, extUri: ExtUri, onFile: (file: FileNode) => Promise | unknown, token: CancellationToken): Promise { const folderExcludes = folderQuery.excludePattern?.map(excludePattern => glob.parse(excludePattern.pattern ?? {}, { trimForExclusions: true }) as glob.ParsedExpression); @@ -276,7 +276,7 @@ export class LocalFileSearchWorker implements ILocalFileSearchWorker, IWebWorker }; }; - const resolveDirectory = async (directory: DirNode, onFile: (f: FileNode) => any) => { + const resolveDirectory = async (directory: DirNode, onFile: (f: FileNode) => Promise | unknown) => { if (token.isCancellationRequested) { return; } await Promise.all( diff --git a/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts b/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts index 59502ab69cc..cefef222089 100644 --- a/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts +++ b/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts @@ -22,7 +22,7 @@ import { TextMateWorkerHost } from './worker/textMateWorkerHost.js'; import { TextMateWorkerTokenizerController } from './textMateWorkerTokenizerController.js'; import { IValidGrammarDefinition } from '../../common/TMScopeRegistry.js'; import type { IRawTheme } from 'vscode-textmate'; -import { createWebWorker } from '../../../../../base/browser/webWorkerFactory.js'; +import { createWebWorker, WebWorkerDescriptor } from '../../../../../base/browser/webWorkerFactory.js'; import { IWebWorkerClient, Proxied } from '../../../../../base/common/worker/webWorker.js'; export class ThreadedBackgroundTokenizerFactory implements IDisposable { @@ -138,8 +138,10 @@ export class ThreadedBackgroundTokenizerFactory implements IDisposable { onigurumaWASMUri: FileAccess.asBrowserUri(onigurumaWASM).toString(true), }; const worker = this._worker = createWebWorker( - FileAccess.asBrowserUri('vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain.js'), - 'TextMateWorker' + new WebWorkerDescriptor({ + esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain.js'), + label: 'TextMateWorker' + }) ); TextMateWorkerHost.setChannel(worker, { $readFile: async (_resource: UriComponents): Promise => { diff --git a/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker.ts b/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker.ts index a184a885fcb..124a298e0bd 100644 --- a/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker.ts +++ b/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker.ts @@ -88,7 +88,7 @@ export class TextMateTokenizationWorker implements IWebWorkerServerRequestHandle return new TMGrammarFactory({ logTrace: (msg: string) => {/* console.log(msg) */ }, - logError: (msg: string, err: any) => console.error(msg, err), + logError: (msg: string, err: unknown) => console.error(msg, err), readFile: (resource: URI) => this._host.$readFile(resource) }, grammarDefinitions, vscodeTextmate, onigLib); } diff --git a/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerHost.ts b/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerHost.ts index 8d2338cf97a..e84330da915 100644 --- a/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerHost.ts +++ b/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerHost.ts @@ -12,7 +12,7 @@ export abstract class TextMateWorkerHost { public static getChannel(workerServer: IWebWorkerServer): TextMateWorkerHost { return workerServer.getChannel(TextMateWorkerHost.CHANNEL_NAME); } - public static setChannel(workerClient: IWebWorkerClient, obj: TextMateWorkerHost): void { + public static setChannel(workerClient: IWebWorkerClient, obj: TextMateWorkerHost): void { workerClient.setChannel(TextMateWorkerHost.CHANNEL_NAME, obj); } diff --git a/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts b/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts index 304c7c18d0b..34ee2bfb8b7 100644 --- a/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts +++ b/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts @@ -269,7 +269,7 @@ export class TextMateTokenizationFeature extends Disposable implements ITextMate this._grammarFactory = new TMGrammarFactory({ logTrace: (msg: string) => this._logService.trace(msg), - logError: (msg: string, err: any) => this._logService.error(msg, err), + logError: (msg: string, err: unknown) => this._logService.error(msg, err), readFile: (resource: URI) => this._extensionResourceLoaderService.readExtensionResource(resource) }, this._grammarDefinitions || [], vscodeTextmate, onigLib); diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index 6622617c120..1440fbb3cce 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -283,7 +283,7 @@ export class WorkbenchThemeService extends Disposable implements IWorkbenchTheme })); } - private installRegistryListeners(): Promise { + private installRegistryListeners(): Promise { let prevColorId: string | undefined = undefined; diff --git a/src/vs/workbench/services/userActivity/common/userActivityRegistry.ts b/src/vs/workbench/services/userActivity/common/userActivityRegistry.ts index 1af59b8c4d8..b9222b40c78 100644 --- a/src/vs/workbench/services/userActivity/common/userActivityRegistry.ts +++ b/src/vs/workbench/services/userActivity/common/userActivityRegistry.ts @@ -7,9 +7,9 @@ import { IInstantiationService } from '../../../../platform/instantiation/common import { IUserActivityService } from './userActivityService.js'; class UserActivityRegistry { - private todo: { new(s: IUserActivityService, ...args: any[]): unknown }[] = []; + private todo: { new(s: IUserActivityService, ...args: unknown[]): unknown }[] = []; - public add = (ctor: { new(s: IUserActivityService, ...args: any[]): unknown }) => { + public add = (ctor: { new(s: IUserActivityService, ...args: unknown[]): unknown }) => { this.todo.push(ctor); }; diff --git a/src/vs/workbench/services/userData/browser/userDataInit.ts b/src/vs/workbench/services/userData/browser/userDataInit.ts index 848219e6530..af58ce53f1f 100644 --- a/src/vs/workbench/services/userData/browser/userDataInit.ts +++ b/src/vs/workbench/services/userData/browser/userDataInit.ts @@ -21,12 +21,12 @@ export interface IUserDataInitializer { export const IUserDataInitializationService = createDecorator('IUserDataInitializationService'); export interface IUserDataInitializationService extends IUserDataInitializer { - _serviceBrand: any; + _serviceBrand: undefined; } export class UserDataInitializationService implements IUserDataInitializationService { - _serviceBrand: any; + _serviceBrand: undefined; constructor(private readonly initializers: IUserDataInitializer[] = []) { } diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileInit.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileInit.ts index a85c311f35f..6df19e5a98e 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileInit.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileInit.ts @@ -27,7 +27,7 @@ import { ProfileResourceType } from '../../../../platform/userDataProfile/common export class UserDataProfileInitializer implements IUserDataInitializer { - _serviceBrand: any; + _serviceBrand: undefined; private readonly initialized: ProfileResourceType[] = []; private readonly initializationFinished = new Barrier(); diff --git a/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.ts b/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.ts index b97bb50f533..36aaa2e2b34 100644 --- a/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.ts +++ b/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.ts @@ -38,7 +38,7 @@ import { ISecretStorageService } from '../../../../platform/secrets/common/secre export class UserDataSyncInitializer implements IUserDataInitializer { - _serviceBrand: any; + _serviceBrand: undefined; private readonly initialized: SyncResource[] = []; private readonly initializationFinished = new Barrier(); diff --git a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts index 28905f3c93f..192ded1f9dc 100644 --- a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts +++ b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts @@ -63,7 +63,7 @@ export function isMergeEditorInput(editor: unknown): editor is MergeEditorInput export class UserDataSyncWorkbenchService extends Disposable implements IUserDataSyncWorkbenchService { - _serviceBrand: any; + _serviceBrand: undefined; private static DONOT_USE_WORKBENCH_SESSION_STORAGE_KEY = 'userDataSyncAccount.donotUseWorkbenchSession'; private static CACHED_AUTHENTICATION_PROVIDER_KEY = 'userDataSyncAccountProvider'; diff --git a/src/vs/workbench/services/userDataSync/common/userDataSync.ts b/src/vs/workbench/services/userDataSync/common/userDataSync.ts index 3381e6d9885..f4991441edb 100644 --- a/src/vs/workbench/services/userDataSync/common/userDataSync.ts +++ b/src/vs/workbench/services/userDataSync/common/userDataSync.ts @@ -24,7 +24,7 @@ export interface IUserDataSyncAccount { export const IUserDataSyncWorkbenchService = createDecorator('IUserDataSyncWorkbenchService'); export interface IUserDataSyncWorkbenchService { - _serviceBrand: any; + _serviceBrand: undefined; readonly enabled: boolean; readonly authenticationProviders: IAuthenticationProvider[]; diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index bcf4471762a..b2cc3ecc7ef 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -1431,6 +1431,8 @@ export class TestHostService implements IHostService { async moveTop(): Promise { } async getCursorScreenPoint(): Promise { return undefined; } + async getWindows(options: unknown) { return []; } + async openWindow(arg1?: IOpenEmptyWindowOptions | IWindowOpenable[], arg2?: IOpenWindowOptions): Promise { } async toggleFullScreen(): Promise { }