Merge branch 'main' into tyriar/274723_platform_terminal__api

This commit is contained in:
Daniel Imms
2025-11-10 06:57:41 -08:00
committed by GitHub
140 changed files with 787 additions and 429 deletions
+1 -73
View File
@@ -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
}
]
}
+4
View File
@@ -179,6 +179,10 @@ export class ApiRepository implements Repository {
return this.#repository.diffIndexWithHEAD(path);
}
diffIndexWithHEADShortStats(path?: string): Promise<CommitShortStat> {
return this.#repository.diffIndexWithHEADShortStats(path);
}
diffIndexWith(ref: string): Promise<Change[]>;
diffIndexWith(ref: string, path: string): Promise<string>;
diffIndexWith(ref: string, path?: string): Promise<string | Change[]> {
+1
View File
@@ -242,6 +242,7 @@ export interface Repository {
diffWith(ref: string, path: string): Promise<string>;
diffIndexWithHEAD(): Promise<Change[]>;
diffIndexWithHEAD(path: string): Promise<string>;
diffIndexWithHEADShortStats(path?: string): Promise<CommitShortStat>;
diffIndexWith(ref: string): Promise<Change[]>;
diffIndexWith(ref: string, path: string): Promise<string>;
diffBlobs(object1: string, object2: string): Promise<string>;
+4
View File
@@ -1658,6 +1658,10 @@ export class Repository {
return result.stdout;
}
async diffIndexWithHEADShortStats(path?: string): Promise<CommitShortStat> {
return this.diffFilesShortStat(undefined, { cached: true, path });
}
diffIndexWith(ref: string): Promise<Change[]>;
diffIndexWith(ref: string, path: string): Promise<string>;
diffIndexWith(ref: string, path?: string | undefined): Promise<string | Change[]>;
+4
View File
@@ -1225,6 +1225,10 @@ export class Repository implements Disposable {
return this.run(Operation.Diff, () => this.repository.diffIndexWithHEAD(path));
}
diffIndexWithHEADShortStats(path?: string): Promise<CommitShortStat> {
return this.run(Operation.Diff, () => this.repository.diffIndexWithHEADShortStats(path));
}
diffIndexWith(ref: string): Promise<Change[]>;
diffIndexWith(ref: string, path: string): Promise<string>;
diffIndexWith(ref: string, path?: string | undefined): Promise<string | Change[]>;
+33
View File
@@ -65,3 +65,36 @@ export interface CellMetadata {
execution_count?: number | null;
}
type KeysOfUnionType<T> = T extends T ? keyof T : never;
type FilterType<T, TTest> = T extends TTest ? T : never;
type MakeOptionalAndBool<T extends object> = { [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<T extends object, TKeys>(x: T, key: TKeys & MakeOptionalAndBool<T>): x is FilterType<T, { [K in KeysOfUnionType<T> & keyof TKeys]: unknown }> {
for (const k in key) {
if (!(k in x)) {
return false;
}
}
return true;
}
+2 -2
View File
@@ -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;
}
+1 -1
View File
@@ -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];
+3 -3
View File
@@ -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 :
' ';
+4 -4
View File
@@ -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<string, unknown> | 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<string, unknown> | undefined;
return (typeof metadata === 'object' && metadata
&& 'scrollable' in metadata && typeof metadata.scrollable === 'boolean') ?
&& typeof metadata.scrollable === 'boolean') ?
metadata.scrollable : options.outputScrolling;
}
@@ -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');
});
});
+56 -23
View File
@@ -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;
+27 -19
View File
@@ -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<Worker> {
function getWorker(descriptor: WebWorkerDescriptor, id: number): Worker | Promise<Worker> {
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<any>());
public readonly onError = this._onError.event;
constructor(descriptorOrWorker: IWebWorkerDescriptor | Worker | Promise<Worker>) {
constructor(descriptorOrWorker: WebWorkerDescriptor | Worker | Promise<Worker>) {
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<T extends object>(esmModuleLocation: URI, label: string | undefined): IWebWorkerClient<T>;
export function createWebWorker<T extends object>(workerDescriptor: IWebWorkerDescriptor | Worker | Promise<Worker>): IWebWorkerClient<T>;
export function createWebWorker<T extends object>(arg0: URI | IWebWorkerDescriptor | Worker | Promise<Worker>, arg1?: string | undefined): IWebWorkerClient<T> {
const workerDescriptorOrWorker = (URI.isUri(arg0) ? new WebWorkerDescriptor(arg0, arg1) : arg0);
return new WebWorkerClient<T>(new WebWorker(workerDescriptorOrWorker));
export function createWebWorker<T extends object>(workerDescriptor: WebWorkerDescriptor | Worker | Promise<Worker>): IWebWorkerClient<T> {
return new WebWorkerClient<T>(new WebWorker(workerDescriptor));
}
+10 -1
View File
@@ -109,7 +109,16 @@ export function binarySearch2(length: number, compareToKey: (index: number) => n
type Compare<T> = (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<T>(nth: number, data: T[], compare: Compare<T>): T {
nth = nth | 0;
+5 -5
View File
@@ -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<any> = Object.freeze(function (callback, context?): IDisposable {
const shortcutEvent: Event<void> = 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<any> | null = null;
private _emitter: Emitter<void> | null = null;
public cancel() {
if (!this._isCancelled) {
@@ -76,12 +76,12 @@ class MutableToken implements CancellationToken {
return this._isCancelled;
}
get onCancellationRequested(): Event<any> {
get onCancellationRequested(): Event<void> {
if (this._isCancelled) {
return shortcutEvent;
}
if (!this._emitter) {
this._emitter = new Emitter<any>();
this._emitter = new Emitter<void>();
}
return this._emitter.event;
}
+10 -10
View File
@@ -5,11 +5,11 @@
class Node<E> {
static readonly Undefined = new Node<any>(undefined);
static readonly Undefined = new Node<unknown>(undefined);
element: E;
next: Node<E>;
prev: Node<E>;
next: Node<E> | typeof Node.Undefined;
prev: Node<E> | typeof Node.Undefined;
constructor(element: E) {
this.element = element;
@@ -20,8 +20,8 @@ class Node<E> {
export class LinkedList<E> {
private _first: Node<E> = Node.Undefined;
private _last: Node<E> = Node.Undefined;
private _first: Node<E> | typeof Node.Undefined = Node.Undefined;
private _last: Node<E> | typeof Node.Undefined = Node.Undefined;
private _size: number = 0;
get size(): number {
@@ -91,7 +91,7 @@ export class LinkedList<E> {
} else {
const res = this._first.element;
this._remove(this._first);
return res;
return res as E;
}
}
@@ -101,7 +101,7 @@ export class LinkedList<E> {
} else {
const res = this._last.element;
this._remove(this._last);
return res;
return res as E;
}
}
@@ -110,11 +110,11 @@ export class LinkedList<E> {
return undefined;
} else {
const res = this._last.element;
return res;
return res as E;
}
}
private _remove(node: Node<E>): void {
private _remove(node: Node<E> | 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<E> {
*[Symbol.iterator](): Iterator<E> {
let node = this._first;
while (node !== Node.Undefined) {
yield node.element;
yield node.element as E;
node = node.next;
}
}
+4 -4
View File
@@ -116,7 +116,7 @@ export class ResourceMap<T> implements Map<URI, T> {
return this.map.delete(this.toKey(resource));
}
forEach(clb: (value: T, key: URI, map: Map<URI, T>) => void, thisArg?: any): void {
forEach(clb: (value: T, key: URI, map: Map<URI, T>) => void, thisArg?: object): void {
if (typeof thisArg !== 'undefined') {
clb = clb.bind(thisArg);
}
@@ -185,7 +185,7 @@ export class ResourceSet implements Set<URI> {
return this._map.delete(value);
}
forEach(callbackfn: (value: URI, value2: URI, set: Set<URI>) => void, thisArg?: any): void {
forEach(callbackfn: (value: URI, value2: URI, set: Set<URI>) => void, thisArg?: unknown): void {
this._map.forEach((_value, key) => callbackfn.call(thisArg, key, key, this));
}
@@ -340,7 +340,7 @@ export class LinkedMap<K, V> implements Map<K, V> {
return item.value;
}
forEach(callbackfn: (value: V, key: K, map: LinkedMap<K, V>) => void, thisArg?: any): void {
forEach(callbackfn: (value: V, key: K, map: LinkedMap<K, V>) => void, thisArg?: unknown): void {
const state = this._state;
let current = this._head;
while (current) {
@@ -789,7 +789,7 @@ export class BidirectionalMap<K, V> {
return true;
}
forEach(callbackfn: (value: V, key: K, map: BidirectionalMap<K, V>) => void, thisArg?: any): void {
forEach(callbackfn: (value: V, key: K, map: BidirectionalMap<K, V>) => void, thisArg?: unknown): void {
this._m1.forEach((value, key) => {
callbackfn.call(thisArg, value, key, this);
});
+6 -6
View File
@@ -35,8 +35,8 @@ export class SkipList<K, V> implements Map<K, V> {
capacity: number = 2 ** 16
) {
this._maxLevel = Math.max(1, Math.log2(capacity) | 0);
// eslint-disable-next-line local/code-no-any-casts
this._header = <any>new Node(this._maxLevel, NIL, NIL);
this._header = new Node(this._maxLevel, <K>NIL, <V>NIL);
}
get size(): number {
@@ -44,8 +44,8 @@ export class SkipList<K, V> implements Map<K, V> {
}
clear(): void {
// eslint-disable-next-line local/code-no-any-casts
this._header = <any>new Node(this._maxLevel, NIL, NIL);
this._header = new Node(this._maxLevel, <K>NIL, <V>NIL);
this._size = 0;
}
@@ -74,7 +74,7 @@ export class SkipList<K, V> implements Map<K, V> {
// --- iteration
forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void {
forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => 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<K, V> implements Map<K, V> {
}
}
private static _randomLevel(list: SkipList<any, any>, p: number = 0.5): number {
private static _randomLevel<K, V>(list: SkipList<K, V>, p: number = 0.5): number {
let lvl = 1;
while (Math.random() < p && lvl < list._maxLevel) {
lvl += 1;
+1 -1
View File
@@ -781,7 +781,7 @@ export class TernarySearchTree<K, V> {
// for debug/testing
_isBalanced(): boolean {
const nodeIsBalanced = (node: TernarySearchTreeNode<any, any> | undefined): boolean => {
const nodeIsBalanced = (node: TernarySearchTreeNode<unknown, unknown> | undefined): boolean => {
if (!node) {
return true;
}
@@ -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();
@@ -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];
+3 -2
View File
@@ -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<boolean>();
private readonly _onDidChangeTabFocus = this._register(new Emitter<boolean>());
public readonly onDidChangeTabFocus: Event<boolean> = this._onDidChangeTabFocus.event;
public getTabFocusMode(): boolean {
+1 -2
View File
@@ -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];
+1 -1
View File
@@ -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.
@@ -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<Worker>,
private readonly _workerDescriptorOrWorker: WebWorkerDescriptor | Worker | Promise<Worker>,
keepIdleModels: boolean,
@IModelService modelService: IModelService,
) {
@@ -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';
@@ -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) {
@@ -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));
}
}
@@ -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);
}
}
@@ -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;
@@ -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];
@@ -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--;
@@ -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;
@@ -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;
}
}
@@ -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;
}
@@ -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<boolean>(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;
@@ -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);
}
@@ -112,7 +112,7 @@ CommandsRegistry.registerCommand('_executeCodeLensProvider', function (accessor,
return getCodeLensModel(codeLensProvider, model, CancellationToken.None).then(value => {
disposables.add(value);
const resolve: Promise<any>[] = [];
const resolve: Promise<unknown>[] = [];
for (const item of value.lenses) {
if (itemResolveCount === undefined || itemResolveCount === null || Boolean(item.symbol.command)) {
@@ -42,7 +42,7 @@ export class CodeLensContribution implements IEditorContribution {
private _getCodeLensModelPromise: CancelablePromise<CodeLensModel> | undefined;
private readonly _oldCodeLensModels = new DisposableStore();
private _currentCodeLensModel: CodeLensModel | undefined;
private _resolveCodeLensesPromise: CancelablePromise<any> | undefined;
private _resolveCodeLensesPromise: CancelablePromise<void[]> | undefined;
constructor(
private readonly _editor: ICodeEditor,
@@ -435,7 +435,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
getPosition(): IOverlayWidgetPosition | null {
return {
preference: OverlayWidgetPositionPreference.TOP_CENTER,
stackOridinal: 10,
stackOrdinal: 10,
};
}
@@ -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(
+2 -2
View File
@@ -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;
}
/**
@@ -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;
}
@@ -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<string, IRawConfigBasedExtensionTip> = new Map<string, IRawConfigBasedExtensionTip>();
@@ -25,7 +25,7 @@ export interface IExtensionHostStarter {
onDynamicStdout(id: string): Event<string>;
onDynamicStderr(id: string): Event<string>;
onDynamicMessage(id: string): Event<any>;
onDynamicMessage(id: string): Event<unknown>;
onDynamicExit(id: string): Event<{ code: number; signal: string }>;
createExtensionHost(): Promise<{ id: string }>;
@@ -61,7 +61,7 @@ export class ExtensionHostStarter extends Disposable implements IDisposable, IEx
return this._getExtHost(id).onStderr;
}
onDynamicMessage(id: string): Event<any> {
onDynamicMessage(id: string): Event<unknown> {
return this._getExtHost(id).onMessage;
}
@@ -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<R>(callback: (worker: Proxied<IProfileAnalysisWorker>) => Promise<R>): Promise<R> {
const worker = createWebWorker<IProfileAnalysisWorker>(
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 {
@@ -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.'));
@@ -10,7 +10,7 @@ import { createDecorator } from '../../instantiation/common/instantiation.js';
export const IIgnoredExtensionsManagementService = createDecorator<IIgnoredExtensionsManagementService>('IIgnoredExtensionsManagementService');
export interface IIgnoredExtensionsManagementService {
readonly _serviceBrand: any;
readonly _serviceBrand: undefined;
getIgnoredExtensions(installed: ILocalExtension[]): string[];
@@ -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<AutoSync>());
private successiveFailures: number = 0;
@@ -545,7 +545,7 @@ export function getEnablementKey(resource: SyncResource) { return `sync.enable.$
// #region User Data Sync Services
export const IUserDataSyncEnablementService = createDecorator<IUserDataSyncEnablementService>('IUserDataSyncEnablementService');
export interface IUserDataSyncEnablementService {
_serviceBrand: any;
_serviceBrand: undefined;
readonly onDidChangeEnablement: Event<boolean>;
isEnabled(): boolean;
@@ -580,7 +580,7 @@ export interface IUserDataManualSyncTask {
export const IUserDataSyncService = createDecorator<IUserDataSyncService>('IUserDataSyncService');
export interface IUserDataSyncService {
_serviceBrand: any;
_serviceBrand: undefined;
readonly status: SyncStatus;
readonly onDidChangeStatus: Event<SyncStatus>;
@@ -617,7 +617,7 @@ export interface IUserDataSyncService {
export const IUserDataSyncResourceProviderService = createDecorator<IUserDataSyncResourceProviderService>('IUserDataSyncResourceProviderService');
export interface IUserDataSyncResourceProviderService {
_serviceBrand: any;
_serviceBrand: undefined;
getRemoteSyncedProfiles(): Promise<ISyncUserDataProfile[]>;
getLocalSyncedProfiles(location?: URI): Promise<ISyncUserDataProfile[]>;
getRemoteSyncResourceHandles(syncResource: SyncResource, profile?: ISyncUserDataProfile): Promise<ISyncResourceHandle[]>;
@@ -633,7 +633,7 @@ export type SyncOptions = { immediately?: boolean; skipIfSyncedRecently?: boolea
export const IUserDataAutoSyncService = createDecorator<IUserDataAutoSyncService>('IUserDataAutoSyncService');
export interface IUserDataAutoSyncService {
_serviceBrand: any;
_serviceBrand: undefined;
readonly onError: Event<UserDataSyncError>;
turnOn(): Promise<void>;
turnOff(everywhere: boolean): Promise<void>;
@@ -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; }
@@ -14,7 +14,7 @@ const enablementKey = 'sync.enable';
export class UserDataSyncEnablementService extends Disposable implements IUserDataSyncEnablementService {
_serviceBrand: any;
_serviceBrand: undefined;
private _onDidChangeEnablement = new Emitter<boolean>();
readonly onDidChangeEnablement: Event<boolean> = this._onDidChangeEnablement.event;
@@ -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,
@@ -32,7 +32,7 @@ export type IUserDataSyncMachine = Readonly<IMachineData> & { readonly isCurrent
export const IUserDataSyncMachinesService = createDecorator<IUserDataSyncMachinesService>('IUserDataSyncMachinesService');
export interface IUserDataSyncMachinesService {
_serviceBrand: any;
_serviceBrand: undefined;
readonly onDidChange: Event<void>;
@@ -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<void>());
readonly onDidChange = this._onDidChange.event;
@@ -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';
@@ -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:
@@ -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<void>());
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,
@@ -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<string[]> {
return getDefaultIgnoredSettings();
@@ -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<boolean>('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<string>(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);
@@ -186,7 +186,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
this.#proxy?.$clear(this._owner);
}
forEach(callback: (uri: URI, diagnostics: ReadonlyArray<vscode.Diagnostic>, collection: DiagnosticCollection) => any, thisArg?: any): void {
forEach(callback: (uri: URI, diagnostics: ReadonlyArray<vscode.Diagnostic>, collection: DiagnosticCollection) => unknown, thisArg?: unknown): void {
this._checkDisposed();
for (const [uri, values] of this) {
callback.call(thisArg, uri, values, this);
@@ -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, <any>{ 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<any> {
private _deliverEventAsyncAndBlameBadListeners([listener, thisArg, extension]: Listener, stubEvent: Pick<vscode.TextDocumentWillSaveEvent, 'document' | 'reason'>): Promise<boolean> {
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<any> {
private _deliverEventAsync(extension: IExtensionDescription, listener: Function, thisArg: unknown, stubEvent: Pick<vscode.TextDocumentWillSaveEvent, 'document' | 'reason'>): Promise<boolean | undefined> {
const promises: Promise<vscode.TextEdit[]>[] = [];
@@ -111,6 +111,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
const event = Object.freeze<vscode.TextDocumentWillSaveEvent>({
document,
reason,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
waitUntil(p: Promise<any | vscode.TextEdit[]>) {
if (Object.isFrozen(promises)) {
throw illegalState('waitUntil can not be called async');
@@ -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);
}
@@ -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<void> {
@@ -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<boolean>();
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<boolean>();
const recentWorkspaces = new ResourceMap<IWorkspaceIdentifier>();
@@ -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
+12 -1
View File
@@ -3050,7 +3050,18 @@ class LayoutStateModel extends Disposable {
}
private loadKeyFromStorage<T extends StorageKeyType>(key: WorkbenchLayoutStateKey<T>): 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
@@ -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']),
@@ -348,6 +348,12 @@ const registry = Registry.as<IConfigurationRegistry>(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<IConfigurationRegistry>(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,
+1
View File
@@ -1254,6 +1254,7 @@ interface IEditorPartConfiguration {
closeEmptyGroups?: boolean;
autoLockGroups?: Set<string>;
revealIfOpen?: boolean;
swipeToNavigate?: boolean;
mouseBackForwardToNavigate?: boolean;
labelFormat?: 'default' | 'short' | 'medium' | 'long';
restoreViewState?: boolean;
@@ -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();
@@ -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<void> {
// 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
@@ -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<IAgentSes
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService,
@IHoverService private readonly hoverService: IHoverService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
) { }
renderTemplate(container: HTMLElement): IAgentSessionItemTemplate {
@@ -88,11 +88,7 @@ export class AgentSessionRenderer implements ICompressibleTreeRenderer<IAgentSes
h('div.agent-session-main-col', [
h('div.agent-session-title-row', [
h('div.agent-session-title@title'),
h('div.agent-session-diff', [
h('span.agent-session-diff-files@diffFiles'),
h('span.agent-session-diff-added@diffAdded'),
h('span.agent-session-diff-removed@diffRemoved')
]),
h('div.agent-session-toolbar@toolbar'),
]),
h('div.agent-session-details-row', [
h('div.agent-session-description@description'),
@@ -104,14 +100,22 @@ export class AgentSessionRenderer implements ICompressibleTreeRenderer<IAgentSes
container.appendChild(elements.item);
const toolbar = disposables.add(new ActionBar(elements.toolbar, {
actionViewItemProvider: (action, options) => {
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<IAgentSes
// Title
template.title.setLabel(session.element.label, undefined, { matches: createMatches(session.filterData) });
// Diff
// Toolbar
template.toolbar.clear();
const { statistics: diff } = session.element;
template.diffFiles.textContent = diff?.files && diff.files > 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<IAgentSes
},
allowedLinkSchemes: { augment: [this.productService.urlProtocol] }
},
}, template.description));
}, template.description);
template.elementDisposable.add(descriptionMarkdown);
// TODO@bpasero this is needed so that a user can click into a link of the session
// without opening the session itself. Revisit this approach as we want to move
// away from allowing different results based on where the user clicks.
template.elementDisposable.add(addDisposableListener(template.description, EventType.MOUSE_DOWN, e => 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)
@@ -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;
}
}
@@ -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 */
}
}
@@ -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 {
@@ -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
};
}
}
@@ -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);
}
@@ -47,7 +47,7 @@ export class ChatFollowups<T extends IChatFollowup> 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');
@@ -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;
@@ -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<Ch
let content: IChatRendererContent[] = [];
if (!element.confirmation) {
const markdown = 'message' in element.message ?
const markdown = isChatFollowup(element.message) ?
element.message.message :
this.markdownDecorationsRenderer.convertParsedRequestToMarkdown(element.message);
content = [{ content: new MarkdownString(markdown), kind: 'markdownContent' }];
@@ -1729,7 +1729,7 @@ export class ChatListDelegate implements IListVirtualDelegate<ChatTreeItem> {
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;
}
@@ -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 });
}
});
@@ -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';
@@ -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
@@ -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);
}
}
@@ -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 {
@@ -6,5 +6,5 @@
import { UserDataSyncStoreClient } from '../../../../platform/userDataSync/common/userDataSyncStoreService.js';
export class EditSessionsStoreClient extends UserDataSyncStoreClient {
_serviceBrand: any;
_serviceBrand: undefined;
}
@@ -36,7 +36,7 @@ class NullBackupStoreService implements IUserDataSyncLocalStoreService {
}
class NullEnablementService implements IUserDataSyncEnablementService {
_serviceBrand: any;
_serviceBrand: undefined;
private _onDidChangeEnablement = new Emitter<boolean>();
readonly onDidChangeEnablement: Event<boolean> = this._onDidChangeEnablement.event;
@@ -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;
@@ -63,7 +63,7 @@
}
.open-editors .monaco-list .monaco-list-row {
padding-left: 22px;
padding-left: 8px;
display: flex;
}
@@ -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) {
@@ -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) {
@@ -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];
}
}
@@ -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<NotebookWorker>(
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);
@@ -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();
}
}));
@@ -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
@@ -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);
}
@@ -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<OutputLinkComputer>(
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();
@@ -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;
}
@@ -100,7 +100,7 @@ export class RepositoryRenderer implements ICompressibleTreeRenderer<ISCMReposit
const label = new IconLabel(provider, { supportIcons: false });
const actions = append(provider, $('.actions'));
const toolBar = new WorkbenchToolBar(actions, { actionViewItemProvider: this.actionViewItemProvider, resetMenu: this.toolbarMenuId, responsive: true }, this.menuService, this.contextKeyService, this.contextMenuService, this.keybindingService, this.commandService, this.telemetryService);
const toolBar = new WorkbenchToolBar(actions, { actionViewItemProvider: this.actionViewItemProvider, resetMenu: this.toolbarMenuId, responsiveBehavior: { enabled: true, minItems: 2 } }, this.menuService, this.contextKeyService, this.contextMenuService, this.keybindingService, this.commandService, this.telemetryService);
const countContainer = append(provider, $('.count'));
const count = new CountBadge(countContainer, {}, defaultCountBadgeStyles);
const visibilityDisposable = toolBar.onDidChangeDropdownVisibility(e => provider.classList.toggle('active', e));
@@ -672,7 +672,7 @@ class CoverageToolbarWidget extends Disposable implements IOverlayWidget {
public getPosition(): IOverlayWidgetPosition | null {
return {
preference: OverlayWidgetPositionPreference.TOP_CENTER,
stackOridinal: 9,
stackOrdinal: 9,
};
}
@@ -219,7 +219,7 @@ export class RunUsingProfileAction extends Action2 {
});
}
public override async run(acessor: ServicesAccessor, ...elements: TestItemTreeElement[]): Promise<any> {
public override async run(acessor: ServicesAccessor, ...elements: TestItemTreeElement[]): Promise<void> {
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<any> {
public override async run(accessor: ServicesAccessor, ...elements: TestItemTreeElement[]): Promise<void> {
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<any> {
public override async run(accessor: ServicesAccessor, ...elements: TestItemTreeElement[]): Promise<void> {
const crService = accessor.get(ITestingContinuousRunService);
const profileService = accessor.get(ITestProfileService);
const notificationService = accessor.get(INotificationService);

Some files were not shown because too many files have changed in this diff Show More