From 16f501ee3382ce3805b9c9198c10076145521718 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Sat, 6 Nov 2021 12:02:54 -0400 Subject: [PATCH 001/119] Fix single line if/else and loop indentation --- extensions/php/language-configuration.json | 9 +++++++++ extensions/typescript-basics/language-configuration.json | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/extensions/php/language-configuration.json b/extensions/php/language-configuration.json index e585ebf1c91..f44d7a25cb6 100644 --- a/extensions/php/language-configuration.json +++ b/extensions/php/language-configuration.json @@ -76,6 +76,15 @@ "indent": "none", "removeText": 1 } + }, + { + // Decrease indentation after single line if/else if/else, for, foreach, or while + "previousLineText": "^\\s*(((else ?)?if|for(each)?|while)\\s*\\(.*\\)\\s*|else\\s*)$", + // But make sure line doesn't have braces or is not another if statement + "beforeText": "^\\s+([^{i\\s]|i(?!f\\b))", + "action": { + "indent": "outdent" + } } ] } diff --git a/extensions/typescript-basics/language-configuration.json b/extensions/typescript-basics/language-configuration.json index 07260718b64..d940228f3e4 100644 --- a/extensions/typescript-basics/language-configuration.json +++ b/extensions/typescript-basics/language-configuration.json @@ -188,6 +188,15 @@ "action": { "indent": "indent" } + }, + { + // Decrease indentation after single line if/else if/else, for, or while + "previousLineText": "/^\\s*(((else )?if|for|while)\\s*\\(.*\\)\\s*|else\\s*)$/", + // But make sure line doesn't have braces or is not another if statement + "beforeText": "/^\\s+([^{i\\s]|i(?!f\\b))/", + "action": { + "indent": "indentOutdent" + } } ] } From 3894c48a02af26e5ddadcaacb5efcb2577a3e4dc Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Mon, 21 Nov 2022 21:41:18 -0500 Subject: [PATCH 002/119] JS/TS fixes --- .../javascript/javascript-language-configuration.json | 9 +++++++++ extensions/typescript-basics/language-configuration.json | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/extensions/javascript/javascript-language-configuration.json b/extensions/javascript/javascript-language-configuration.json index abfef6e8c4c..4029985233a 100644 --- a/extensions/javascript/javascript-language-configuration.json +++ b/extensions/javascript/javascript-language-configuration.json @@ -188,6 +188,15 @@ "action": { "indent": "indent" } + }, + { + // Decrease indentation after single line if/else if/else, for, or while + "previousLineText": "^\\s*(((else ?)?if|for|while)\\s*\\(.*\\)\\s*|else\\s*)$", + // But make sure line doesn't have braces or is not another if statement + "beforeText": "^\\s+([^{i\\s]|i(?!f\\b))", + "action": { + "indent": "outdent" + } } ] } diff --git a/extensions/typescript-basics/language-configuration.json b/extensions/typescript-basics/language-configuration.json index e0f21535797..03f06fa04d5 100644 --- a/extensions/typescript-basics/language-configuration.json +++ b/extensions/typescript-basics/language-configuration.json @@ -209,11 +209,11 @@ }, { // Decrease indentation after single line if/else if/else, for, or while - "previousLineText": "/^\\s*(((else )?if|for|while)\\s*\\(.*\\)\\s*|else\\s*)$/", + "previousLineText": "^\\s*(((else ?)?if|for|while)\\s*\\(.*\\)\\s*|else\\s*)$", // But make sure line doesn't have braces or is not another if statement - "beforeText": "/^\\s+([^{i\\s]|i(?!f\\b))/", + "beforeText": "^\\s+([^{i\\s]|i(?!f\\b))", "action": { - "indent": "indentOutdent" + "indent": "outdent" } } ] From a99fb2c5c313207a127e5adf534d10329df772ec Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Tue, 28 Feb 2023 21:17:35 -0500 Subject: [PATCH 003/119] Add to C/C++ --- extensions/cpp/language-configuration.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/extensions/cpp/language-configuration.json b/extensions/cpp/language-configuration.json index 0f365702269..3a5459401f9 100644 --- a/extensions/cpp/language-configuration.json +++ b/extensions/cpp/language-configuration.json @@ -30,5 +30,16 @@ "start": "^\\s*#pragma\\s+region\\b", "end": "^\\s*#pragma\\s+endregion\\b" } - } + }, + "onEnterRules": [ + { + // Decrease indentation after single line if/else if/else, for, or while + "previousLineText": "^\\s*(((else ?)?if|for|while)\\s*\\(.*\\)\\s*|else\\s*)$", + // But make sure line doesn't have braces or is not another if statement + "beforeText": "^\\s+([^{i\\s]|i(?!f\\b))", + "action": { + "indent": "outdent" + } + } + ] } From d772a63452f080dcae80a727ca38cbe1e4e73807 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Wed, 5 Jul 2023 10:48:10 -0700 Subject: [PATCH 004/119] remove redundant tag --- .../interactive/browser/interactive.contribution.ts | 5 +---- .../notebook/browser/services/notebookServiceImpl.ts | 8 ++++---- .../workbench/contrib/notebook/common/notebookCommon.ts | 2 -- .../workbench/contrib/notebook/common/notebookProvider.ts | 3 --- .../workbench/contrib/notebook/common/notebookService.ts | 1 + src/vs/workbench/services/extensions/common/extensions.ts | 3 ++- 6 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index 86bf90f9304..da64485f909 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -89,15 +89,12 @@ export class InteractiveDocumentContribution extends Disposable implements IWork const info = notebookService.getContributedNotebookType('interactive'); // We need to contribute a notebook type for the Interactive Window to provide notebook models. - // Don't add a file selector for the notebook type to avoid having the notebook Service create an editor for it. - // The IW editor is registered below, and we don't want it overwritten by the notebook Service. if (!info) { this._register(notebookService.registerContributedNotebookType('interactive', { providerDisplayName: 'Interactive Notebook', displayName: 'Interactive', filenamePattern: ['*.interactive'], - exclusive: true, - externalEditor: true + exclusive: true })); } diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts index 6afedbfff8e..0c82eb7cb7f 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts @@ -279,8 +279,9 @@ export class NotebookProviderInfoStore extends Disposable { } this._contributedEditors.set(info.id, info); let editorRegistration: IDisposable | undefined; - // Don't overwrite editor contributions if they come from elsewhere - if (!info.externalEditor) { + + // built-in notebook providers contribute their own editors + if (info.extension) { editorRegistration = this._registerContributionPoint(info); this._contributedEditorDisposables.add(editorRegistration); } @@ -640,8 +641,7 @@ export class NotebookService extends Disposable implements INotebookService { providerDisplayName: data.providerDisplayName, exclusive: data.exclusive, priority: RegisteredEditorPriority.default, - selectors: [], - externalEditor: !!data.externalEditor + selectors: [] }); info.update({ selectors: data.filenamePattern }); diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index f9df8c3c694..e57bc24b374 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -533,8 +533,6 @@ export interface INotebookContributionData { displayName: string; filenamePattern: (string | glob.IRelativePattern | INotebookExclusiveDocumentFilter)[]; exclusive: boolean; - /// Editor contribution is handled elswhere e.g. interactive - externalEditor?: boolean; } diff --git a/src/vs/workbench/contrib/notebook/common/notebookProvider.ts b/src/vs/workbench/contrib/notebook/common/notebookProvider.ts index 8345ef61981..16a9ee3a57b 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookProvider.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookProvider.ts @@ -20,7 +20,6 @@ export interface NotebookEditorDescriptor { readonly priority: RegisteredEditorPriority; readonly providerDisplayName: string; readonly exclusive: boolean; - readonly externalEditor?: boolean; } export class NotebookProviderInfo { @@ -31,7 +30,6 @@ export class NotebookProviderInfo { readonly priority: RegisteredEditorPriority; readonly providerDisplayName: string; readonly exclusive: boolean; - readonly externalEditor: boolean; private _selectors: NotebookSelector[]; get selectors() { @@ -59,7 +57,6 @@ export class NotebookProviderInfo { transientOutputs: false, cellContentMetadata: {} }; - this.externalEditor = !!descriptor.externalEditor; } update(args: { selectors?: NotebookSelector[]; options?: TransientOptions }) { diff --git a/src/vs/workbench/contrib/notebook/common/notebookService.ts b/src/vs/workbench/contrib/notebook/common/notebookService.ts index 2024a6fb925..6614adc8fbf 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookService.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookService.ts @@ -79,6 +79,7 @@ export interface INotebookService { getNotebookTextModels(): Iterable; listNotebookDocuments(): readonly NotebookTextModel[]; + /** Register a notebook type that we will handle. The notebook editor will be registered for notebook types contributed by extensions */ registerContributedNotebookType(viewType: string, data: INotebookContributionData): IDisposable; getContributedNotebookType(viewType: string): NotebookProviderInfo | undefined; getContributedNotebookTypes(resource?: URI): readonly NotebookProviderInfo[]; diff --git a/src/vs/workbench/services/extensions/common/extensions.ts b/src/vs/workbench/services/extensions/common/extensions.ts index 436f780bd00..cb18e8ac6f3 100644 --- a/src/vs/workbench/services/extensions/common/extensions.ts +++ b/src/vs/workbench/services/extensions/common/extensions.ts @@ -260,7 +260,8 @@ function extensionDescriptionArrayToMap(extensions: IExtensionDescription[]): Ex } export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean { - if (!extension.enabledApiProposals) { + if (!extension. + enabledApiProposals) { return false; } return extension.enabledApiProposals.includes(proposal); From 8e574b41c99da483f916de530f2189093899fa21 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Wed, 5 Jul 2023 11:04:40 -0700 Subject: [PATCH 005/119] undo format --- src/vs/workbench/services/extensions/common/extensions.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/services/extensions/common/extensions.ts b/src/vs/workbench/services/extensions/common/extensions.ts index cb18e8ac6f3..436f780bd00 100644 --- a/src/vs/workbench/services/extensions/common/extensions.ts +++ b/src/vs/workbench/services/extensions/common/extensions.ts @@ -260,8 +260,7 @@ function extensionDescriptionArrayToMap(extensions: IExtensionDescription[]): Ex } export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean { - if (!extension. - enabledApiProposals) { + if (!extension.enabledApiProposals) { return false; } return extension.enabledApiProposals.includes(proposal); From bd915931bd54d77309b17564f2746d989ddb48e9 Mon Sep 17 00:00:00 2001 From: Svante Boberg Date: Wed, 5 Jul 2023 21:08:19 +0200 Subject: [PATCH 006/119] Dispose `TerminalWordLinkDetector` listeners --- .../links/browser/terminal.links.contribution.ts | 2 +- .../terminalContrib/links/browser/terminalLinkManager.ts | 2 +- .../links/browser/terminalWordLinkDetector.ts | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminal.links.contribution.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminal.links.contribution.ts index 3bca06c97e1..dbd35c08605 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminal.links.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminal.links.contribution.ts @@ -54,7 +54,7 @@ class TerminalLinkContribution extends DisposableStore implements ITerminalContr this._processManager.onProcessReady(() => { linkManager.setWidgetManager(this._widgetManager); }); - this._linkManager = linkManager; + this._linkManager = this.add(linkManager); // Attach the link provider(s) to the instance and listen for changes for (const linkProvider of this._terminalLinkProviderService.linkProviders) { diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkManager.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkManager.ts index 2016e7ca592..e100b3a68c0 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkManager.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkManager.ts @@ -77,7 +77,7 @@ export class TerminalLinkManager extends DisposableStore { this._setupLinkDetector(TerminalMultiLineLinkDetector.id, this._instantiationService.createInstance(TerminalMultiLineLinkDetector, this._xterm, this._processManager, this._linkResolver)); this._setupLinkDetector(TerminalLocalLinkDetector.id, this._instantiationService.createInstance(TerminalLocalLinkDetector, this._xterm, capabilities, this._processManager, this._linkResolver)); } - this._setupLinkDetector(TerminalWordLinkDetector.id, this._instantiationService.createInstance(TerminalWordLinkDetector, this._xterm)); + this._setupLinkDetector(TerminalWordLinkDetector.id, this.add(this._instantiationService.createInstance(TerminalWordLinkDetector, this._xterm))); // Setup link openers const localFileOpener = this._instantiationService.createInstance(TerminalLocalFileLinkOpener); diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalWordLinkDetector.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalWordLinkDetector.ts index c79f6389ad0..1991ba84eac 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalWordLinkDetector.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalWordLinkDetector.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Disposable } from 'vs/base/common/lifecycle'; import { escapeRegExpCharacters } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -27,7 +28,7 @@ interface Word { text: string; } -export class TerminalWordLinkDetector implements ITerminalLinkDetector { +export class TerminalWordLinkDetector extends Disposable implements ITerminalLinkDetector { static id = 'word'; // Word links typically search the workspace so it makes sense that their maximum link length is @@ -41,12 +42,14 @@ export class TerminalWordLinkDetector implements ITerminalLinkDetector { @IConfigurationService private readonly _configurationService: IConfigurationService, @IProductService private readonly _productService: IProductService, ) { + super(); + this._refreshSeparatorCodes(); - this._configurationService.onDidChangeConfiguration(e => { + this._register(this._configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(TerminalSettingId.WordSeparators)) { this._refreshSeparatorCodes(); } - }); + })); } detect(lines: IBufferLine[], startLine: number, endLine: number): ITerminalSimpleLink[] { From ce3f06b9db174204ab5bd616b77447c32f2d8dc1 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:23:30 -0700 Subject: [PATCH 007/119] Bring local terminal reconnect changes to remote Part of #187076 --- .../terminal/browser/remoteTerminalBackend.ts | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts index fb741eebd25..7c79670a1f1 100644 --- a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts @@ -6,7 +6,7 @@ import { DeferredPromise } from 'vs/base/common/async'; import { Emitter } from 'vs/base/common/event'; import { revive } from 'vs/base/common/marshalling'; -import { PerformanceMark } from 'vs/base/common/performance'; +import { PerformanceMark, mark } from 'vs/base/common/performance'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -324,22 +324,28 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack // Revive processes if needed const serializedState = this._storageService.get(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE); const parsed = this._deserializeTerminalState(serializedState); - if (parsed) { - try { - // Note that remote terminals do not get their environment re-resolved unlike in local terminals - - await this._remoteTerminalChannel.reviveTerminalProcesses(parsed, Intl.DateTimeFormat().resolvedOptions().locale); - this._storageService.remove(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE); - // If reviving processes, send the terminal layout info back to the pty host as it - // will not have been persisted on application exit - const layoutInfo = this._storageService.get(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); - if (layoutInfo) { - await this._remoteTerminalChannel.setTerminalLayoutInfo(JSON.parse(layoutInfo)); - this._storageService.remove(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); - } - } catch { - // no-op + if (!parsed) { + return undefined; + } + + try { + // Note that remote terminals do not get their environment re-resolved unlike in local terminals + + mark('code/terminal/willReviveTerminalProcessesRemote'); + await this._remoteTerminalChannel.reviveTerminalProcesses(parsed, Intl.DateTimeFormat().resolvedOptions().locale); + mark('code/terminal/didReviveTerminalProcessesRemote'); + this._storageService.remove(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE); + // If reviving processes, send the terminal layout info back to the pty host as it + // will not have been persisted on application exit + const layoutInfo = this._storageService.get(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); + if (layoutInfo) { + mark('code/terminal/willSetTerminalLayoutInfoRemote'); + await this._remoteTerminalChannel.setTerminalLayoutInfo(JSON.parse(layoutInfo)); + mark('code/terminal/didSetTerminalLayoutInfoRemote'); + this._storageService.remove(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); } + } catch (e: unknown) { + this._logService.warn('RemoteTerminalBackend#getTerminalLayoutInfo Error', e && typeof e === 'object' && 'message' in e ? e.message : e); } return this._remoteTerminalChannel.getTerminalLayoutInfo(); From 9922b1cb8a63d87ce06729a898d0c1cb78f00e0a Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:23:57 -0700 Subject: [PATCH 008/119] Improve logging of pty host startup/reconnection --- src/vs/platform/terminal/node/ptyHostService.ts | 7 ++++++- .../workbench/contrib/terminal/browser/terminalService.ts | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index f250294c592..ea53c6c81c1 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -8,7 +8,7 @@ import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IProcessEnvironment, OperatingSystem, isWindows } from 'vs/base/common/platform'; import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ILogService, ILoggerService } from 'vs/platform/log/common/log'; +import { ILogService, ILoggerService, LogLevel } from 'vs/platform/log/common/log'; import { RemoteLoggerChannelClient } from 'vs/platform/log/common/logIpc'; import { getResolvedShellEnv } from 'vs/platform/shell/node/shellEnv'; import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/capabilities/capabilities'; @@ -139,6 +139,11 @@ export class PtyHostService extends Disposable implements IPtyService { const connection = this._ptyHostStarter.start(); const client = connection.client; + // Log a full stack trace which will tell the exact reason the pty host is starting up + if (this._logService.getLevel() === LogLevel.Trace) { + this._logService.trace('PtyHostService#_startPtyHost', new Error().stack?.replace(/^Error/, '')); + } + // Setup heartbeat service and trigger a heartbeat immediately to reset the timeouts const heartbeatService = ProxyChannel.toService(client.getChannel(TerminalIpcChannels.Heartbeat)); heartbeatService.onBeat(() => this._handleHeartbeat()); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 90152cd6a12..c09c471e5cd 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -422,7 +422,7 @@ export class TerminalService implements ITerminalService { private _setConnected() { this._connectionState = TerminalConnectionState.Connected; this._onDidChangeConnectionState.fire(); - this._logService.trace('Reconnected to terminals'); + this._logService.trace('Pty host ready to use'); } private async _reconnectToRemoteTerminals(): Promise { @@ -444,6 +444,8 @@ export class TerminalService implements ITerminalService { // now that terminals have been restored, // attach listeners to update remote when terminals are changed this._attachProcessLayoutListeners(); + + this._logService.trace('Reconnected to remote terminals'); } private async _reconnectToLocalTerminals(): Promise { @@ -462,6 +464,8 @@ export class TerminalService implements ITerminalService { // now that terminals have been restored, // attach listeners to update local state when terminals are changed this._attachProcessLayoutListeners(); + + this._logService.trace('Reconnected to local terminals'); } private _recreateTerminalGroups(layoutInfo?: ITerminalsLayoutInfo): Promise { From 592302766f50858f0bf4dbfb9ac3b832d1efb60d Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:25:05 -0700 Subject: [PATCH 009/119] Don't automatically start up pty host in remote --- src/vs/platform/terminal/node/ptyHostService.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index ea53c6c81c1..60b6f1df0a4 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -106,8 +106,6 @@ export class PtyHostService extends Disposable implements IPtyService { // capability if (this._ptyHostStarter.onBeforeWindowConnection) { Event.once(this._ptyHostStarter.onBeforeWindowConnection)(() => this._ensurePtyHost()); - } else { - this._ensurePtyHost(); } this._ptyHostStarter.onWillShutdown?.(() => this._wasQuitRequested = true); From 86a4dad4a6259fae69faaf19d2440695da66bad0 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:26:00 -0700 Subject: [PATCH 010/119] Improve name of pty host connection request --- .../terminal/electron-main/electronPtyHostStarter.ts | 6 +++--- src/vs/platform/terminal/node/ptyHost.ts | 2 +- src/vs/platform/terminal/node/ptyHostService.ts | 7 +++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts b/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts index acd36340ca8..a1599f50737 100644 --- a/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts +++ b/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts @@ -23,8 +23,8 @@ export class ElectronPtyHostStarter extends Disposable implements IPtyHostStarte private utilityProcess: UtilityProcess | undefined = undefined; - private readonly _onBeforeWindowConnection = new Emitter(); - readonly onBeforeWindowConnection = this._onBeforeWindowConnection.event; + private readonly _onRequestConnection = new Emitter(); + readonly onRequestConnection = this._onRequestConnection.event; private readonly _onWillShutdown = new Emitter(); readonly onWillShutdown = this._onWillShutdown.event; @@ -104,7 +104,7 @@ export class ElectronPtyHostStarter extends Disposable implements IPtyHostStarte } private _onWindowConnection(e: IpcMainEvent, nonce: string) { - this._onBeforeWindowConnection.fire(); + this._onRequestConnection.fire(); const port = this.utilityProcess!.connect(); diff --git a/src/vs/platform/terminal/node/ptyHost.ts b/src/vs/platform/terminal/node/ptyHost.ts index f9f7761b9e3..7c8b7318a67 100644 --- a/src/vs/platform/terminal/node/ptyHost.ts +++ b/src/vs/platform/terminal/node/ptyHost.ts @@ -14,7 +14,7 @@ export interface IPtyHostConnection { } export interface IPtyHostStarter extends IDisposable { - onBeforeWindowConnection?: Event; + onRequestConnection?: Event; onWillShutdown?: Event; /** diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index 60b6f1df0a4..78f0467bcb3 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -102,10 +102,9 @@ export class PtyHostService extends Disposable implements IPtyService { this._resolveVariablesRequestStore = this._register(new RequestStore(undefined, this._logService)); this._resolveVariablesRequestStore.onCreateRequest(this._onPtyHostRequestResolveVariables.fire, this._onPtyHostRequestResolveVariables); - // Force the pty host to start as the first window is starting if the starter has that - // capability - if (this._ptyHostStarter.onBeforeWindowConnection) { - Event.once(this._ptyHostStarter.onBeforeWindowConnection)(() => this._ensurePtyHost()); + // Start the pty host when a window requests a connection, if the starter has that capability. + if (this._ptyHostStarter.onRequestConnection) { + Event.once(this._ptyHostStarter.onRequestConnection)(() => this._ensurePtyHost()); } this._ptyHostStarter.onWillShutdown?.(() => this._wasQuitRequested = true); From 221013805985f49950b4fd2451bf22afd73548d2 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:45:57 -0700 Subject: [PATCH 011/119] . --- src/vs/platform/terminal/node/ptyHostMain.ts | 1 + src/vs/platform/terminal/node/ptyHostService.ts | 2 ++ src/vs/platform/terminal/node/terminalProcess.ts | 4 +++- .../contrib/terminal/browser/remoteTerminalBackend.ts | 1 + src/vs/workbench/contrib/terminal/browser/terminalService.ts | 2 +- .../contrib/terminal/electron-sandbox/localTerminalBackend.ts | 1 + 6 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/terminal/node/ptyHostMain.ts b/src/vs/platform/terminal/node/ptyHostMain.ts index 46763b6e0f2..cd0faa5ff20 100644 --- a/src/vs/platform/terminal/node/ptyHostMain.ts +++ b/src/vs/platform/terminal/node/ptyHostMain.ts @@ -88,6 +88,7 @@ async function startPtyHost() { // Clean up process.once('exit', () => { + logService.trace('Pty host exiting'); logService.dispose(); heartbeatService.dispose(); ptyService.dispose(); diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index 78f0467bcb3..1dd232bd80d 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -105,6 +105,8 @@ export class PtyHostService extends Disposable implements IPtyService { // Start the pty host when a window requests a connection, if the starter has that capability. if (this._ptyHostStarter.onRequestConnection) { Event.once(this._ptyHostStarter.onRequestConnection)(() => this._ensurePtyHost()); + } else { + this._ensurePtyHost(); } this._ptyHostStarter.onWillShutdown?.(() => this._wasQuitRequested = true); diff --git a/src/vs/platform/terminal/node/terminalProcess.ts b/src/vs/platform/terminal/node/terminalProcess.ts index 84fbbc9d28e..701426ba768 100644 --- a/src/vs/platform/terminal/node/terminalProcess.ts +++ b/src/vs/platform/terminal/node/terminalProcess.ts @@ -13,7 +13,7 @@ import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/co import { URI } from 'vs/base/common/uri'; import { Promises } from 'vs/base/node/pfs'; import { localize } from 'vs/nls'; -import { ILogService } from 'vs/platform/log/common/log'; +import { ILogService, LogLevel } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { FlowControlConstants, IShellLaunchConfig, ITerminalChildProcess, ITerminalLaunchError, IProcessProperty, IProcessPropertyMap as IProcessPropertyMap, ProcessPropertyType, TerminalShellType, IProcessReadyEvent, ITerminalProcessOptions, PosixShellType, IProcessReadyWindowsPty } from 'vs/platform/terminal/common/terminal'; import { ChildProcessMonitor } from 'vs/platform/terminal/node/childProcessMonitor'; @@ -353,6 +353,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess // Allow any trailing data events to be sent before the exit event is sent. // See https://github.com/Tyriar/node-pty/issues/72 private _queueProcessExit() { + this._logService.trace('TerminalProcess#_queueProcessExit', new Error().stack?.replace(/^Error/, '')); if (this._closeTimeout) { clearTimeout(this._closeTimeout); } @@ -417,6 +418,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess } shutdown(immediate: boolean): void { + this._logService.trace('TerminalProcess#shutdown', new Error().stack?.replace(/^Error/, '')); // don't force immediate disposal of the terminal processes on Windows as an additional // mitigation for https://github.com/microsoft/vscode/issues/71966 which causes the pty host // to become unresponsive, disconnecting all terminals across all windows. diff --git a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts index 7c79670a1f1..5c5c940be45 100644 --- a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts @@ -165,6 +165,7 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack } const ids = Array.from(this._ptys.keys()); const serialized = await this._remoteTerminalChannel.serializeTerminalState(ids); + this._logService.info('remote persistTerminalState serialied', serialized); this._storageService.store(TerminalStorageKeys.TerminalBufferState, serialized, StorageScope.WORKSPACE, StorageTarget.MACHINE); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index c09c471e5cd..b0e8a2c08cd 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -422,7 +422,7 @@ export class TerminalService implements ITerminalService { private _setConnected() { this._connectionState = TerminalConnectionState.Connected; this._onDidChangeConnectionState.fire(); - this._logService.trace('Pty host ready to use'); + this._logService.trace('Pty host ready'); } private async _reconnectToRemoteTerminals(): Promise { diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts index ac4c6650e8b..23f93fe7ac6 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts @@ -183,6 +183,7 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke async persistTerminalState(): Promise { const ids = Array.from(this._ptys.keys()); const serialized = await this._proxy.serializeTerminalState(ids); + this._logService.info('local persistTerminalState serialied', serialized); this._storageService.store(TerminalStorageKeys.TerminalBufferState, serialized, StorageScope.WORKSPACE, StorageTarget.MACHINE); } From 1157e96e241152529a1351fd93b33994bfb5e72d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 5 Jul 2023 22:29:34 +0200 Subject: [PATCH 012/119] adopt atomic write for userdata (#187038) * #180695 - adopt atomic write for userdata * check if fsp has atomic write * fix tests --- src/vs/code/electron-main/main.ts | 5 +++++ .../code/node/sharedProcess/sharedProcessMain.ts | 4 ++-- .../environment/common/environmentService.ts | 6 +++--- .../common/extensionsProfileScannerService.ts | 5 +++-- .../node/sharedProcessEnvironmentService.ts | 16 ---------------- .../userData/common/fileUserDataProvider.ts | 6 +++++- src/vs/server/node/serverEnvironmentService.ts | 4 ++++ .../workbench/electron-sandbox/desktop.main.ts | 3 ++- .../electron-sandbox/environmentService.ts | 3 --- 9 files changed, 24 insertions(+), 28 deletions(-) delete mode 100644 src/vs/platform/sharedProcess/node/sharedProcessEnvironmentService.ts diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 6e960fc47c7..0174a24c3c8 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -70,6 +70,7 @@ import { ILoggerMainService, LoggerMainService } from 'vs/platform/log/electron- import { LogService } from 'vs/platform/log/common/logService'; import { massageMessageBoxOptions } from 'vs/platform/dialogs/common/dialogs'; import { SaveStrategy, StateService } from 'vs/platform/state/node/stateService'; +import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider'; /** * The main VS Code entry point. @@ -178,6 +179,10 @@ class CodeMain { const diskFileSystemProvider = new DiskFileSystemProvider(logService); fileService.registerProvider(Schemas.file, diskFileSystemProvider); + // Use FileUserDataProvider for user data to + // enable atomic read / write operations. + fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, logService)); + // URI Identity const uriIdentityService = new UriIdentityService(fileService); services.set(IUriIdentityService, uriIdentityService); diff --git a/src/vs/code/node/sharedProcess/sharedProcessMain.ts b/src/vs/code/node/sharedProcess/sharedProcessMain.ts index 28053c1cdd6..d8b6d791e74 100644 --- a/src/vs/code/node/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/node/sharedProcess/sharedProcessMain.ts @@ -26,7 +26,6 @@ import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsServ import { IDownloadService } from 'vs/platform/download/common/download'; import { DownloadService } from 'vs/platform/download/common/downloadService'; import { INativeEnvironmentService } from 'vs/platform/environment/common/environment'; -import { SharedProcessEnvironmentService } from 'vs/platform/sharedProcess/node/sharedProcessEnvironmentService'; import { GlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -112,6 +111,7 @@ import { RemoteStorageService } from 'vs/platform/storage/common/storageService' import { IRemoteSocketFactoryService, RemoteSocketFactoryService } from 'vs/platform/remote/common/remoteSocketFactoryService'; import { RemoteConnectionType } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory'; +import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService'; class SharedProcessMain extends Disposable { @@ -191,7 +191,7 @@ class SharedProcessMain extends Disposable { services.set(IPolicyService, policyService); // Environment - const environmentService = new SharedProcessEnvironmentService(this.configuration.args, productService); + const environmentService = new NativeEnvironmentService(this.configuration.args, productService); services.set(INativeEnvironmentService, environmentService); // Logger diff --git a/src/vs/platform/environment/common/environmentService.ts b/src/vs/platform/environment/common/environmentService.ts index 7f2e8e93b3e..78eccd30b05 100644 --- a/src/vs/platform/environment/common/environmentService.ts +++ b/src/vs/platform/environment/common/environmentService.ts @@ -5,7 +5,7 @@ import { toLocalISOString } from 'vs/base/common/date'; import { memoize } from 'vs/base/common/decorators'; -import { FileAccess } from 'vs/base/common/network'; +import { FileAccess, Schemas } from 'vs/base/common/network'; import { dirname, join, normalize, resolve } from 'vs/base/common/path'; import { env } from 'vs/base/common/process'; import { joinPath } from 'vs/base/common/resources'; @@ -65,10 +65,10 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron get stateResource(): URI { return joinPath(this.appSettingsHome, 'globalStorage', 'storage.json'); } @memoize - get userRoamingDataHome(): URI { return this.appSettingsHome; } + get userRoamingDataHome(): URI { return this.appSettingsHome.with({ scheme: Schemas.vscodeUserData }); } @memoize - get userDataSyncHome(): URI { return joinPath(this.userRoamingDataHome, 'sync'); } + get userDataSyncHome(): URI { return joinPath(this.appSettingsHome, 'sync'); } get logsHome(): URI { if (!this.args.logsPath) { diff --git a/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts b/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts index 30e749ac312..925b9dd905c 100644 --- a/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts +++ b/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts @@ -12,7 +12,7 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import { Metadata, isIExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IExtension, IExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -import { FileOperationResult, IFileService, toFileOperationResult } from 'vs/platform/files/common/files'; +import { FileOperationResult, IFileService, hasFileAtomicWriteCapability, toFileOperationResult } from 'vs/platform/files/common/files'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; @@ -290,7 +290,8 @@ export abstract class AbstractExtensionsProfileScannerService extends Disposable relativeLocation: this.toRelativePath(e.location), metadata: e.metadata })); - await this.fileService.writeFile(file, VSBuffer.fromString(JSON.stringify(storedProfileExtensions))); + const fsp = this.fileService.getProvider(file.scheme); + await this.fileService.writeFile(file, VSBuffer.fromString(JSON.stringify(storedProfileExtensions)), fsp && hasFileAtomicWriteCapability(fsp) ? { atomic: { postfix: '.vsctmp' } } : undefined); } return extensions; diff --git a/src/vs/platform/sharedProcess/node/sharedProcessEnvironmentService.ts b/src/vs/platform/sharedProcess/node/sharedProcessEnvironmentService.ts deleted file mode 100644 index 7cb9f0d402f..00000000000 --- a/src/vs/platform/sharedProcess/node/sharedProcessEnvironmentService.ts +++ /dev/null @@ -1,16 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { memoize } from 'vs/base/common/decorators'; -import { Schemas } from 'vs/base/common/network'; -import { URI } from 'vs/base/common/uri'; -import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService'; - -export class SharedProcessEnvironmentService extends NativeEnvironmentService { - - @memoize - override get userRoamingDataHome(): URI { return this.appSettingsHome.with({ scheme: Schemas.vscodeUserData }); } - -} diff --git a/src/vs/platform/userData/common/fileUserDataProvider.ts b/src/vs/platform/userData/common/fileUserDataProvider.ts index 539c8011f3e..9382a676acb 100644 --- a/src/vs/platform/userData/common/fileUserDataProvider.ts +++ b/src/vs/platform/userData/common/fileUserDataProvider.ts @@ -4,13 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import { Event, Emitter } from 'vs/base/common/event'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, IFileOverwriteOptions, FileType, IFileWriteOptions, IFileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileFolderCopyCapability, hasFileFolderCopyCapability } from 'vs/platform/files/common/files'; +import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, IFileOverwriteOptions, FileType, IFileWriteOptions, IFileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileFolderCopyCapability, hasFileFolderCopyCapability, hasFileAtomicWriteCapability } from 'vs/platform/files/common/files'; import { URI } from 'vs/base/common/uri'; import { CancellationToken } from 'vs/base/common/cancellation'; import { newWriteableStream, ReadableStreamEvents } from 'vs/base/common/stream'; import { ILogService } from 'vs/platform/log/common/log'; import { TernarySearchTree } from 'vs/base/common/ternarySearchTree'; import { VSBuffer } from 'vs/base/common/buffer'; +import { isObject } from 'vs/base/common/types'; /** * This is a wrapper on top of the local filesystem provider which will @@ -85,6 +86,9 @@ export class FileUserDataProvider extends Disposable implements } writeFile(resource: URI, content: Uint8Array, opts: IFileWriteOptions): Promise { + if (!isObject(opts.atomic) && hasFileAtomicWriteCapability(this.fileSystemProvider)) { + opts = { ...opts, atomic: { postfix: '.vsctmp' } }; + } return this.fileSystemProvider.writeFile(this.toFileSystemResource(resource), content, opts); } diff --git a/src/vs/server/node/serverEnvironmentService.ts b/src/vs/server/node/serverEnvironmentService.ts index ea6cb346184..e3742efaa51 100644 --- a/src/vs/server/node/serverEnvironmentService.ts +++ b/src/vs/server/node/serverEnvironmentService.ts @@ -9,6 +9,8 @@ import { NativeEnvironmentService } from 'vs/platform/environment/node/environme import { OPTIONS, OptionDescriptions } from 'vs/platform/environment/node/argv'; import { refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment'; +import { memoize } from 'vs/base/common/decorators'; +import { URI } from 'vs/base/common/uri'; export const serverOptions: OptionDescriptions> = { @@ -211,5 +213,7 @@ export interface IServerEnvironmentService extends INativeEnvironmentService { } export class ServerEnvironmentService extends NativeEnvironmentService implements IServerEnvironmentService { + @memoize + override get userRoamingDataHome(): URI { return this.appSettingsHome; } override get args(): ServerParsedArgs { return super.args as ServerParsedArgs; } } diff --git a/src/vs/workbench/electron-sandbox/desktop.main.ts b/src/vs/workbench/electron-sandbox/desktop.main.ts index 87db0ff9fc1..9609e5f96bb 100644 --- a/src/vs/workbench/electron-sandbox/desktop.main.ts +++ b/src/vs/workbench/electron-sandbox/desktop.main.ts @@ -224,7 +224,8 @@ export class DesktopMain extends Disposable { const diskFileSystemProvider = this._register(new DiskFileSystemProvider(mainProcessService, utilityProcessWorkerWorkbenchService, logService)); fileService.registerProvider(Schemas.file, diskFileSystemProvider); - // User Data Provider + // Use FileUserDataProvider for user data to + // enable atomic read / write operations. fileService.registerProvider(Schemas.vscodeUserData, this._register(new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, logService))); // URI Identity diff --git a/src/vs/workbench/services/environment/electron-sandbox/environmentService.ts b/src/vs/workbench/services/environment/electron-sandbox/environmentService.ts index 810a38b3866..26fedfa0219 100644 --- a/src/vs/workbench/services/environment/electron-sandbox/environmentService.ts +++ b/src/vs/workbench/services/environment/electron-sandbox/environmentService.ts @@ -84,9 +84,6 @@ export class NativeWorkbenchEnvironmentService extends AbstractNativeEnvironment }; } - @memoize - override get userRoamingDataHome(): URI { return this.appSettingsHome.with({ scheme: Schemas.vscodeUserData }); } - @memoize get windowLogsPath(): URI { return joinPath(this.logsHome, `window${this.configuration.windowId}`); } From 075cf4ac2b2b56511af2e4eefe8d946e144245b3 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 5 Jul 2023 13:38:53 -0700 Subject: [PATCH 013/119] getWorkspaceTasks --- .../contrib/tasks/browser/abstractTaskService.ts | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 3ca656e61ab..979b207b9e5 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -2201,9 +2201,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } await this._waitForSupportedExecutions; await this._whenTaskSystemReady; - if (this._workspaceTasksPromise) { - return this._workspaceTasksPromise; - } return this._updateWorkspaceTasks(runSource); } @@ -2748,16 +2745,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return true; } - private async _ensureWorkspaceTasks(): Promise { - if (!this._workspaceTasksPromise) { - await this.getWorkspaceTasks(); - } else { - await this._workspaceTasksPromise; - } - } - private async _runTaskCommand(filter?: string | ITaskIdentifier): Promise { - await this._ensureWorkspaceTasks(); + await this.getWorkspaceTasks(); if (!filter) { return this._doRunTaskCommand(); } @@ -2915,7 +2904,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer title: strings.fetching }; const promise = (async () => { - await this._ensureWorkspaceTasks(); + await this.getWorkspaceTasks(); let taskGroupTasks: (Task | ConfiguringTask)[] = []; async function runSingleTask(task: Task | undefined, problemMatcherOptions: IProblemMatcherRunOptions | undefined, that: AbstractTaskService) { From 0c3fb42a1e31f63ec7f17906a19bbcebdbe8bb3e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 5 Jul 2023 13:46:59 -0700 Subject: [PATCH 014/119] Disable seamless relaunch on Windows/remote/ConPTY The fast process spawn, kill, spawn was causing problems on remotes Fixes #187084 --- .../platform/terminal/node/terminalProcess.ts | 2 +- .../terminal/browser/terminalInstance.ts | 21 +++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/vs/platform/terminal/node/terminalProcess.ts b/src/vs/platform/terminal/node/terminalProcess.ts index 701426ba768..c3bd57c1562 100644 --- a/src/vs/platform/terminal/node/terminalProcess.ts +++ b/src/vs/platform/terminal/node/terminalProcess.ts @@ -13,7 +13,7 @@ import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/co import { URI } from 'vs/base/common/uri'; import { Promises } from 'vs/base/node/pfs'; import { localize } from 'vs/nls'; -import { ILogService, LogLevel } from 'vs/platform/log/common/log'; +import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { FlowControlConstants, IShellLaunchConfig, ITerminalChildProcess, ITerminalLaunchError, IProcessProperty, IProcessPropertyMap as IProcessPropertyMap, ProcessPropertyType, TerminalShellType, IProcessReadyEvent, ITerminalProcessOptions, PosixShellType, IProcessReadyWindowsPty } from 'vs/platform/terminal/common/terminal'; import { ChildProcessMonitor } from 'vs/platform/terminal/node/childProcessMonitor'; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 4f2ca596f77..9ecf7d39c00 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -2080,7 +2080,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._refreshEnvironmentVariableInfoWidgetState(info); } - private _refreshEnvironmentVariableInfoWidgetState(info?: IEnvironmentVariableInfo): void { + private async _refreshEnvironmentVariableInfoWidgetState(info?: IEnvironmentVariableInfo): Promise { // Check if the status should exist if (!info) { this.statusList.remove(TerminalStatus.RelaunchNeeded); @@ -2088,16 +2088,25 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { return; } - // Recreate the process if the terminal has not yet been interacted with and it's not a - // special terminal (eg. extension terminal) + // Recreate the process seamlessly without informing the use if the following conditions are + // met. if ( + // The change requires a relaunch info.requiresAction && + // The feature is enabled this._configHelper.config.environmentChangesRelaunch && + // Has not been interacted with !this._processManager.hasWrittenData && + // Not a feature terminal or is a reconnecting task terminal (TODO: Need to explain the latter case) (!this._shellLaunchConfig.isFeatureTerminal || (this.reconnectionProperties && this._configurationService.getValue(TaskSettingId.Reconnection) === true)) && - !this._shellLaunchConfig.customPtyImplementation - && !this._shellLaunchConfig.isExtensionOwnedTerminal && - !this._shellLaunchConfig.attachPersistentProcess + // Not a custom pty + !this._shellLaunchConfig.customPtyImplementation && + // Not an extension owned terminal + !this._shellLaunchConfig.isExtensionOwnedTerminal && + // Not a reconnected or revived terminal + !this._shellLaunchConfig.attachPersistentProcess && + // Not a Windows remote using ConPTY (#187084) + !(this._processManager.remoteAuthority && this._configHelper.config.windowsEnableConpty && (await this._processManager.getBackendOS()) === OperatingSystem.Windows) ) { this.relaunch(); return; From 55d8d97b45cb0aac78cd5d0ad9e7a9838a4af45d Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 5 Jul 2023 14:06:38 -0700 Subject: [PATCH 015/119] testing: fix default size of inline peek diff (#187072) * testing: fix default size of inline peek diff Fixes #185331 * rm unused import --- .../testing/browser/testingOutputPeek.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts index bc522e678f9..761d9c4319c 100644 --- a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts +++ b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts @@ -26,7 +26,6 @@ import { Iterable } from 'vs/base/common/iterator'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Lazy } from 'vs/base/common/lazy'; import { Disposable, DisposableStore, IDisposable, IReference, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { clamp } from 'vs/base/common/numbers'; import { count } from 'vs/base/common/strings'; import { ThemeIcon } from 'vs/base/common/themables'; import { URI } from 'vs/base/common/uri'; @@ -520,8 +519,8 @@ export class TestingOutputPeekController extends Disposable implements IEditorCo * Shows a peek for the message in the editor. */ public async show(uri: URI) { - const subjecet = this.retrieveTest(uri); - if (!subjecet) { + const subject = this.retrieveTest(uri); + if (!subject) { return; } @@ -537,12 +536,12 @@ export class TestingOutputPeekController extends Disposable implements IEditorCo this.peek.value!.create(); } - if (subjecet instanceof MessageSubject) { - const message = subjecet.messages[subjecet.messageIndex]; + if (subject instanceof MessageSubject) { + const message = subject.messages[subject.messageIndex]; alert(renderStringAsPlaintext(message.message)); } - this.peek.value.setModel(subjecet); + this.peek.value.setModel(subject); this.currentPeekUri = uri; } @@ -1022,7 +1021,7 @@ const diffEditorOptions: IDiffEditorConstructionOptions = { diffAlgorithm: 'advanced', }; -const isDiffable = (message: ITestMessage): message is ITestErrorMessage & { actualOutput: string; expectedOutput: string } => +const isDiffable = (message: ITestMessage): message is ITestErrorMessage & { actual: string; expected: string } => message.type === TestMessageType.Error && message.actual !== undefined && message.expected !== undefined; class DiffContentProvider extends Disposable implements IPeekOutputRenderer { @@ -1381,8 +1380,9 @@ const firstLine = (str: string) => { }; const isMultiline = (str: string | undefined) => !!str && str.includes('\n'); -const hintPeekStrHeight = (str: string | undefined) => - clamp(str ? Math.max(count(str, '\n'), Math.ceil(str.length / 80)) + 3 : 0, 14, 24); + +// add 5ish lines for the size of the title and decorations in the peek. +const hintPeekStrHeight = (str: string) => Math.min(count(str, '\n') + 5, 24); class SimpleDiffEditorModel extends EditorModel { public readonly original = this._original.object.textEditorModel; From 406d3d5cf5488bacec8c7f97fd91b385e1d4b42f Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Wed, 5 Jul 2023 14:08:37 -0700 Subject: [PATCH 016/119] fix #186651 -- notebook action tab border only on icon, not label (#187085) fix #186651 --- .../notebook/browser/media/notebookToolbar.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/vs/workbench/contrib/notebook/browser/media/notebookToolbar.css b/src/vs/workbench/contrib/notebook/browser/media/notebookToolbar.css index 53505527259..28ea1557a52 100644 --- a/src/vs/workbench/contrib/notebook/browser/media/notebookToolbar.css +++ b/src/vs/workbench/contrib/notebook/browser/media/notebookToolbar.css @@ -40,6 +40,18 @@ height: 22px; } +.monaco-workbench .notebookOverlay .notebook-toolbar-container .notebook-toolbar-left .monaco-action-bar li a[tabindex="0"]:focus { + outline: none !important; +} + +.monaco-workbench .notebookOverlay .notebook-toolbar-container .notebook-toolbar-left .monaco-action-bar li:has(a:focus) { + outline-width: 1px; + outline-style: solid; + outline-offset: -1px; + outline-color: var(--vscode-focusBorder); + opacity: 1; +} + .monaco-workbench .notebookOverlay .notebook-toolbar-container .notebook-toolbar-left .monaco-action-bar .action-item .action-label.separator { margin: 5px 0px !important; padding: 0px !important; From 72fb36496cde044d0334b3f2015565417efb0b88 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:10:18 -0700 Subject: [PATCH 017/119] Fix pty host lazy spawning Fixes #187076 --- .../platform/terminal/node/ptyHostService.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index 1dd232bd80d..ad7dd4be94d 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -43,6 +43,13 @@ export class PtyHostService extends Disposable implements IPtyService { this._ensurePtyHost(); return this.__proxy!; } + /** + * Get the proxy if it exists, otherwise undefined. This is used when calls are not needed to be + * passed through to the pty host if it has not yet been spawned. + */ + private get _optionalProxy(): IPtyService | undefined { + return this.__proxy; + } private _ensurePtyHost() { if (!this.__connection) { @@ -105,8 +112,6 @@ export class PtyHostService extends Disposable implements IPtyService { // Start the pty host when a window requests a connection, if the starter has that capability. if (this._ptyHostStarter.onRequestConnection) { Event.once(this._ptyHostStarter.onRequestConnection)(() => this._ensurePtyHost()); - } else { - this._ensurePtyHost(); } this._ptyHostStarter.onWillShutdown?.(() => this._wasQuitRequested = true); @@ -228,13 +233,10 @@ export class PtyHostService extends Disposable implements IPtyService { return this._proxy.listProcesses(); } async getPerformanceMarks(): Promise { - if (!this.__proxy) { - return []; - } - return this._proxy.getPerformanceMarks(); + return this._optionalProxy?.getPerformanceMarks() ?? []; } - reduceConnectionGraceTime(): Promise { - return this._proxy.reduceConnectionGraceTime(); + async reduceConnectionGraceTime(): Promise { + return this._optionalProxy?.reduceConnectionGraceTime(); } start(id: number): Promise { return this._proxy.start(id); From b540ba7b277b27f2481ba2a9dbf380019d4cffdd Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:11:27 -0700 Subject: [PATCH 018/119] Unexpected link highlighting in search editor (#187091) Fixes #180813 --- extensions/search-result/src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/search-result/src/extension.ts b/extensions/search-result/src/extension.ts index 90443f16771..815bd8c1391 100644 --- a/extensions/search-result/src/extension.ts +++ b/extensions/search-result/src/extension.ts @@ -78,7 +78,7 @@ export function activate(context: vscode.ExtensionContext) { const lineResult = parseSearchResults(document, token)[position.line]; if (!lineResult) { return []; } if (lineResult.type === 'file') { - return lineResult.allLocations; + return lineResult.allLocations.map(l => ({ ...l, originSelectionRange: lineResult.location.originSelectionRange })); } const location = lineResult.locations.find(l => l.originSelectionRange.contains(position)); From f409c06e471383b382ac7501c895adb7752d4ab5 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:12:48 -0700 Subject: [PATCH 019/119] Clean up trace logs --- src/vs/platform/terminal/node/terminalProcess.ts | 10 +++++++--- .../contrib/terminal/browser/remoteTerminalBackend.ts | 1 - .../terminal/electron-sandbox/localTerminalBackend.ts | 1 - 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/platform/terminal/node/terminalProcess.ts b/src/vs/platform/terminal/node/terminalProcess.ts index c3bd57c1562..467007e8728 100644 --- a/src/vs/platform/terminal/node/terminalProcess.ts +++ b/src/vs/platform/terminal/node/terminalProcess.ts @@ -13,7 +13,7 @@ import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/co import { URI } from 'vs/base/common/uri'; import { Promises } from 'vs/base/node/pfs'; import { localize } from 'vs/nls'; -import { ILogService } from 'vs/platform/log/common/log'; +import { ILogService, LogLevel } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { FlowControlConstants, IShellLaunchConfig, ITerminalChildProcess, ITerminalLaunchError, IProcessProperty, IProcessPropertyMap as IProcessPropertyMap, ProcessPropertyType, TerminalShellType, IProcessReadyEvent, ITerminalProcessOptions, PosixShellType, IProcessReadyWindowsPty } from 'vs/platform/terminal/common/terminal'; import { ChildProcessMonitor } from 'vs/platform/terminal/node/childProcessMonitor'; @@ -353,7 +353,9 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess // Allow any trailing data events to be sent before the exit event is sent. // See https://github.com/Tyriar/node-pty/issues/72 private _queueProcessExit() { - this._logService.trace('TerminalProcess#_queueProcessExit', new Error().stack?.replace(/^Error/, '')); + if (this._logService.getLevel() === LogLevel.Trace) { + this._logService.trace('TerminalProcess#_queueProcessExit', new Error().stack?.replace(/^Error/, '')); + } if (this._closeTimeout) { clearTimeout(this._closeTimeout); } @@ -418,7 +420,9 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess } shutdown(immediate: boolean): void { - this._logService.trace('TerminalProcess#shutdown', new Error().stack?.replace(/^Error/, '')); + if (this._logService.getLevel() === LogLevel.Trace) { + this._logService.trace('TerminalProcess#shutdown', new Error().stack?.replace(/^Error/, '')); + } // don't force immediate disposal of the terminal processes on Windows as an additional // mitigation for https://github.com/microsoft/vscode/issues/71966 which causes the pty host // to become unresponsive, disconnecting all terminals across all windows. diff --git a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts index 5c5c940be45..7c79670a1f1 100644 --- a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts @@ -165,7 +165,6 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack } const ids = Array.from(this._ptys.keys()); const serialized = await this._remoteTerminalChannel.serializeTerminalState(ids); - this._logService.info('remote persistTerminalState serialied', serialized); this._storageService.store(TerminalStorageKeys.TerminalBufferState, serialized, StorageScope.WORKSPACE, StorageTarget.MACHINE); } diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts index 23f93fe7ac6..ac4c6650e8b 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts @@ -183,7 +183,6 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke async persistTerminalState(): Promise { const ids = Array.from(this._ptys.keys()); const serialized = await this._proxy.serializeTerminalState(ids); - this._logService.info('local persistTerminalState serialied', serialized); this._storageService.store(TerminalStorageKeys.TerminalBufferState, serialized, StorageScope.WORKSPACE, StorageTarget.MACHINE); } From 3d6d83950e6acabe71ca8a561ca5dc7e04efa7ec Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:15:59 -0700 Subject: [PATCH 020/119] Don't spawn pty host on getDefaultSystemShell or refreshIgnoreProcessNames --- src/vs/platform/terminal/node/ptyHostService.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index ad7dd4be94d..ecd550e3826 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -5,7 +5,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IProcessEnvironment, OperatingSystem, isWindows } from 'vs/base/common/platform'; +import { IProcessEnvironment, OS, OperatingSystem, isWindows } from 'vs/base/common/platform'; import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService, ILoggerService, LogLevel } from 'vs/platform/log/common/log'; @@ -19,6 +19,7 @@ import { IGetTerminalLayoutInfoArgs, IProcessDetails, ISetTerminalLayoutInfoArgs import { IPtyHostConnection, IPtyHostStarter } from 'vs/platform/terminal/node/ptyHost'; import { detectAvailableProfiles } from 'vs/platform/terminal/node/terminalProfiles'; import * as performance from 'vs/base/common/performance'; +import { getSystemShell } from 'vs/base/node/shell'; enum Constants { MaxRestarts = 5 @@ -122,7 +123,7 @@ export class PtyHostService extends Disposable implements IPtyService { } private async _refreshIgnoreProcessNames(): Promise { - return this._proxy.refreshIgnoreProcessNames?.(this._ignoreProcessNames); + return this._optionalProxy?.refreshIgnoreProcessNames?.(this._ignoreProcessNames); } private async _resolveShellEnv(): Promise { @@ -286,7 +287,7 @@ export class PtyHostService extends Disposable implements IPtyService { } getDefaultSystemShell(osOverride?: OperatingSystem): Promise { - return this._proxy.getDefaultSystemShell(osOverride); + return this._optionalProxy?.getDefaultSystemShell(osOverride) ?? getSystemShell(osOverride ?? OS, process.env); } async getProfiles(workspaceId: string, profiles: unknown, defaultProfile: unknown, includeDetectedProfiles: boolean = false): Promise { const shellEnv = await this._resolveShellEnv(); From 26a45ba4d3ba4f89f61ef94747857bc5cc1e6967 Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:31:37 -0700 Subject: [PATCH 021/119] fix: adjust widget overflow styling (#186951) Fixes microsoft/vscode-pull-request-github#4973 --- .../contrib/preferences/browser/media/settingsWidgets.css | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css index 31d9112df2f..a77fedea1d9 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css @@ -18,9 +18,8 @@ .settings-editor > .settings-body .settings-tree-container .setting-item.setting-item-list .setting-list-sibling, .settings-editor > .settings-body .settings-tree-container .setting-item.setting-item-list .setting-list-object-widget .setting-list-object-key, .settings-editor > .settings-body .settings-tree-container .setting-item.setting-item-list .setting-list-object-widget .setting-list-object-value { - white-space: pre; - overflow: hidden; - text-overflow: ellipsis; + white-space: normal; + overflow-wrap: normal; } .settings-editor > .settings-body .settings-tree-container .setting-item-bool .setting-value-checkbox { From 753fdf84207db7023f197c84c52bbfed03350099 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 5 Jul 2023 14:34:38 -0700 Subject: [PATCH 022/119] testing: fix inconsistent action name (#187098) Fixes #186370 --- src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts index 761d9c4319c..9d737a61184 100644 --- a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts +++ b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts @@ -2002,7 +2002,7 @@ class TreeActionsProvider { const extId = element.test.item.extId; primary.push(new Action( 'testing.outputPeek.goToFile', - localize('testing.goToFile', "Go to File"), + localize('testing.goToFile', "Go to Source"), ThemeIcon.asClassName(Codicon.goToFile), undefined, () => this.commandService.executeCommand('vscode.revealTest', extId), From 856bc1e28de12896333edefe113b0311353d6d61 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 5 Jul 2023 14:38:29 -0700 Subject: [PATCH 023/119] testing: property make double click go to test (#187099) Fixes #183835 --- .../workbench/contrib/testing/browser/testingExplorerView.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts index 2db684d11a5..9b7feea3e14 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts @@ -566,7 +566,8 @@ class TestingExplorerViewModel extends Disposable { keyboardNavigationLabelProvider: instantiationService.createInstance(TreeKeyboardNavigationLabelProvider), accessibilityProvider: instantiationService.createInstance(ListAccessibilityProvider), filter: this.filter, - findWidgetEnabled: false + findWidgetEnabled: false, + openOnSingleClick: false, }) as TestingObjectTree; @@ -612,7 +613,7 @@ class TestingExplorerViewModel extends Disposable { testService.excluded.onTestExclusionsChanged, )(this.tree.refilter, this.tree)); - this._register(this.tree.onMouseDblClick(e => { + this._register(this.tree.onDidOpen(e => { if (e.element instanceof TestItemTreeElement && !e.element.children.size && e.element.test.item.uri) { commandService.executeCommand('vscode.revealTest', e.element.test.item.extId); } From c7d219b53f5e602f27d36dc1676709f5e49ab2c2 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 5 Jul 2023 14:55:10 -0700 Subject: [PATCH 024/119] testing: make running tests open the results view instead of explorer (#187100) Closes #153068 --- .../contrib/testing/browser/testingProgressUiService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/testing/browser/testingProgressUiService.ts b/src/vs/workbench/contrib/testing/browser/testingProgressUiService.ts index a3ffe5863c2..63a83e504dc 100644 --- a/src/vs/workbench/contrib/testing/browser/testingProgressUiService.ts +++ b/src/vs/workbench/contrib/testing/browser/testingProgressUiService.ts @@ -82,7 +82,7 @@ export class TestingProgressTrigger extends Disposable { } private openTestView() { - this.viewsService.openView(Testing.ExplorerViewId, false); + this.viewsService.openView(Testing.ResultsViewId, false); } } From 322bc2d7d86e8d0c2ccb1bfdabe594e2011d500f Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 5 Jul 2023 15:09:01 -0700 Subject: [PATCH 025/119] Have getCurrentAuthenticationSessionInfo take in a secretStorageService (#187092) To start the migration process, we have `getCurrentAuthenticationSessionInfo` take in a `secretStorageService` and also replaces the `LocalStorageCredentialProvider` with a `LocalStorageSecretStorageProvider`. After this goes in we can then update all embedders (vscode.dev, github.dev, Codespaces, vscode-web-test?) and replace ICredentialProvider usages with ISecretStorageProviders and then once we do that, we can get rid of a bunch of code! --- src/vs/code/browser/workbench/workbench.ts | 169 ++++-------------- .../parts/activitybar/activitybarActions.ts | 4 +- src/vs/workbench/browser/web.main.ts | 11 +- .../browser/editSessionsStorageService.ts | 4 +- .../browser/authenticationService.ts | 16 +- .../secrets/browser/secretStorageService.ts | 4 - .../userDataSync/browser/userDataSyncInit.ts | 4 +- .../browser/userDataSyncWorkbenchService.ts | 4 +- 8 files changed, 71 insertions(+), 145 deletions(-) diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts index 62a0406d7f5..3ceea02d892 100644 --- a/src/vs/code/browser/workbench/workbench.ts +++ b/src/vs/code/browser/workbench/workbench.ts @@ -4,38 +4,32 @@ *--------------------------------------------------------------------------------------------*/ import { isStandalone } from 'vs/base/browser/browser'; -import { CancellationToken } from 'vs/base/common/cancellation'; import { parse } from 'vs/base/common/marshalling'; import { Emitter } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; import { isEqual } from 'vs/base/common/resources'; import { URI, UriComponents } from 'vs/base/common/uri'; -import { request } from 'vs/base/parts/request/browser/request'; import product from 'vs/platform/product/common/product'; import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/window/common/window'; import { create } from 'vs/workbench/workbench.web.main'; import { posix } from 'vs/base/common/path'; import { ltrim } from 'vs/base/common/strings'; -import type { ICredentialsProvider } from 'vs/platform/credentials/common/credentials'; import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService'; import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api'; import type { IWorkspace, IWorkspaceProvider } from 'vs/workbench/services/host/browser/browserHostService'; +import { ISecretStorageProvider } from 'vs/platform/secrets/common/secrets'; +import { AuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService'; -interface ICredential { - service: string; - account: string; - password: string; -} - -class LocalStorageCredentialsProvider implements ICredentialsProvider { +class LocalStorageSecretStorageProvider implements ISecretStorageProvider { + private static readonly STORAGE_KEY = 'secrets.provider'; - private static readonly CREDENTIALS_STORAGE_KEY = 'credentials.provider'; + private _secrets: Record | undefined; - private readonly authService: string | undefined; + type: 'in-memory' | 'persisted' | 'unknown' = 'persisted'; constructor() { - let authSessionInfo: { readonly id: string; readonly accessToken: string; readonly providerId: string; readonly canSignOut?: boolean; readonly scopes: string[][] } | undefined; + let authSessionInfo: (AuthenticationSessionInfo & { scopes: string[][] }) | undefined; const authSessionElement = document.getElementById('vscode-workbench-auth-session'); const authSessionElementAttribute = authSessionElement ? authSessionElement.getAttribute('data-settings') : undefined; if (authSessionElementAttribute) { @@ -46,11 +40,15 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider { if (authSessionInfo) { // Settings Sync Entry - this.setPassword(`${product.urlProtocol}.login`, 'account', JSON.stringify(authSessionInfo)); + this.set(`${product.urlProtocol}.loginAccount`, JSON.stringify(authSessionInfo)); // Auth extension Entry - this.authService = `${product.urlProtocol}-${authSessionInfo.providerId}.login`; - this.setPassword(this.authService, 'account', JSON.stringify(authSessionInfo.scopes.map(scopes => ({ + if (authSessionInfo.providerId !== 'github') { + console.error(`Unexpected auth provider: ${authSessionInfo.providerId}. Expected 'github'.`); + return; + } + const authAccount = JSON.stringify({ extensionId: 'vscode.github-authentication', key: 'github.auth' }); + this.set(authAccount, JSON.stringify(authSessionInfo.scopes.map(scopes => ({ id: authSessionInfo!.id, scopes, accessToken: authSessionInfo!.accessToken @@ -58,121 +56,44 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider { } } - private _credentials: ICredential[] | undefined; - private get credentials(): ICredential[] { - if (!this._credentials) { - try { - const serializedCredentials = window.localStorage.getItem(LocalStorageCredentialsProvider.CREDENTIALS_STORAGE_KEY); - if (serializedCredentials) { - this._credentials = JSON.parse(serializedCredentials); - } - } catch (error) { - // ignore - } - - if (!Array.isArray(this._credentials)) { - this._credentials = []; - } - } - - return this._credentials; - } - - private save(): void { - window.localStorage.setItem(LocalStorageCredentialsProvider.CREDENTIALS_STORAGE_KEY, JSON.stringify(this.credentials)); - } - - async getPassword(service: string, account: string): Promise { - return this.doGetPassword(service, account); + get(key: string): Promise { + return Promise.resolve(this.secrets[key]); } + set(key: string, value: string): Promise { + this.secrets[key] = value; + this.save(); - private async doGetPassword(service: string, account?: string): Promise { - for (const credential of this.credentials) { - if (credential.service === service) { - if (typeof account !== 'string' || account === credential.account) { - return credential.password; - } - } - } - - return null; + return Promise.resolve(); } - - async setPassword(service: string, account: string, password: string): Promise { - this.doDeletePassword(service, account); - - this.credentials.push({ service, account, password }); + async delete(key: string): Promise { + delete this.secrets[key]; this.save(); - try { - if (password && service === this.authService) { - const value = JSON.parse(password); - if (Array.isArray(value) && value.length === 0) { - await this.logout(service); - } - } - } catch (error) { - console.log(error); - } + return Promise.resolve(); } - async deletePassword(service: string, account: string): Promise { - const result = await this.doDeletePassword(service, account); - - if (result && service === this.authService) { + private get secrets(): Record { + if (!this._secrets) { try { - await this.logout(service); + const serializedCredentials = window.localStorage.getItem(LocalStorageSecretStorageProvider.STORAGE_KEY); + if (serializedCredentials) { + this._secrets = JSON.parse(serializedCredentials); + } } catch (error) { - console.log(error); + // ignore } - } - - return result; - } - private async doDeletePassword(service: string, account: string): Promise { - let found = false; - - this._credentials = this.credentials.filter(credential => { - if (credential.service === service && credential.account === account) { - found = true; - - return false; + if (!(this._secrets instanceof Object)) { + this._secrets = {}; } - - return true; - }); - - if (found) { - this.save(); } - return found; - } - - async findPassword(service: string): Promise { - return this.doGetPassword(service); + return this._secrets; } - async findCredentials(service: string): Promise> { - return this.credentials - .filter(credential => credential.service === service) - .map(({ account, password }) => ({ account, password })); - } - - private async logout(service: string): Promise { - const queryValues: Map = new Map(); - queryValues.set('logout', String(true)); - queryValues.set('service', service); - - await request({ - url: doCreateUri('/auth/logout', queryValues).toString(true) - }, CancellationToken.None); - } - - async clear(): Promise { - window.localStorage.removeItem(LocalStorageCredentialsProvider.CREDENTIALS_STORAGE_KEY); + private save(): void { + window.localStorage.setItem(LocalStorageSecretStorageProvider.STORAGE_KEY, JSON.stringify(this.secrets)); } } @@ -469,24 +390,6 @@ class WorkspaceProvider implements IWorkspaceProvider { } } -function doCreateUri(path: string, queryValues: Map): URI { - let query: string | undefined = undefined; - - if (queryValues) { - let index = 0; - queryValues.forEach((value, key) => { - if (!query) { - query = ''; - } - - const prefix = (index++ === 0) ? '' : '&'; - query += `${prefix}${key}=${encodeURIComponent(value)}`; - }); - } - - return URI.parse(window.location.href).with({ path, query }); -} - (function () { // Find config by checking for DOM @@ -504,6 +407,6 @@ function doCreateUri(path: string, queryValues: Map): URI { settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined, workspaceProvider: WorkspaceProvider.create(config), urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute), - credentialsProvider: config.remoteAuthority ? undefined /* with a remote, we don't use a local credentials provider */ : new LocalStorageCredentialsProvider() + secretStorageProvider: config.remoteAuthority ? undefined /* with a remote, we don't use a local secret storage provider */ : new LocalStorageSecretStorageProvider() }); })(); diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts index ce043278337..6fbd655eb67 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts @@ -41,6 +41,7 @@ import { ICredentialsService } from 'vs/platform/credentials/common/credentials' import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { ILogService } from 'vs/platform/log/common/log'; +import { ISecretStorageService } from 'vs/platform/secrets/common/secrets'; export class ViewContainerActivityAction extends ActivityAction { @@ -235,7 +236,7 @@ export class AccountsActivityActionViewItem extends MenuActivityActionViewItem { private readonly problematicProviders: Set = new Set(); private initialized = false; - private sessionFromEmbedder = getCurrentAuthenticationSessionInfo(this.credentialsService, this.productService); + private sessionFromEmbedder = getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService); constructor( action: ActivityAction, @@ -253,6 +254,7 @@ export class AccountsActivityActionViewItem extends MenuActivityActionViewItem { @IConfigurationService configurationService: IConfigurationService, @IStorageService private readonly storageService: IStorageService, @IKeybindingService keybindingService: IKeybindingService, + @ISecretStorageService private readonly secretStorageService: ISecretStorageService, @ICredentialsService private readonly credentialsService: ICredentialsService, @ILogService private readonly logService: ILogService ) { diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index e1e8c5de6c6..4cec41e3b9a 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -92,6 +92,10 @@ import { BrowserRemoteResourceLoader } from 'vs/workbench/services/remote/browse import { BufferLogger } from 'vs/platform/log/common/bufferLog'; import { FileLoggerService } from 'vs/platform/log/common/fileLog'; import { IEmbedderTerminalService } from 'vs/workbench/services/terminal/common/embedderTerminalService'; +import { BrowserSecretStorageService } from 'vs/workbench/services/secrets/browser/secretStorageService'; +import { EncryptionService } from 'vs/workbench/services/encryption/browser/encryptionService'; +import { IEncryptionService } from 'vs/platform/encryption/common/encryptionService'; +import { ISecretStorageService } from 'vs/platform/secrets/common/secrets'; export class BrowserMain extends Disposable { @@ -384,9 +388,14 @@ export class BrowserMain extends Disposable { const credentialsService = new BrowserCredentialsService(environmentService, remoteAgentService, productService); serviceCollection.set(ICredentialsService, credentialsService); + const encryptionService = new EncryptionService(); + serviceCollection.set(IEncryptionService, encryptionService); + const secretStorageService = new BrowserSecretStorageService(storageService, encryptionService, environmentService, logService); + serviceCollection.set(ISecretStorageService, secretStorageService); + // Userdata Initialize Service const userDataInitializers: IUserDataInitializer[] = []; - userDataInitializers.push(new UserDataSyncInitializer(environmentService, credentialsService, userDataSyncStoreManagementService, fileService, userDataProfilesService, storageService, productService, requestService, logService, uriIdentityService)); + userDataInitializers.push(new UserDataSyncInitializer(environmentService, secretStorageService, credentialsService, userDataSyncStoreManagementService, fileService, userDataProfilesService, storageService, productService, requestService, logService, uriIdentityService)); if (environmentService.options.profile) { userDataInitializers.push(new UserDataProfileInitializer(environmentService, fileService, userDataProfileService, storageService, logService, uriIdentityService, requestService)); } diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts index a3a69e50222..f394515c6e2 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts @@ -25,6 +25,7 @@ import { IUserDataSyncMachinesService, UserDataSyncMachinesService } from 'vs/pl import { Emitter } from 'vs/base/common/event'; import { CancellationError } from 'vs/base/common/errors'; import { EditSessionsStoreClient } from 'vs/workbench/contrib/editSessions/common/editSessionsStorageClient'; +import { ISecretStorageService } from 'vs/platform/secrets/common/secrets'; type ExistingSession = IQuickPickItem & { session: AuthenticationSession & { providerId: string } }; type AuthenticationProviderOption = IQuickPickItem & { provider: IAuthenticationProvider }; @@ -81,6 +82,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes @IProductService private readonly productService: IProductService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IDialogService private readonly dialogService: IDialogService, + @ISecretStorageService private readonly secretStorageService: ISecretStorageService, @ICredentialsService private readonly credentialsService: ICredentialsService ) { super(); @@ -278,7 +280,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes // If settings sync is already enabled, avoid asking again to authenticate if (this.shouldAttemptEditSessionInit()) { this.logService.info(`Reusing user data sync enablement`); - const authenticationSessionInfo = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.productService); + const authenticationSessionInfo = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService); if (authenticationSessionInfo !== undefined) { this.logService.info(`Using current authentication session with ID ${authenticationSessionInfo.id}`); this.existingSessionId = authenticationSessionInfo.id; diff --git a/src/vs/workbench/services/authentication/browser/authenticationService.ts b/src/vs/workbench/services/authentication/browser/authenticationService.ts index d149dc29f23..f6c2f14685a 100644 --- a/src/vs/workbench/services/authentication/browser/authenticationService.ts +++ b/src/vs/workbench/services/authentication/browser/authenticationService.ts @@ -19,6 +19,7 @@ import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/ import { Severity } from 'vs/platform/notification/common/notification'; import { IProductService } from 'vs/platform/product/common/productService'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { ISecretStorageService } from 'vs/platform/secrets/common/secrets'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { IAuthenticationCreateSessionOptions, AuthenticationProviderInformation, AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationProvider, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; @@ -76,9 +77,17 @@ export function addAccountUsage(storageService: IStorageService, providerId: str storageService.store(accountKey, JSON.stringify(usages), StorageScope.APPLICATION, StorageTarget.MACHINE); } +// TODO: pull this out into its own service export type AuthenticationSessionInfo = { readonly id: string; readonly accessToken: string; readonly providerId: string; readonly canSignOut?: boolean }; -export async function getCurrentAuthenticationSessionInfo(credentialsService: ICredentialsService, productService: IProductService): Promise { - const authenticationSessionValue = await credentialsService.getPassword(`${productService.urlProtocol}.login`, 'account'); +export async function getCurrentAuthenticationSessionInfo( + // TODO: Remove when all known embedders implement SecretStorageProviders instead of CredentialsProviders + credentialsService: ICredentialsService, + secretStorageService: ISecretStorageService, + productService: IProductService +): Promise { + const authenticationSessionValue = + await secretStorageService.get(`${productService.urlProtocol}.loginAccount`) + ?? await credentialsService.getPassword(`${productService.urlProtocol}.login`, 'account'); if (authenticationSessionValue) { try { const authenticationSessionInfo: AuthenticationSessionInfo = JSON.parse(authenticationSessionValue); @@ -90,7 +99,8 @@ export async function getCurrentAuthenticationSessionInfo(credentialsService: IC return authenticationSessionInfo; } } catch (e) { - // ignore as this is a best effort operation. + // This is a best effort operation. + console.error(`Failed parsing current auth session value: ${e}`); } } return undefined; diff --git a/src/vs/workbench/services/secrets/browser/secretStorageService.ts b/src/vs/workbench/services/secrets/browser/secretStorageService.ts index 0f023b4d0d4..cc101aec985 100644 --- a/src/vs/workbench/services/secrets/browser/secretStorageService.ts +++ b/src/vs/workbench/services/secrets/browser/secretStorageService.ts @@ -5,9 +5,7 @@ import { IEncryptionService } from 'vs/platform/encryption/common/encryptionService'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; -import { INotificationService } from 'vs/platform/notification/common/notification'; import { ISecretStorageProvider, ISecretStorageService, BaseSecretStorageService } from 'vs/platform/secrets/common/secrets'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; @@ -20,8 +18,6 @@ export class BrowserSecretStorageService extends BaseSecretStorageService { @IStorageService storageService: IStorageService, @IEncryptionService encryptionService: IEncryptionService, @IBrowserWorkbenchEnvironmentService environmentService: IBrowserWorkbenchEnvironmentService, - @IInstantiationService instantiationService: IInstantiationService, - @INotificationService notificationService: INotificationService, @ILogService logService: ILogService ) { super(storageService, encryptionService, logService); diff --git a/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.ts b/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.ts index f87046057c6..ef77a1a411d 100644 --- a/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.ts +++ b/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.ts @@ -35,6 +35,7 @@ import { TasksInitializer } from 'vs/platform/userDataSync/common/tasksSync'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; import { IUserDataInitializer } from 'vs/workbench/services/userData/browser/userDataInit'; +import { ISecretStorageService } from 'vs/platform/secrets/common/secrets'; export class UserDataSyncInitializer implements IUserDataInitializer { @@ -46,6 +47,7 @@ export class UserDataSyncInitializer implements IUserDataInitializer { constructor( @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService, + @ISecretStorageService private readonly secretStorageService: ISecretStorageService, @ICredentialsService private readonly credentialsService: ICredentialsService, @IUserDataSyncStoreManagementService private readonly userDataSyncStoreManagementService: IUserDataSyncStoreManagementService, @IFileService private readonly fileService: IFileService, @@ -90,7 +92,7 @@ export class UserDataSyncInitializer implements IUserDataInitializer { let authenticationSession; try { - authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.productService); + authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService); } catch (error) { this.logService.error(error); } diff --git a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts index 556467309b5..ecc0fb248af 100644 --- a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts +++ b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts @@ -39,6 +39,7 @@ import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity' import { isDiffEditorInput } from 'vs/workbench/common/editor'; import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; import { IUserDataInitializationService } from 'vs/workbench/services/userData/browser/userDataInit'; +import { ISecretStorageService } from 'vs/platform/secrets/common/secrets'; type AccountQuickPickItem = { label: string; authenticationProvider: IAuthenticationProvider; account?: UserDataSyncAccount; description?: string }; @@ -105,6 +106,7 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat @IExtensionService private readonly extensionService: IExtensionService, @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService, @ICredentialsService private readonly credentialsService: ICredentialsService, + @ISecretStorageService private readonly secretStorageService: ISecretStorageService, @INotificationService private readonly notificationService: INotificationService, @IProgressService private readonly progressService: IProgressService, @IDialogService private readonly dialogService: IDialogService, @@ -169,7 +171,7 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat } private async initialize(): Promise { - const authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.productService); + const authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService); if (this.currentSessionId === undefined && authenticationSession?.id) { if (this.environmentService.options?.settingsSyncOptions?.authenticationProvider && this.environmentService.options.settingsSyncOptions.enabled) { this.currentSessionId = authenticationSession.id; From 99494a7a29e381c72103c3ccfcd31b4d7cdf259a Mon Sep 17 00:00:00 2001 From: Bhavya U Date: Wed, 5 Jul 2023 16:14:40 -0700 Subject: [PATCH 026/119] Show busy indicator in remote menu when initializing. (#187018) * Show progress bar in remote indicator when initializing * Remove placeholder change --- .../contrib/remote/browser/remoteIndicator.ts | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts index add2bda68e1..0244b7ad8e6 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts @@ -8,8 +8,8 @@ import { STATUS_BAR_HOST_NAME_BACKGROUND, STATUS_BAR_HOST_NAME_FOREGROUND } from import { themeColorFromId } from 'vs/platform/theme/common/themeService'; import { IRemoteAgentService, remoteConnectionLatencyMeasurer } from 'vs/workbench/services/remote/common/remoteAgentService'; import { RunOnceScheduler, retry } from 'vs/base/common/async'; -import { Event } from 'vs/base/common/event'; -import { Disposable, dispose } from 'vs/base/common/lifecycle'; +import { Emitter, Event } from 'vs/base/common/event'; +import { Disposable } from 'vs/base/common/lifecycle'; import { MenuId, IMenuService, MenuItemAction, MenuRegistry, registerAction2, Action2, SubmenuItemAction } from 'vs/platform/actions/common/actions'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor, IStatusbarEntry } from 'vs/workbench/services/statusbar/browser/statusbar'; @@ -115,6 +115,9 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr private loggedInvalidGroupNames: { [group: string]: boolean } = Object.create(null); private readonly remoteExtensionMetadata: RemoteExtensionMetadata[]; private remoteMetadataInitialized: boolean = false; + private readonly _onDidChangeEntries = this._register(new Emitter()); + private readonly onDidChangeEntries: Event = this._onDidChangeEntries.event; + constructor( @IStatusbarService private readonly statusbarService: IStatusbarService, @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService, @@ -341,6 +344,7 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr } this.remoteMetadataInitialized = true; + this._onDidChangeEntries.fire(); showRemoteStartEntry.bindTo(this.contextKeyService).set(true); this.updateRemoteStatusIndicator(); } @@ -551,15 +555,8 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr } } - // Show when there are commands or installable remote extensions. - if (this.hasRemoteMenuCommands(true) || this.remoteExtensionMetadata.some(ext => !ext.installed && ext.isPlatformCompatible)) { - this.renderRemoteStatusIndicator(`$(remote)`, nls.localize('noHost.tooltip', "Open a Remote Window")); - return; - } - - // No Remote Extensions: hide status indicator - dispose(this.remoteStatusEntry); - this.remoteStatusEntry = undefined; + this.renderRemoteStatusIndicator(`$(remote)`, nls.localize('noHost.tooltip', "Open a Remote Window")); + return; } private renderRemoteStatusIndicator(initialText: string, initialTooltip?: string | MarkdownString, command?: string, showProgress?: boolean): void { @@ -573,7 +570,7 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr text, showProgress, tooltip, - command: command ?? (this.hasRemoteMenuCommands(false) || this.remoteExtensionMetadata.some(ext => !ext.installed && ext.isPlatformCompatible)) ? RemoteStatusIndicator.REMOTE_ACTIONS_COMMAND_ID : undefined + command: command ?? RemoteStatusIndicator.REMOTE_ACTIONS_COMMAND_ID }; if (this.remoteStatusEntry) { @@ -834,17 +831,15 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr const itemUpdater = this.remoteIndicatorMenu.onDidChange(() => quickPick.items = computeItems()); quickPick.onDidHide(itemUpdater.dispose); - quickPick.show(); - } - - private hasRemoteMenuCommands(ignoreInstallAdditional: boolean): boolean { - if (this.remoteAuthority !== undefined || this.virtualWorkspaceLocation !== undefined) { - if (RemoteStatusIndicator.SHOW_CLOSE_REMOTE_COMMAND_ID) { - return true; - } - } else if (!ignoreInstallAdditional && this.extensionGalleryService.isEnabled()) { - return true; + if (!this.remoteMetadataInitialized) { + quickPick.busy = true; + this._register(this.onDidChangeEntries(() => { + // If quick pick is open, update the quick pick items after initialization. + quickPick.busy = false; + quickPick.items = computeItems(); + })); } - return this.getRemoteMenuActions().length > 0; + + quickPick.show(); } } From 6fa852f87a0bb83f951e9ac38b4481462b10e11c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jul 2023 16:29:29 -0700 Subject: [PATCH 027/119] Bump semver from 7.3.5 to 7.5.3 in /remote (#185981) Bumps [semver](https://github.com/npm/node-semver) from 7.3.5 to 7.5.3. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v7.3.5...v7.5.3) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- remote/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/remote/yarn.lock b/remote/yarn.lock index e06f1e1adba..0539567ca2d 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -661,9 +661,9 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" From 9618e4fa2a80e3ea788a6098a72d46c8db058a91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jul 2023 16:29:55 -0700 Subject: [PATCH 028/119] Bump semver from 7.3.8 to 7.5.3 in /build/npm/gyp (#186809) Bumps [semver](https://github.com/npm/node-semver) from 7.3.8 to 7.5.3. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v7.3.8...v7.5.3) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build/npm/gyp/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/npm/gyp/yarn.lock b/build/npm/gyp/yarn.lock index d5d6bced114..1fe78aba8f3 100644 --- a/build/npm/gyp/yarn.lock +++ b/build/npm/gyp/yarn.lock @@ -520,9 +520,9 @@ safe-buffer@~5.2.0: integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== semver@^7.3.5: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" From c9073ad0c8f57bcbea556d67d8044a068667f2d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 01:54:58 +0200 Subject: [PATCH 029/119] Bump semver from 7.3.7 to 7.5.3 in /extensions/css-language-features (#187107) Bumps [semver](https://github.com/npm/node-semver) from 7.3.7 to 7.5.3. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v7.3.7...v7.5.3) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- extensions/css-language-features/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/css-language-features/yarn.lock b/extensions/css-language-features/yarn.lock index f8ab6ac49a4..bad63f26ca1 100644 --- a/extensions/css-language-features/yarn.lock +++ b/extensions/css-language-features/yarn.lock @@ -34,9 +34,9 @@ minimatch@^5.1.0: brace-expansion "^2.0.1" semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" From 609e6369335d436a5fa14ec97467447d5608b51f Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 5 Jul 2023 17:19:33 -0700 Subject: [PATCH 030/119] Also check for secret storage provider before using old API (#187105) This allows a nice migration path for web environments: 1. Embedder implements a secret storage provider in addition to the credentials provider they already have 2. Wait a release or 2 3. Remove the credentials provider from the embedder Once all known embedders do number 1, we can delete the `_oldMainThreadSecretState` entirely. --- .../workbench/api/browser/mainThreadSecretState.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadSecretState.ts b/src/vs/workbench/api/browser/mainThreadSecretState.ts index 8bb4a91d976..d8fa95ac538 100644 --- a/src/vs/workbench/api/browser/mainThreadSecretState.ts +++ b/src/vs/workbench/api/browser/mainThreadSecretState.ts @@ -110,6 +110,7 @@ class OldMainThreadSecretState extends Disposable implements MainThreadSecretSta export class MainThreadSecretState extends Disposable implements MainThreadSecretStateShape { private readonly _proxy: ExtHostSecretStateShape; + // TODO: Remove this when all known embedders implement a secret storage provider private readonly _oldMainThreadSecretState: OldMainThreadSecretState | undefined; private readonly _sequencer = new SequencerByKey(); @@ -131,7 +132,11 @@ export class MainThreadSecretState extends Disposable implements MainThreadSecre this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostSecretState); - if (environmentService.options?.credentialsProvider) { + // If the embedder doesn't implement a secret storage provider, then we need to use the old API + // to ensure that secrets are still stored in a secure way. This is only temporary until all + // embedders implement a secret storage provider. + // TODO: Remove this when all known embedders implement a secret storage provider + if (environmentService.options?.credentialsProvider && !environmentService.options?.secretStorageProvider) { this._oldMainThreadSecretState = this._register(new OldMainThreadSecretState( this._proxy, credentialsService, @@ -158,7 +163,7 @@ export class MainThreadSecretState extends Disposable implements MainThreadSecre } private async doGetPassword(extensionId: string, key: string): Promise { - // TODO: Remove this when we remove the old API + // TODO: Remove this when all known embedders implement a secret storage provider if (this._oldMainThreadSecretState) { return await this._oldMainThreadSecretState.$getPassword(extensionId, key); } @@ -184,7 +189,7 @@ export class MainThreadSecretState extends Disposable implements MainThreadSecre } private async doSetPassword(extensionId: string, key: string, value: string): Promise { - // TODO: Remove this when we remove the old API + // TODO: Remove this when all known embedders implement a secret storage provider if (this._oldMainThreadSecretState) { return await this._oldMainThreadSecretState.$setPassword(extensionId, key, value); } @@ -200,7 +205,7 @@ export class MainThreadSecretState extends Disposable implements MainThreadSecre } private async doDeletePassword(extensionId: string, key: string): Promise { - // TODO: Remove this when we remove the old API + // TODO: Remove this when all known embedders implement a secret storage provider if (this._oldMainThreadSecretState) { return await this._oldMainThreadSecretState.$deletePassword(extensionId, key); } From 6c8cdf325eb1dc8a0e2ea9205a1d2ca05f69c101 Mon Sep 17 00:00:00 2001 From: Bhavya U Date: Wed, 5 Jul 2023 17:35:13 -0700 Subject: [PATCH 031/119] Remove galleryExtension check when initializing remote menu (#187109) Remove galleryExtension check --- .../contrib/remote/browser/remoteIndicator.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts index 0244b7ad8e6..1450fb17d17 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts @@ -47,7 +47,7 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { DomEmitter } from 'vs/base/browser/event'; import { registerColor } from 'vs/platform/theme/common/colorRegistry'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { CancellationToken } from 'vs/base/common/cancellation'; import { ThemeIcon } from 'vs/base/common/themables'; import { infoIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons'; import { IOpenerService } from 'vs/platform/opener/common/opener'; @@ -325,22 +325,18 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr for (let i = 0; i < this.remoteExtensionMetadata.length; i++) { const extensionId = this.remoteExtensionMetadata[i].id; const supportedPlatforms = this.remoteExtensionMetadata[i].supportedPlatforms; - // Update compatibility - const token = new CancellationTokenSource(); - const galleryExtension = (await this.extensionGalleryService.getExtensions([{ id: extensionId }], token.token))[0]; - if (!await this.extensionManagementService.canInstall(galleryExtension)) { - this.remoteExtensionMetadata[i].isPlatformCompatible = false; + const isInstalled = (await this.extensionManagementService.getInstalled()).find(value => ExtensionIdentifier.equals(value.identifier.id, extensionId)) ? true : false; + + this.remoteExtensionMetadata[i].installed = isInstalled; + if (isInstalled) { + this.remoteExtensionMetadata[i].isPlatformCompatible = true; } else if (supportedPlatforms && !supportedPlatforms.includes(currentPlatform)) { this.remoteExtensionMetadata[i].isPlatformCompatible = false; } else { this.remoteExtensionMetadata[i].isPlatformCompatible = true; - this.remoteExtensionMetadata[i].dependencies = galleryExtension.properties.extensionPack ?? []; } - - // Check if installed and enabled - this.remoteExtensionMetadata[i].installed = (await this.extensionManagementService.getInstalled()).find(value => ExtensionIdentifier.equals(value.identifier.id, extensionId)) ? true : false; } this.remoteMetadataInitialized = true; From 4223cc994e10b1b4bb92ff8ee5373aaace39361d Mon Sep 17 00:00:00 2001 From: Marshall Roch Date: Tue, 30 May 2023 13:19:26 -0400 Subject: [PATCH 032/119] fix [object Object] in invalid decorator warning when there's an invalid decorator, you get a warning like this: ``` [warning] INVALID decoration from extension '[object Object]': Error: The decoration is empty ``` as is done elsewhere in this file, should use `extensionId.identifier.value` to get a string --- src/vs/workbench/api/common/extHostDecorations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/common/extHostDecorations.ts b/src/vs/workbench/api/common/extHostDecorations.ts index 12dcb1072a5..7633574f065 100644 --- a/src/vs/workbench/api/common/extHostDecorations.ts +++ b/src/vs/workbench/api/common/extHostDecorations.ts @@ -106,7 +106,7 @@ export class ExtHostDecorations implements ExtHostDecorationsShape { } result[id] = [data.propagate, data.tooltip, data.badge, data.color]; } catch (e) { - this._logService.warn(`INVALID decoration from extension '${extensionId}': ${e}`); + this._logService.warn(`INVALID decoration from extension '${extensionId.identifier.value}': ${e}`); } } catch (err) { this._logService.error(err); From 42e9acc5a8efae6150f49926221171ca8f93ad54 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 6 Jul 2023 07:11:18 -0700 Subject: [PATCH 033/119] no need to explicitly get workspace tasks as they're always refreshed now --- .../contrib/tasks/browser/abstractTaskService.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 979b207b9e5..801bcdf5e6f 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -374,7 +374,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._tasksReconnected = true; return; } - this.getWorkspaceTasks().then(async () => { + this.getWorkspaceTasks(TaskRunSource.Reconnect).then(async () => { this._tasksReconnected = await this._reconnectTasks(); }); } @@ -2349,11 +2349,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return { workspaceFolder, set: undefined, configurations: undefined, hasErrors: false }; } - private async _computeTasksForSingleConfig(workspaceFolder: IWorkspaceFolder | undefined, config: TaskConfig.IExternalTaskRunnerConfiguration | undefined, runSource: TaskRunSource, custom: CustomTask[], customized: IStringDictionary, source: TaskConfig.TaskConfigSource, isRecentTask: boolean = false): Promise { - if (!config || !workspaceFolder) { + private async _computeTasksForSingleConfig(workspaceFolder: IWorkspaceFolder, config: TaskConfig.IExternalTaskRunnerConfiguration | undefined, runSource: TaskRunSource, custom: CustomTask[], customized: IStringDictionary, source: TaskConfig.TaskConfigSource, isRecentTask: boolean = false): Promise { + if (!config) { return false; } - const taskSystemInfo: ITaskSystemInfo | undefined = workspaceFolder ? this._getTaskSystemInfo(workspaceFolder.uri.scheme) : undefined; + const taskSystemInfo: ITaskSystemInfo | undefined = this._getTaskSystemInfo(workspaceFolder.uri.scheme); const problemReporter = new ProblemReporter(this._outputChannel); if (!taskSystemInfo) { problemReporter.fatal(nls.localize('TaskSystem.workspaceFolderError', 'Workspace folder was undefined')); @@ -2746,7 +2746,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private async _runTaskCommand(filter?: string | ITaskIdentifier): Promise { - await this.getWorkspaceTasks(); if (!filter) { return this._doRunTaskCommand(); } @@ -2904,7 +2903,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer title: strings.fetching }; const promise = (async () => { - await this.getWorkspaceTasks(); let taskGroupTasks: (Task | ConfiguringTask)[] = []; async function runSingleTask(task: Task | undefined, problemMatcherOptions: IProblemMatcherRunOptions | undefined, that: AbstractTaskService) { From e1021bf70d836a572d6de04c83e36ddac8c64ed4 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 6 Jul 2023 07:14:31 -0700 Subject: [PATCH 034/119] Create codespaces_issue.yml --- .github/commands/codespaces_issue.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/commands/codespaces_issue.yml diff --git a/.github/commands/codespaces_issue.yml b/.github/commands/codespaces_issue.yml new file mode 100644 index 00000000000..7abacafaf21 --- /dev/null +++ b/.github/commands/codespaces_issue.yml @@ -0,0 +1,11 @@ +# Learn more about the syntax here: +# https://docs.github.com/en/early-access/github/save-time-with-slash-commands/syntax-for-user-defined-slash-commands +--- +trigger: codespaces_issue +title: Codespaces Issue +description: Report downstream + +steps: + - type: fill + template: |- + This looks like an issue with the Codespaces service which we don't track in this repository. You can report this to the Codespaces team at https://github.com/orgs/community/discussions/categories/codespaces From 4f1df73b952ee3526c279b0aea348a4733bb128f Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 6 Jul 2023 09:23:11 -0700 Subject: [PATCH 035/119] when supported executions change, make sure to unset the promise so they get re-evaluated --- .../workbench/contrib/tasks/browser/abstractTaskService.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 801bcdf5e6f..12fc22bd477 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -362,6 +362,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const processContext = ProcessExecutionSupportedContext.bindTo(this._contextKeyService); processContext.set(process && !isVirtual); } + // update tasks so an incomplete list isn't returned when getWorkspaceTasks is called + this._workspaceTasksPromise = undefined; this._onDidRegisterSupportedExecutions.fire(); } @@ -2201,6 +2203,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } await this._waitForSupportedExecutions; await this._whenTaskSystemReady; + if (this._workspaceTasksPromise) { + return this._workspaceTasksPromise; + } return this._updateWorkspaceTasks(runSource); } From 001615e0b661554397e1af7c62e1ef10cc9ae96a Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 6 Jul 2023 10:29:50 -0700 Subject: [PATCH 036/119] No need for additional readonly and missing file check. --- .../workbench/api/common/extHostNotebook.ts | 72 +------------------ 1 file changed, 2 insertions(+), 70 deletions(-) diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index 02e1dd91363..e61788f49e1 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -328,11 +328,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { } // validate write - const statBeforeWrite = await this._validateWriteFile(uri, options); - - if (!statBeforeWrite) { - await this._mkdirp(uri); - } + await this._validateWriteFile(uri, options); const data: vscode.NotebookData = { metadata: filter(document.apiNotebook.metadata, key => !(serializer.options?.transientDocumentMetadata ?? {})[key]), @@ -377,20 +373,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { } private async _validateWriteFile(uri: URI, options: files.IWriteFileOptions) { - // File system provider registered in Extension Host doesn't have unlock or atomic support - // Validate via file stat meta data const stat = await this._extHostFileSystem.value.stat(uri); - - // File cannot be directory - if ((stat.type & files.FileType.Directory) !== 0) { - throw new files.FileOperationError(localize('fileIsDirectoryWriteError', "Unable to write file '{0}' that is actually a directory", this._resourceForError(uri)), files.FileOperationResult.FILE_IS_DIRECTORY, options); - } - - // File cannot be readonly - if ((stat.permissions ?? 0) & files.FilePermission.Readonly) { - throw new files.FileOperationError(localize('err.readonly', "Unable to modify read-only file '{0}'", this._resourceForError(uri)), files.FileOperationResult.FILE_PERMISSION_DENIED); - } - // Dirty write prevention if ( typeof options?.mtime === 'number' && typeof options.etag === 'string' && options.etag !== files.ETAG_DISABLED && @@ -400,58 +383,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { throw new files.FileOperationError(localize('fileModifiedError', "File Modified Since"), files.FileOperationResult.FILE_MODIFIED_SINCE, options); } - return stat; - } - - private async _mkdirp(uri: URI) { - const providerExtUri = this._extHostFileSystem.getFileSystemProviderExtUri(uri.scheme); - let directory = providerExtUri.dirname(uri); - - const directoriesToCreate: string[] = []; - - while (!providerExtUri.isEqual(directory, providerExtUri.dirname(directory))) { - try { - const stat = await this._extHostFileSystem.value.stat(directory); - if ((stat.type & files.FileType.Directory) === 0) { - throw new Error(localize('mkdirExistsError', "Unable to create folder '{0}' that already exists but is not a directory", this._resourceForError(directory))); - } - - break; // we have hit a directory that exists -> good - } catch (error) { - - // Bubble up any other error that is not file not found - if (files.toFileSystemProviderErrorCode(error) !== files.FileSystemProviderErrorCode.FileNotFound) { - throw error; - } - - // Upon error, remember directories that need to be created - directoriesToCreate.push(providerExtUri.basename(directory)); - - // Continue up - directory = providerExtUri.dirname(directory); - } - } - - // Create directories as needed - for (let i = directoriesToCreate.length - 1; i >= 0; i--) { - directory = providerExtUri.joinPath(directory, directoriesToCreate[i]); - - try { - await this._extHostFileSystem.value.createDirectory(directory); - } catch (error) { - if (files.toFileSystemProviderErrorCode(error) !== files.FileSystemProviderErrorCode.FileExists) { - // For mkdirp() we tolerate that the mkdir() call fails - // in case the folder already exists. This follows node.js - // own implementation of fs.mkdir({ recursive: true }) and - // reduces the chances of race conditions leading to errors - // if multiple calls try to create the same folders - // As such, we only throw an error here if it is other than - // the fact that the file already exists. - // (see also https://github.com/microsoft/vscode/issues/89834) - throw error; - } - } - } + return; } private _resourceForError(uri: URI): string { From 078d0fd6e3041364c0e9a686a4deb0a13980bb66 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Thu, 6 Jul 2023 11:00:48 -0700 Subject: [PATCH 037/119] Fix capitalization in survey notification (#187168) --- src/vs/workbench/contrib/surveys/browser/ces.contribution.ts | 2 +- .../contrib/surveys/browser/languageSurveys.contribution.ts | 2 +- src/vs/workbench/contrib/surveys/browser/nps.contribution.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/surveys/browser/ces.contribution.ts b/src/vs/workbench/contrib/surveys/browser/ces.contribution.ts index 386247aa716..b24d91f8da3 100644 --- a/src/vs/workbench/contrib/surveys/browser/ces.contribution.ts +++ b/src/vs/workbench/contrib/surveys/browser/ces.contribution.ts @@ -98,7 +98,7 @@ class CESContribution extends Disposable implements IWorkbenchContribution { this.skipSurvey(); } }, { - label: nls.localize('remindLater', "Remind Me later"), + label: nls.localize('remindLater', "Remind Me Later"), run: () => { sendTelemetry('remindLater'); this.storageService.store(REMIND_LATER_DATE_KEY, new Date().toUTCString(), StorageScope.APPLICATION, StorageTarget.USER); diff --git a/src/vs/workbench/contrib/surveys/browser/languageSurveys.contribution.ts b/src/vs/workbench/contrib/surveys/browser/languageSurveys.contribution.ts index 300123f2761..b72e929518a 100644 --- a/src/vs/workbench/contrib/surveys/browser/languageSurveys.contribution.ts +++ b/src/vs/workbench/contrib/surveys/browser/languageSurveys.contribution.ts @@ -105,7 +105,7 @@ class LanguageSurvey extends Disposable { storageService.store(SKIP_VERSION_KEY, productService.version, StorageScope.APPLICATION, StorageTarget.USER); } }, { - label: localize('remindLater', "Remind Me later"), + label: localize('remindLater', "Remind Me Later"), run: () => { telemetryService.publicLog(`${data.surveyId}.survey/remindMeLater`); storageService.store(SESSION_COUNT_KEY, sessionCount - 3, StorageScope.APPLICATION, StorageTarget.USER); diff --git a/src/vs/workbench/contrib/surveys/browser/nps.contribution.ts b/src/vs/workbench/contrib/surveys/browser/nps.contribution.ts index bf961d2e22f..f3cea74430c 100644 --- a/src/vs/workbench/contrib/surveys/browser/nps.contribution.ts +++ b/src/vs/workbench/contrib/surveys/browser/nps.contribution.ts @@ -76,7 +76,7 @@ class NPSContribution implements IWorkbenchContribution { storageService.store(SKIP_VERSION_KEY, productService.version, StorageScope.APPLICATION, StorageTarget.USER); } }, { - label: nls.localize('remindLater', "Remind Me later"), + label: nls.localize('remindLater', "Remind Me Later"), run: () => storageService.store(SESSION_COUNT_KEY, sessionCount - 3, StorageScope.APPLICATION, StorageTarget.USER) }, { label: nls.localize('neverAgain', "Don't Show Again"), From ccbcba53e642136ce30465cd4f5605d60c760d7c Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 6 Jul 2023 11:04:59 -0700 Subject: [PATCH 038/119] debug: shut down debug sessions if an extension host goes away (#187169) Fixes #184552 --- src/vs/workbench/api/browser/mainThreadDebugService.ts | 7 ++++++- src/vs/workbench/contrib/debug/browser/rawDebugSession.ts | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadDebugService.ts b/src/vs/workbench/api/browser/mainThreadDebugService.ts index 79fe81e21d6..6b833ab272e 100644 --- a/src/vs/workbench/api/browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/browser/mainThreadDebugService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { DisposableStore } from 'vs/base/common/lifecycle'; +import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { URI as uri, UriComponents } from 'vs/base/common/uri'; import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IDebugAdapter, IDebugAdapterDescriptorFactory, IDebugSession, IDebugAdapterFactory, IDataBreakpoint, IDebugSessionOptions, IInstructionBreakpoint, DebugConfigurationProviderTriggerKind } from 'vs/workbench/contrib/debug/common/debug'; import { @@ -50,6 +50,11 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb this._toDispose.add(debugService.getViewModel().onDidFocusSession(session => { this._proxy.$acceptDebugSessionActiveChanged(this.getSessionDto(session)); })); + this._toDispose.add(toDisposable(() => { + for (const [handle, da] of this._debugAdapters) { + da.fireError(handle, new Error('Extension host shut down')); + } + })); this._debugAdapters = new Map(); this._debugConfigurationProviders = new Map(); diff --git a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts index 294aaffa3e9..db8cd73120e 100644 --- a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts @@ -573,7 +573,8 @@ export class RawDebugSession implements IDisposable { args.suspendDebuggee = suspendDebuggee; } - await this.send('disconnect', args, undefined, 2000); + // if there's an error, the DA is probably already gone, so give it a much shorter timeout. + await this.send('disconnect', args, undefined, error ? 200 : 2000); } catch (e) { // Catch the potential 'disconnect' error - no need to show it to the user since the adapter is shutting down } finally { From c067a3bf81b79b0c29c983b847fd0db3839fc6d0 Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:18:02 -0700 Subject: [PATCH 039/119] chore: bump semver 7 dependencies (#187171) --- build/yarn.lock | 15 ++++----------- extensions/html-language-features/yarn.lock | 6 +++--- extensions/json-language-features/yarn.lock | 6 +++--- extensions/markdown-language-features/yarn.lock | 6 +++--- test/smoke/yarn.lock | 6 +++--- 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/build/yarn.lock b/build/yarn.lock index c29bf14c70a..3c3bce1fbc5 100644 --- a/build/yarn.lock +++ b/build/yarn.lock @@ -2568,17 +2568,10 @@ semver@^6.2.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.2: - version "7.3.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" - integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.5, semver@^7.3.8: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== +semver@^7.3.2, semver@^7.3.5, semver@^7.3.8: + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" diff --git a/extensions/html-language-features/yarn.lock b/extensions/html-language-features/yarn.lock index 9b13e63e639..e4f74847429 100644 --- a/extensions/html-language-features/yarn.lock +++ b/extensions/html-language-features/yarn.lock @@ -354,9 +354,9 @@ semver@^5.3.0, semver@^5.4.1: integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index 5bec70a9925..dcf55538c9a 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -359,9 +359,9 @@ semver@^5.3.0, semver@^5.4.1: integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" diff --git a/extensions/markdown-language-features/yarn.lock b/extensions/markdown-language-features/yarn.lock index e796e655bae..46f769556aa 100644 --- a/extensions/markdown-language-features/yarn.lock +++ b/extensions/markdown-language-features/yarn.lock @@ -480,9 +480,9 @@ semver@^5.3.0, semver@^5.4.1: integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@^7.3.5: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" diff --git a/test/smoke/yarn.lock b/test/smoke/yarn.lock index 42787b9e371..9c7dbcbe089 100644 --- a/test/smoke/yarn.lock +++ b/test/smoke/yarn.lock @@ -643,9 +643,9 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@^7.3.8: - version "7.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" - integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" From ed59e75f3d4a3bf50d4d51edfb761afef18cb9dd Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:35:45 -0700 Subject: [PATCH 040/119] Add IPtyHostService This is a new service which extends IPtyService and provides additional methods on the process that manages the connection to the pty host: - IPtyService: Talk to the pty host, this may be direct via a message port of via the main/server procs. - IPtyHostService: Talk to the pty host management interfaces on the main/server procs. These are no longer available as optional methods on IPtyService to be clear about where they happen (eg. getProfiles). Fixes #186935 --- src/vs/platform/terminal/common/terminal.ts | 43 ++++---- .../platform/terminal/node/ptyHostService.ts | 9 +- src/vs/platform/terminal/node/ptyService.ts | 8 +- src/vs/server/node/remoteTerminalChannel.ts | 102 +++++++++--------- src/vs/server/node/serverServices.ts | 9 +- .../electron-sandbox/localTerminalBackend.ts | 3 +- 6 files changed, 86 insertions(+), 88 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 890998623de..2f29ede8364 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -221,8 +221,6 @@ export enum TerminalIpcChannels { Heartbeat = 'heartbeat' } -export const IPtyService = createDecorator('ptyService'); - export const enum ProcessPropertyType { Cwd = 'cwd', InitialCwd = 'initialCwd', @@ -266,18 +264,8 @@ export interface IFixedTerminalDimensions { rows?: number; } -export interface IPtyHostController { - readonly onPtyHostExit?: Event; - readonly onPtyHostStart?: Event; - readonly onPtyHostUnresponsive?: Event; - readonly onPtyHostResponsive?: Event; - readonly onPtyHostRequestResolveVariables?: Event; - - restartPtyHost?(): void; - acceptPtyHostResolvedVariables?(requestId: number, resolved: string[]): Promise; -} - -export interface IPtyService extends IPtyHostController { +export const IPtyService = createDecorator('ptyService'); +export interface IPtyService { readonly _serviceBrand: undefined; readonly onProcessData: Event<{ id: number; event: IProcessDataEvent | string }>; @@ -288,10 +276,6 @@ export interface IPtyService extends IPtyHostController { readonly onDidChangeProperty: Event<{ id: number; property: IProcessProperty }>; readonly onProcessExit: Event<{ id: number; event: number | undefined }>; - restartPtyHost?(): Promise; - shutdownAll?(): Promise; - acceptPtyHostResolvedVariables?(requestId: number, resolved: string[]): Promise; - createProcess( shellLaunchConfig: IShellLaunchConfig, cwd: string, @@ -307,6 +291,7 @@ export interface IPtyService extends IPtyHostController { ): Promise; attachToProcess(id: number): Promise; detachFromProcess(id: number, forcePersist?: boolean): Promise; + shutdownAll(): Promise; /** * Lists all orphaned processes, ie. those without a connected frontend. @@ -334,7 +319,6 @@ export interface IPtyService extends IPtyHostController { uninstallAllAutoReplies(): Promise; uninstallAutoReply(match: string): Promise; getDefaultSystemShell(osOverride?: OperatingSystem): Promise; - getProfiles?(workspaceId: string, profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise; getEnvironment(): Promise; getWslPath(original: string, direction: 'unix-to-win' | 'win-to-unix'): Promise; getRevivedPtyNewId(workspaceId: string, id: number): Promise; @@ -343,7 +327,7 @@ export interface IPtyService extends IPtyHostController { reduceConnectionGraceTime(): Promise; requestDetachInstance(workspaceId: string, instanceId: number): Promise; acceptDetachInstanceReply(requestId: number, persistentProcessId?: number): Promise; - freePortKillProcess?(port: string): Promise<{ port: string; processId: string }>; + freePortKillProcess(port: string): Promise<{ port: string; processId: string }>; /** * Serializes and returns terminal state. * @param ids The persistent terminal IDs to serialize. @@ -357,9 +341,26 @@ export interface IPtyService extends IPtyHostController { refreshProperty(id: number, property: T): Promise; updateProperty(id: number, property: T, value: IProcessPropertyMap[T]): Promise; + // TODO: Make mandatory and remove impl from pty host service refreshIgnoreProcessNames?(names: string[]): Promise; } +export interface IPtyHostController { + readonly onPtyHostExit: Event; + readonly onPtyHostStart: Event; + readonly onPtyHostUnresponsive: Event; + readonly onPtyHostResponsive: Event; + readonly onPtyHostRequestResolveVariables: Event; + + restartPtyHost(): Promise; + acceptPtyHostResolvedVariables(requestId: number, resolved: string[]): Promise; + getProfiles(workspaceId: string, profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise; +} + +export const IPtyHostService = createDecorator('ptyHostService'); +export interface IPtyHostService extends IPtyService, IPtyHostController { +} + /** * Serialized terminal state matching the interface that can be used across versions, the version * should be verified before using the state payload. @@ -1066,7 +1067,7 @@ export const ILocalPtyService = createDecorator('localPtyServi * * **This service should only be used within the terminal component.** */ -export interface ILocalPtyService extends IPtyService { } +export interface ILocalPtyService extends IPtyHostService { } export const ITerminalLogService = createDecorator('terminalLogService'); export interface ITerminalLogService extends ILogService { diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index ecd550e3826..59b84827479 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -13,7 +13,7 @@ import { RemoteLoggerChannelClient } from 'vs/platform/log/common/logIpc'; import { getResolvedShellEnv } from 'vs/platform/shell/node/shellEnv'; import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/capabilities/capabilities'; import { RequestStore } from 'vs/platform/terminal/common/requestStore'; -import { HeartbeatConstants, IHeartbeatService, IProcessDataEvent, IProcessProperty, IProcessPropertyMap, IProcessReadyEvent, IPtyService, IRequestResolveVariablesEvent, ISerializedTerminalState, IShellLaunchConfig, ITerminalLaunchError, ITerminalProcessOptions, ITerminalProfile, ITerminalsLayoutInfo, ProcessPropertyType, TerminalIcon, TerminalIpcChannels, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { HeartbeatConstants, IHeartbeatService, IProcessDataEvent, IProcessProperty, IProcessPropertyMap, IProcessReadyEvent, IPtyHostService, IPtyService, IRequestResolveVariablesEvent, ISerializedTerminalState, IShellLaunchConfig, ITerminalLaunchError, ITerminalProcessOptions, ITerminalProfile, ITerminalsLayoutInfo, ProcessPropertyType, TerminalIcon, TerminalIpcChannels, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { registerTerminalPlatformConfiguration } from 'vs/platform/terminal/common/terminalPlatformConfiguration'; import { IGetTerminalLayoutInfoArgs, IProcessDetails, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess'; import { IPtyHostConnection, IPtyHostStarter } from 'vs/platform/terminal/node/ptyHost'; @@ -29,7 +29,7 @@ enum Constants { * This service implements IPtyService by launching a pty host process, forwarding messages to and * from the pty host process and manages the connection. */ -export class PtyHostService extends Disposable implements IPtyService { +export class PtyHostService extends Disposable implements IPtyHostService { declare readonly _serviceBrand: undefined; private __connection?: IPtyHostConnection; @@ -230,6 +230,9 @@ export class PtyHostService extends Disposable implements IPtyService { detachFromProcess(id: number, forcePersist?: boolean): Promise { return this._proxy.detachFromProcess(id, forcePersist); } + shutdownAll(): Promise { + return this._proxy.shutdownAll(); + } listProcesses(): Promise { return this._proxy.listProcesses(); } @@ -354,7 +357,7 @@ export class PtyHostService extends Disposable implements IPtyService { } private _disposePtyHost(): void { - this._proxy.shutdownAll?.(); + this._proxy.shutdownAll(); this._connection.store.dispose(); } diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 89a37150b5a..564b87612f3 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri'; import { getSystemShell } from 'vs/base/node/shell'; import { ILogService, LogLevel } from 'vs/platform/log/common/log'; import { RequestStore } from 'vs/platform/terminal/common/requestStore'; -import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, IProcessProperty, TitleEventSource, ProcessPropertyType, IProcessPropertyMap, IFixedTerminalDimensions, IPersistentTerminalProcessLaunchConfig, ICrossVersionSerializedTerminalState, ISerializedTerminalState, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IShellLaunchConfig, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, IProcessProperty, TitleEventSource, ProcessPropertyType, IProcessPropertyMap, IFixedTerminalDimensions, IPersistentTerminalProcessLaunchConfig, ICrossVersionSerializedTerminalState, ISerializedTerminalState, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal'; import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment'; import { Terminal as XtermTerminal } from 'xterm-headless'; @@ -136,12 +136,6 @@ export class PtyService extends Disposable implements IPtyService { ignoreProcessNames.push(...names); } - onPtyHostExit?: Event | undefined; - onPtyHostStart?: Event | undefined; - onPtyHostUnresponsive?: Event | undefined; - onPtyHostResponsive?: Event | undefined; - onPtyHostRequestResolveVariables?: Event | undefined; - @traceRpc async requestDetachInstance(workspaceId: string, instanceId: number): Promise { return this._detachInstanceRequestStore.createRequest({ workspaceId, instanceId }); diff --git a/src/vs/server/node/remoteTerminalChannel.ts b/src/vs/server/node/remoteTerminalChannel.ts index 426cb7f5a6f..8d396c86021 100644 --- a/src/vs/server/node/remoteTerminalChannel.ts +++ b/src/vs/server/node/remoteTerminalChannel.ts @@ -14,7 +14,7 @@ import { IURITransformer } from 'vs/base/common/uriIpc'; import { IServerChannel } from 'vs/base/parts/ipc/common/ipc'; import { createRandomIPCHandle } from 'vs/base/parts/ipc/node/ipc.net'; import { RemoteAgentConnectionContext } from 'vs/platform/remote/common/remoteAgentEnvironment'; -import { IPtyService, IShellLaunchConfig, ITerminalProfile } from 'vs/platform/terminal/common/terminal'; +import { IPtyHostService, IShellLaunchConfig, ITerminalProfile } from 'vs/platform/terminal/common/terminal'; import { IGetTerminalLayoutInfoArgs, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { createURITransformer } from 'vs/workbench/api/node/uriTransformer'; @@ -97,7 +97,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< constructor( private readonly _environmentService: IServerEnvironmentService, private readonly _logService: ILogService, - private readonly _ptyService: IPtyService, + private readonly _ptyHostService: IPtyHostService, private readonly _productService: IProductService, private readonly _extensionManagementService: IExtensionManagementService, private readonly _configurationService: IConfigurationService @@ -107,52 +107,52 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< async call(ctx: RemoteAgentConnectionContext, command: string, args?: any): Promise { switch (command) { - case '$restartPtyHost': return this._ptyService.restartPtyHost?.apply(this._ptyService, args); + case '$restartPtyHost': return this._ptyHostService.restartPtyHost?.apply(this._ptyHostService, args); case '$createProcess': { const uriTransformer = createURITransformer(ctx.remoteAuthority); return this._createProcess(uriTransformer, args); } - case '$attachToProcess': return this._ptyService.attachToProcess.apply(this._ptyService, args); - case '$detachFromProcess': return this._ptyService.detachFromProcess.apply(this._ptyService, args); + case '$attachToProcess': return this._ptyHostService.attachToProcess.apply(this._ptyHostService, args); + case '$detachFromProcess': return this._ptyHostService.detachFromProcess.apply(this._ptyHostService, args); - case '$listProcesses': return this._ptyService.listProcesses.apply(this._ptyService, args); - case '$getPerformanceMarks': return this._ptyService.getPerformanceMarks.apply(this._ptyService, args); - case '$orphanQuestionReply': return this._ptyService.orphanQuestionReply.apply(this._ptyService, args); - case '$acceptPtyHostResolvedVariables': return this._ptyService.acceptPtyHostResolvedVariables?.apply(this._ptyService, args); + case '$listProcesses': return this._ptyHostService.listProcesses.apply(this._ptyHostService, args); + case '$getPerformanceMarks': return this._ptyHostService.getPerformanceMarks.apply(this._ptyHostService, args); + case '$orphanQuestionReply': return this._ptyHostService.orphanQuestionReply.apply(this._ptyHostService, args); + case '$acceptPtyHostResolvedVariables': return this._ptyHostService.acceptPtyHostResolvedVariables?.apply(this._ptyHostService, args); - case '$start': return this._ptyService.start.apply(this._ptyService, args); - case '$input': return this._ptyService.input.apply(this._ptyService, args); - case '$acknowledgeDataEvent': return this._ptyService.acknowledgeDataEvent.apply(this._ptyService, args); - case '$shutdown': return this._ptyService.shutdown.apply(this._ptyService, args); - case '$resize': return this._ptyService.resize.apply(this._ptyService, args); - case '$clearBuffer': return this._ptyService.clearBuffer.apply(this._ptyService, args); - case '$getInitialCwd': return this._ptyService.getInitialCwd.apply(this._ptyService, args); - case '$getCwd': return this._ptyService.getCwd.apply(this._ptyService, args); + case '$start': return this._ptyHostService.start.apply(this._ptyHostService, args); + case '$input': return this._ptyHostService.input.apply(this._ptyHostService, args); + case '$acknowledgeDataEvent': return this._ptyHostService.acknowledgeDataEvent.apply(this._ptyHostService, args); + case '$shutdown': return this._ptyHostService.shutdown.apply(this._ptyHostService, args); + case '$resize': return this._ptyHostService.resize.apply(this._ptyHostService, args); + case '$clearBuffer': return this._ptyHostService.clearBuffer.apply(this._ptyHostService, args); + case '$getInitialCwd': return this._ptyHostService.getInitialCwd.apply(this._ptyHostService, args); + case '$getCwd': return this._ptyHostService.getCwd.apply(this._ptyHostService, args); - case '$processBinary': return this._ptyService.processBinary.apply(this._ptyService, args); + case '$processBinary': return this._ptyHostService.processBinary.apply(this._ptyHostService, args); case '$sendCommandResult': return this._sendCommandResult(args[0], args[1], args[2]); - case '$installAutoReply': return this._ptyService.installAutoReply.apply(this._ptyService, args); - case '$uninstallAllAutoReplies': return this._ptyService.uninstallAllAutoReplies.apply(this._ptyService, args); + case '$installAutoReply': return this._ptyHostService.installAutoReply.apply(this._ptyHostService, args); + case '$uninstallAllAutoReplies': return this._ptyHostService.uninstallAllAutoReplies.apply(this._ptyHostService, args); case '$getDefaultSystemShell': return this._getDefaultSystemShell.apply(this, args); case '$getProfiles': return this._getProfiles.apply(this, args); case '$getEnvironment': return this._getEnvironment(); case '$getWslPath': return this._getWslPath(args[0], args[1]); - case '$getTerminalLayoutInfo': return this._ptyService.getTerminalLayoutInfo(args); - case '$setTerminalLayoutInfo': return this._ptyService.setTerminalLayoutInfo(args); - case '$serializeTerminalState': return this._ptyService.serializeTerminalState.apply(this._ptyService, args); - case '$reviveTerminalProcesses': return this._ptyService.reviveTerminalProcesses.apply(this._ptyService, args); - case '$getRevivedPtyNewId': return this._ptyService.getRevivedPtyNewId.apply(this._ptyService, args); - case '$setUnicodeVersion': return this._ptyService.setUnicodeVersion.apply(this._ptyService, args); + case '$getTerminalLayoutInfo': return this._ptyHostService.getTerminalLayoutInfo(args); + case '$setTerminalLayoutInfo': return this._ptyHostService.setTerminalLayoutInfo(args); + case '$serializeTerminalState': return this._ptyHostService.serializeTerminalState.apply(this._ptyHostService, args); + case '$reviveTerminalProcesses': return this._ptyHostService.reviveTerminalProcesses.apply(this._ptyHostService, args); + case '$getRevivedPtyNewId': return this._ptyHostService.getRevivedPtyNewId.apply(this._ptyHostService, args); + case '$setUnicodeVersion': return this._ptyHostService.setUnicodeVersion.apply(this._ptyHostService, args); case '$reduceConnectionGraceTime': return this._reduceConnectionGraceTime(); - case '$updateIcon': return this._ptyService.updateIcon.apply(this._ptyService, args); - case '$updateTitle': return this._ptyService.updateTitle.apply(this._ptyService, args); - case '$updateProperty': return this._ptyService.updateProperty.apply(this._ptyService, args); - case '$refreshProperty': return this._ptyService.refreshProperty.apply(this._ptyService, args); - case '$requestDetachInstance': return this._ptyService.requestDetachInstance(args[0], args[1]); - case '$acceptDetachedInstance': return this._ptyService.acceptDetachInstanceReply(args[0], args[1]); - case '$freePortKillProcess': return this._ptyService.freePortKillProcess?.apply(this._ptyService, args); + case '$updateIcon': return this._ptyHostService.updateIcon.apply(this._ptyHostService, args); + case '$updateTitle': return this._ptyHostService.updateTitle.apply(this._ptyHostService, args); + case '$updateProperty': return this._ptyHostService.updateProperty.apply(this._ptyHostService, args); + case '$refreshProperty': return this._ptyHostService.refreshProperty.apply(this._ptyHostService, args); + case '$requestDetachInstance': return this._ptyHostService.requestDetachInstance(args[0], args[1]); + case '$acceptDetachedInstance': return this._ptyHostService.acceptDetachInstanceReply(args[0], args[1]); + case '$freePortKillProcess': return this._ptyHostService.freePortKillProcess?.apply(this._ptyHostService, args); } throw new Error(`IPC Command ${command} not found`); @@ -160,19 +160,19 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< listen(_: any, event: string, arg: any): Event { switch (event) { - case '$onPtyHostExitEvent': return this._ptyService.onPtyHostExit || Event.None; - case '$onPtyHostStartEvent': return this._ptyService.onPtyHostStart || Event.None; - case '$onPtyHostUnresponsiveEvent': return this._ptyService.onPtyHostUnresponsive || Event.None; - case '$onPtyHostResponsiveEvent': return this._ptyService.onPtyHostResponsive || Event.None; - case '$onPtyHostRequestResolveVariablesEvent': return this._ptyService.onPtyHostRequestResolveVariables || Event.None; - case '$onProcessDataEvent': return this._ptyService.onProcessData; - case '$onProcessReadyEvent': return this._ptyService.onProcessReady; - case '$onProcessExitEvent': return this._ptyService.onProcessExit; - case '$onProcessReplayEvent': return this._ptyService.onProcessReplay; - case '$onProcessOrphanQuestion': return this._ptyService.onProcessOrphanQuestion; + case '$onPtyHostExitEvent': return this._ptyHostService.onPtyHostExit || Event.None; + case '$onPtyHostStartEvent': return this._ptyHostService.onPtyHostStart || Event.None; + case '$onPtyHostUnresponsiveEvent': return this._ptyHostService.onPtyHostUnresponsive || Event.None; + case '$onPtyHostResponsiveEvent': return this._ptyHostService.onPtyHostResponsive || Event.None; + case '$onPtyHostRequestResolveVariablesEvent': return this._ptyHostService.onPtyHostRequestResolveVariables || Event.None; + case '$onProcessDataEvent': return this._ptyHostService.onProcessData; + case '$onProcessReadyEvent': return this._ptyHostService.onProcessReady; + case '$onProcessExitEvent': return this._ptyHostService.onProcessExit; + case '$onProcessReplayEvent': return this._ptyHostService.onProcessReplay; + case '$onProcessOrphanQuestion': return this._ptyHostService.onProcessOrphanQuestion; case '$onExecuteCommand': return this.onExecuteCommand; - case '$onDidRequestDetach': return this._ptyService.onDidRequestDetach || Event.None; - case '$onDidChangeProperty': return this._ptyService.onDidChangeProperty; + case '$onDidRequestDetach': return this._ptyHostService.onDidRequestDetach || Event.None; + case '$onDidChangeProperty': return this._ptyHostService.onDidChangeProperty; default: break; } @@ -251,12 +251,12 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< const ipcHandlePath = createRandomIPCHandle(); env.VSCODE_IPC_HOOK_CLI = ipcHandlePath; - const persistentProcessId = await this._ptyService.createProcess(shellLaunchConfig, initialCwd, args.cols, args.rows, args.unicodeVersion, env, baseEnv, args.options, args.shouldPersistTerminal, args.workspaceId, args.workspaceName); + const persistentProcessId = await this._ptyHostService.createProcess(shellLaunchConfig, initialCwd, args.cols, args.rows, args.unicodeVersion, env, baseEnv, args.options, args.shouldPersistTerminal, args.workspaceId, args.workspaceName); const commandsExecuter: ICommandsExecuter = { executeCommand: (id: string, ...args: any[]): Promise => this._executeCommand(persistentProcessId, id, args, uriTransformer) }; const cliServer = new CLIServerBase(commandsExecuter, this._logService, ipcHandlePath); - this._ptyService.onProcessExit(e => e.id === persistentProcessId && cliServer.dispose()); + this._ptyHostService.onProcessExit(e => e.id === persistentProcessId && cliServer.dispose()); return { persistentTerminalId: persistentProcessId, @@ -316,11 +316,11 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< } private _getDefaultSystemShell(osOverride?: platform.OperatingSystem): Promise { - return this._ptyService.getDefaultSystemShell(osOverride); + return this._ptyHostService.getDefaultSystemShell(osOverride); } private async _getProfiles(workspaceId: string, profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise { - return this._ptyService.getProfiles?.(workspaceId, profiles, defaultProfile, includeDetectedProfiles) || []; + return this._ptyHostService.getProfiles?.(workspaceId, profiles, defaultProfile, includeDetectedProfiles) || []; } private _getEnvironment(): platform.IProcessEnvironment { @@ -328,11 +328,11 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< } private _getWslPath(original: string, direction: 'unix-to-win' | 'win-to-unix'): Promise { - return this._ptyService.getWslPath(original, direction); + return this._ptyHostService.getWslPath(original, direction); } private _reduceConnectionGraceTime(): Promise { - return this._ptyService.reduceConnectionGraceTime(); + return this._ptyHostService.reduceConnectionGraceTime(); } } diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index cc788df0163..af1425f61cb 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -48,7 +48,7 @@ import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/ import { ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import { getPiiPathsFromEnvironment, isInternalTelemetry, ITelemetryAppender, NullAppender, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; import ErrorTelemetry from 'vs/platform/telemetry/node/errorTelemetry'; -import { IPtyService, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; +import { IPtyService, IPtyHostService, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; @@ -197,8 +197,9 @@ export async function setupServerServices(connectionToken: ServerConnectionToken scrollback: configurationService.getValue(TerminalSettingId.PersistentSessionScrollback) ?? 100 } ); - const ptyService = instantiationService.createInstance(PtyHostService, ptyHostStarter); - services.set(IPtyService, ptyService); + const ptyHostService = instantiationService.createInstance(PtyHostService, ptyHostStarter); + services.set(IPtyService, ptyHostService); + services.set(IPtyHostService, ptyHostService); services.set(ICredentialsMainService, new SyncDescriptor(CredentialsWebMainService)); @@ -213,7 +214,7 @@ export async function setupServerServices(connectionToken: ServerConnectionToken const telemetryChannel = new ServerTelemetryChannel(accessor.get(IServerTelemetryService), oneDsAppender); socketServer.registerChannel('telemetry', telemetryChannel); - socketServer.registerChannel(REMOTE_TERMINAL_CHANNEL_NAME, new RemoteTerminalChannel(environmentService, logService, ptyService, productService, extensionManagementService, configurationService)); + socketServer.registerChannel(REMOTE_TERMINAL_CHANNEL_NAME, new RemoteTerminalChannel(environmentService, logService, ptyHostService, productService, extensionManagementService, configurationService)); const remoteExtensionsScanner = new RemoteExtensionsScannerService(instantiationService.createInstance(ExtensionManagementCLI, logService), environmentService, userDataProfilesService, extensionsScannerService, logService, extensionGalleryService, languagePackService); socketServer.registerChannel(RemoteExtensionsScannerChannelName, new RemoteExtensionsScannerChannel(remoteExtensionsScanner, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority))); diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts index ac4c6650e8b..4f976936a55 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts @@ -258,8 +258,7 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke } async getProfiles(profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean) { - // TODO: Differentiate interfaces of direct to pty host and pty host service (or just move them all to pty host) - return this._proxy.getProfiles?.(this._workspaceContextService.getWorkspace().id, profiles, defaultProfile, includeDetectedProfiles) || []; + return this._localPtyService.getProfiles(this._workspaceContextService.getWorkspace().id, profiles, defaultProfile, includeDetectedProfiles) || []; } @memoize From 074121ee30245e06e8b46d20a770285aa0793cde Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:42:22 -0700 Subject: [PATCH 041/119] Remove now unneeded optional checks --- src/vs/server/node/remoteTerminalChannel.ts | 8 +- .../terminal/browser/baseTerminalBackend.ts | 118 ++++++++---------- 2 files changed, 58 insertions(+), 68 deletions(-) diff --git a/src/vs/server/node/remoteTerminalChannel.ts b/src/vs/server/node/remoteTerminalChannel.ts index 8d396c86021..494e2c35f86 100644 --- a/src/vs/server/node/remoteTerminalChannel.ts +++ b/src/vs/server/node/remoteTerminalChannel.ts @@ -107,7 +107,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< async call(ctx: RemoteAgentConnectionContext, command: string, args?: any): Promise { switch (command) { - case '$restartPtyHost': return this._ptyHostService.restartPtyHost?.apply(this._ptyHostService, args); + case '$restartPtyHost': return this._ptyHostService.restartPtyHost.apply(this._ptyHostService, args); case '$createProcess': { const uriTransformer = createURITransformer(ctx.remoteAuthority); @@ -119,7 +119,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< case '$listProcesses': return this._ptyHostService.listProcesses.apply(this._ptyHostService, args); case '$getPerformanceMarks': return this._ptyHostService.getPerformanceMarks.apply(this._ptyHostService, args); case '$orphanQuestionReply': return this._ptyHostService.orphanQuestionReply.apply(this._ptyHostService, args); - case '$acceptPtyHostResolvedVariables': return this._ptyHostService.acceptPtyHostResolvedVariables?.apply(this._ptyHostService, args); + case '$acceptPtyHostResolvedVariables': return this._ptyHostService.acceptPtyHostResolvedVariables.apply(this._ptyHostService, args); case '$start': return this._ptyHostService.start.apply(this._ptyHostService, args); case '$input': return this._ptyHostService.input.apply(this._ptyHostService, args); @@ -152,7 +152,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< case '$refreshProperty': return this._ptyHostService.refreshProperty.apply(this._ptyHostService, args); case '$requestDetachInstance': return this._ptyHostService.requestDetachInstance(args[0], args[1]); case '$acceptDetachedInstance': return this._ptyHostService.acceptDetachInstanceReply(args[0], args[1]); - case '$freePortKillProcess': return this._ptyHostService.freePortKillProcess?.apply(this._ptyHostService, args); + case '$freePortKillProcess': return this._ptyHostService.freePortKillProcess.apply(this._ptyHostService, args); } throw new Error(`IPC Command ${command} not found`); @@ -320,7 +320,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< } private async _getProfiles(workspaceId: string, profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise { - return this._ptyHostService.getProfiles?.(workspaceId, profiles, defaultProfile, includeDetectedProfiles) || []; + return this._ptyHostService.getProfiles(workspaceId, profiles, defaultProfile, includeDetectedProfiles) || []; } private _getEnvironment(): platform.IProcessEnvironment { diff --git a/src/vs/workbench/contrib/terminal/browser/baseTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/baseTerminalBackend.ts index 3b5ab5a0fad..ae7e0824e2e 100644 --- a/src/vs/workbench/contrib/terminal/browser/baseTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/baseTerminalBackend.ts @@ -46,73 +46,63 @@ export abstract class BaseTerminalBackend extends Disposable { let hasStarted = false; // Attach pty host listeners - if (this._ptyHostController.onPtyHostExit) { - this._register(this._ptyHostController.onPtyHostExit(() => { - this._logService.error(`The terminal's pty host process exited, the connection to all terminal processes was lost`); - })); - } - if (this._ptyHostController.onPtyHostStart) { - this.onPtyHostConnected(() => hasStarted = true); - this._register(this._ptyHostController.onPtyHostStart(() => { - this._logService.debug(`The terminal's pty host process is starting`); - // Only fire the _restart_ event after it has started - if (hasStarted) { - this._logService.trace('IPtyHostController#onPtyHostRestart'); - this._onPtyHostRestart.fire(); - } - statusBarAccessor?.dispose(); - this._isPtyHostUnresponsive = false; - })); - } - if (this._ptyHostController.onPtyHostUnresponsive) { - this._register(this._ptyHostController.onPtyHostUnresponsive(() => { - statusBarAccessor?.dispose(); - if (!unresponsiveStatusBarEntry) { - unresponsiveStatusBarEntry = { - name: localize('ptyHostStatus', 'Pty Host Status'), - text: `$(debug-disconnect) ${localize('ptyHostStatus.short', 'Pty Host')}`, - tooltip: localize('nonResponsivePtyHost', "The connection to the terminal's pty host process is unresponsive, terminals may stop working. Click to manually restart the pty host."), - ariaLabel: localize('ptyHostStatus.ariaLabel', 'Pty Host is unresponsive'), - command: TerminalCommandId.RestartPtyHost, - backgroundColor: themeColorFromId(STATUS_BAR_WARNING_ITEM_BACKGROUND), - color: themeColorFromId(STATUS_BAR_WARNING_ITEM_FOREGROUND), - }; - } - statusBarAccessor = statusBarService.addEntry(unresponsiveStatusBarEntry, 'ptyHostStatus', StatusbarAlignment.LEFT); - this._isPtyHostUnresponsive = true; - this._onPtyHostUnresponsive.fire(); - })); - } - if (this._ptyHostController.onPtyHostResponsive) { - this._register(this._ptyHostController.onPtyHostResponsive(() => { - if (!this._isPtyHostUnresponsive) { - return; - } - this._logService.info('The pty host became responsive again'); - statusBarAccessor?.dispose(); - this._isPtyHostUnresponsive = false; - this._onPtyHostResponsive.fire(); - })); - } - if (this._ptyHostController.onPtyHostRequestResolveVariables) { - this._register(this._ptyHostController.onPtyHostRequestResolveVariables(async e => { - // Only answer requests for this workspace - if (e.workspaceId !== this._workspaceContextService.getWorkspace().id) { - return; - } - const activeWorkspaceRootUri = historyService.getLastActiveWorkspaceRoot(Schemas.file); - const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? withNullAsUndefined(this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri)) : undefined; - const resolveCalls: Promise[] = e.originalText.map(t => { - return configurationResolverService.resolveAsync(lastActiveWorkspaceRoot, t); - }); - const result = await Promise.all(resolveCalls); - this._ptyHostController.acceptPtyHostResolvedVariables?.(e.requestId, result); - })); - } + this._register(this._ptyHostController.onPtyHostExit(() => { + this._logService.error(`The terminal's pty host process exited, the connection to all terminal processes was lost`); + })); + this.onPtyHostConnected(() => hasStarted = true); + this._register(this._ptyHostController.onPtyHostStart(() => { + this._logService.debug(`The terminal's pty host process is starting`); + // Only fire the _restart_ event after it has started + if (hasStarted) { + this._logService.trace('IPtyHostController#onPtyHostRestart'); + this._onPtyHostRestart.fire(); + } + statusBarAccessor?.dispose(); + this._isPtyHostUnresponsive = false; + })); + this._register(this._ptyHostController.onPtyHostUnresponsive(() => { + statusBarAccessor?.dispose(); + if (!unresponsiveStatusBarEntry) { + unresponsiveStatusBarEntry = { + name: localize('ptyHostStatus', 'Pty Host Status'), + text: `$(debug-disconnect) ${localize('ptyHostStatus.short', 'Pty Host')}`, + tooltip: localize('nonResponsivePtyHost', "The connection to the terminal's pty host process is unresponsive, terminals may stop working. Click to manually restart the pty host."), + ariaLabel: localize('ptyHostStatus.ariaLabel', 'Pty Host is unresponsive'), + command: TerminalCommandId.RestartPtyHost, + backgroundColor: themeColorFromId(STATUS_BAR_WARNING_ITEM_BACKGROUND), + color: themeColorFromId(STATUS_BAR_WARNING_ITEM_FOREGROUND), + }; + } + statusBarAccessor = statusBarService.addEntry(unresponsiveStatusBarEntry, 'ptyHostStatus', StatusbarAlignment.LEFT); + this._isPtyHostUnresponsive = true; + this._onPtyHostUnresponsive.fire(); + })); + this._register(this._ptyHostController.onPtyHostResponsive(() => { + if (!this._isPtyHostUnresponsive) { + return; + } + this._logService.info('The pty host became responsive again'); + statusBarAccessor?.dispose(); + this._isPtyHostUnresponsive = false; + this._onPtyHostResponsive.fire(); + })); + this._register(this._ptyHostController.onPtyHostRequestResolveVariables(async e => { + // Only answer requests for this workspace + if (e.workspaceId !== this._workspaceContextService.getWorkspace().id) { + return; + } + const activeWorkspaceRootUri = historyService.getLastActiveWorkspaceRoot(Schemas.file); + const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? withNullAsUndefined(this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri)) : undefined; + const resolveCalls: Promise[] = e.originalText.map(t => { + return configurationResolverService.resolveAsync(lastActiveWorkspaceRoot, t); + }); + const result = await Promise.all(resolveCalls); + this._ptyHostController.acceptPtyHostResolvedVariables(e.requestId, result); + })); } restartPtyHost(): void { - this._ptyHostController.restartPtyHost?.(); + this._ptyHostController.restartPtyHost(); } protected _deserializeTerminalState(serializedState: string | undefined): ISerializedTerminalState[] | undefined { From 0d1bc0818c65c189aae2514d3122ae66e6c12b4f Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:45:42 -0700 Subject: [PATCH 042/119] Clean up pty services --- src/vs/platform/terminal/common/terminal.ts | 10 ++++++++-- src/vs/server/node/serverServices.ts | 3 +-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 2f29ede8364..550e3dff813 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -264,7 +264,9 @@ export interface IFixedTerminalDimensions { rows?: number; } -export const IPtyService = createDecorator('ptyService'); +/** + * A service that communicates with a pty host. +*/ export interface IPtyService { readonly _serviceBrand: undefined; @@ -344,6 +346,7 @@ export interface IPtyService { // TODO: Make mandatory and remove impl from pty host service refreshIgnoreProcessNames?(names: string[]): Promise; } +export const IPtyService = createDecorator('ptyService'); export interface IPtyHostController { readonly onPtyHostExit: Event; @@ -357,7 +360,10 @@ export interface IPtyHostController { getProfiles(workspaceId: string, profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise; } -export const IPtyHostService = createDecorator('ptyHostService'); +/** + * A service that communicates with a pty host controller (eg. main or server + * process) and is able to launch and forward requests to the pty host. +*/ export interface IPtyHostService extends IPtyService, IPtyHostController { } diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index af1425f61cb..945743bcd51 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -48,7 +48,7 @@ import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/ import { ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import { getPiiPathsFromEnvironment, isInternalTelemetry, ITelemetryAppender, NullAppender, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; import ErrorTelemetry from 'vs/platform/telemetry/node/errorTelemetry'; -import { IPtyService, IPtyHostService, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; +import { IPtyService, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; @@ -199,7 +199,6 @@ export async function setupServerServices(connectionToken: ServerConnectionToken ); const ptyHostService = instantiationService.createInstance(PtyHostService, ptyHostStarter); services.set(IPtyService, ptyHostService); - services.set(IPtyHostService, ptyHostService); services.set(ICredentialsMainService, new SyncDescriptor(CredentialsWebMainService)); From ab08a18321c4d8aa08fb1ce4713cbed2e59cba4b Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 6 Jul 2023 12:12:56 -0700 Subject: [PATCH 043/119] Use const enum for all remote terminal requests Part of #187176 --- src/vs/server/node/remoteTerminalChannel.ts | 122 +++++++++--------- src/vs/server/node/serverServices.ts | 2 +- .../contrib/terminal/browser/remotePty.ts | 2 +- .../terminal/browser/remoteTerminalBackend.ts | 2 +- .../{ => remote}/remoteTerminalChannel.ts | 97 +++++++------- .../terminal/common/remote/terminal.ts | 99 ++++++++++++++ 6 files changed, 211 insertions(+), 113 deletions(-) rename src/vs/workbench/contrib/terminal/common/{ => remote}/remoteTerminalChannel.ts (73%) create mode 100644 src/vs/workbench/contrib/terminal/common/remote/terminal.ts diff --git a/src/vs/server/node/remoteTerminalChannel.ts b/src/vs/server/node/remoteTerminalChannel.ts index 494e2c35f86..245aa816891 100644 --- a/src/vs/server/node/remoteTerminalChannel.ts +++ b/src/vs/server/node/remoteTerminalChannel.ts @@ -22,7 +22,7 @@ import { CLIServerBase, ICommandsExecuter } from 'vs/workbench/api/node/extHostC import { IEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection'; import { deserializeEnvironmentDescriptionMap, deserializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared'; -import { ICreateTerminalProcessArguments, ICreateTerminalProcessResult, IWorkspaceFolderData } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel'; +import { ICreateTerminalProcessArguments, ICreateTerminalProcessResult, IWorkspaceFolderData, RemoteTerminalChannelEvent, RemoteTerminalChannelRequest } from 'vs/workbench/contrib/terminal/common/remote/terminal'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/common/variableResolver'; import { buildUserEnvironment } from 'vs/server/node/extensionHostConnection'; @@ -105,78 +105,76 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< super(); } - async call(ctx: RemoteAgentConnectionContext, command: string, args?: any): Promise { + async call(ctx: RemoteAgentConnectionContext, command: RemoteTerminalChannelRequest, args?: any): Promise { switch (command) { - case '$restartPtyHost': return this._ptyHostService.restartPtyHost.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.RestartPtyHost: return this._ptyHostService.restartPtyHost.apply(this._ptyHostService, args); - case '$createProcess': { + case RemoteTerminalChannelRequest.CreateProcess: { const uriTransformer = createURITransformer(ctx.remoteAuthority); return this._createProcess(uriTransformer, args); } - case '$attachToProcess': return this._ptyHostService.attachToProcess.apply(this._ptyHostService, args); - case '$detachFromProcess': return this._ptyHostService.detachFromProcess.apply(this._ptyHostService, args); - - case '$listProcesses': return this._ptyHostService.listProcesses.apply(this._ptyHostService, args); - case '$getPerformanceMarks': return this._ptyHostService.getPerformanceMarks.apply(this._ptyHostService, args); - case '$orphanQuestionReply': return this._ptyHostService.orphanQuestionReply.apply(this._ptyHostService, args); - case '$acceptPtyHostResolvedVariables': return this._ptyHostService.acceptPtyHostResolvedVariables.apply(this._ptyHostService, args); - - case '$start': return this._ptyHostService.start.apply(this._ptyHostService, args); - case '$input': return this._ptyHostService.input.apply(this._ptyHostService, args); - case '$acknowledgeDataEvent': return this._ptyHostService.acknowledgeDataEvent.apply(this._ptyHostService, args); - case '$shutdown': return this._ptyHostService.shutdown.apply(this._ptyHostService, args); - case '$resize': return this._ptyHostService.resize.apply(this._ptyHostService, args); - case '$clearBuffer': return this._ptyHostService.clearBuffer.apply(this._ptyHostService, args); - case '$getInitialCwd': return this._ptyHostService.getInitialCwd.apply(this._ptyHostService, args); - case '$getCwd': return this._ptyHostService.getCwd.apply(this._ptyHostService, args); - - case '$processBinary': return this._ptyHostService.processBinary.apply(this._ptyHostService, args); - - case '$sendCommandResult': return this._sendCommandResult(args[0], args[1], args[2]); - case '$installAutoReply': return this._ptyHostService.installAutoReply.apply(this._ptyHostService, args); - case '$uninstallAllAutoReplies': return this._ptyHostService.uninstallAllAutoReplies.apply(this._ptyHostService, args); - case '$getDefaultSystemShell': return this._getDefaultSystemShell.apply(this, args); - case '$getProfiles': return this._getProfiles.apply(this, args); - case '$getEnvironment': return this._getEnvironment(); - case '$getWslPath': return this._getWslPath(args[0], args[1]); - case '$getTerminalLayoutInfo': return this._ptyHostService.getTerminalLayoutInfo(args); - case '$setTerminalLayoutInfo': return this._ptyHostService.setTerminalLayoutInfo(args); - case '$serializeTerminalState': return this._ptyHostService.serializeTerminalState.apply(this._ptyHostService, args); - case '$reviveTerminalProcesses': return this._ptyHostService.reviveTerminalProcesses.apply(this._ptyHostService, args); - case '$getRevivedPtyNewId': return this._ptyHostService.getRevivedPtyNewId.apply(this._ptyHostService, args); - case '$setUnicodeVersion': return this._ptyHostService.setUnicodeVersion.apply(this._ptyHostService, args); - case '$reduceConnectionGraceTime': return this._reduceConnectionGraceTime(); - case '$updateIcon': return this._ptyHostService.updateIcon.apply(this._ptyHostService, args); - case '$updateTitle': return this._ptyHostService.updateTitle.apply(this._ptyHostService, args); - case '$updateProperty': return this._ptyHostService.updateProperty.apply(this._ptyHostService, args); - case '$refreshProperty': return this._ptyHostService.refreshProperty.apply(this._ptyHostService, args); - case '$requestDetachInstance': return this._ptyHostService.requestDetachInstance(args[0], args[1]); - case '$acceptDetachedInstance': return this._ptyHostService.acceptDetachInstanceReply(args[0], args[1]); - case '$freePortKillProcess': return this._ptyHostService.freePortKillProcess.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.AttachToProcess: return this._ptyHostService.attachToProcess.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.DetachFromProcess: return this._ptyHostService.detachFromProcess.apply(this._ptyHostService, args); + + case RemoteTerminalChannelRequest.ListProcesses: return this._ptyHostService.listProcesses.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.GetPerformanceMarks: return this._ptyHostService.getPerformanceMarks.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.OrphanQuestionReply: return this._ptyHostService.orphanQuestionReply.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.AcceptPtyHostResolvedVariables: return this._ptyHostService.acceptPtyHostResolvedVariables.apply(this._ptyHostService, args); + + case RemoteTerminalChannelRequest.Start: return this._ptyHostService.start.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.Input: return this._ptyHostService.input.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.AcknowledgeDataEvent: return this._ptyHostService.acknowledgeDataEvent.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.Shutdown: return this._ptyHostService.shutdown.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.Resize: return this._ptyHostService.resize.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.ClearBuffer: return this._ptyHostService.clearBuffer.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.GetInitialCwd: return this._ptyHostService.getInitialCwd.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.GetCwd: return this._ptyHostService.getCwd.apply(this._ptyHostService, args); + + case RemoteTerminalChannelRequest.ProcessBinary: return this._ptyHostService.processBinary.apply(this._ptyHostService, args); + + case RemoteTerminalChannelRequest.SendCommandResult: return this._sendCommandResult(args[0], args[1], args[2]); + case RemoteTerminalChannelRequest.InstallAutoReply: return this._ptyHostService.installAutoReply.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.UninstallAllAutoReplies: return this._ptyHostService.uninstallAllAutoReplies.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.GetDefaultSystemShell: return this._getDefaultSystemShell.apply(this, args); + case RemoteTerminalChannelRequest.GetProfiles: return this._getProfiles.apply(this, args); + case RemoteTerminalChannelRequest.GetEnvironment: return this._getEnvironment(); + case RemoteTerminalChannelRequest.GetWslPath: return this._getWslPath(args[0], args[1]); + case RemoteTerminalChannelRequest.GetTerminalLayoutInfo: return this._ptyHostService.getTerminalLayoutInfo(args); + case RemoteTerminalChannelRequest.SetTerminalLayoutInfo: return this._ptyHostService.setTerminalLayoutInfo(args); + case RemoteTerminalChannelRequest.SerializeTerminalState: return this._ptyHostService.serializeTerminalState.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.ReviveTerminalProcesses: return this._ptyHostService.reviveTerminalProcesses.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.GetRevivedPtyNewId: return this._ptyHostService.getRevivedPtyNewId.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.SetUnicodeVersion: return this._ptyHostService.setUnicodeVersion.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.ReduceConnectionGraceTime: return this._reduceConnectionGraceTime(); + case RemoteTerminalChannelRequest.UpdateIcon: return this._ptyHostService.updateIcon.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.UpdateTitle: return this._ptyHostService.updateTitle.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.UpdateProperty: return this._ptyHostService.updateProperty.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.RefreshProperty: return this._ptyHostService.refreshProperty.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.RequestDetachInstance: return this._ptyHostService.requestDetachInstance(args[0], args[1]); + case RemoteTerminalChannelRequest.AcceptDetachedInstance: return this._ptyHostService.acceptDetachInstanceReply(args[0], args[1]); + case RemoteTerminalChannelRequest.FreePortKillProcess: return this._ptyHostService.freePortKillProcess.apply(this._ptyHostService, args); + default: break; } - throw new Error(`IPC Command ${command} not found`); } - listen(_: any, event: string, arg: any): Event { + listen(_: any, event: RemoteTerminalChannelEvent, arg: any): Event { switch (event) { - case '$onPtyHostExitEvent': return this._ptyHostService.onPtyHostExit || Event.None; - case '$onPtyHostStartEvent': return this._ptyHostService.onPtyHostStart || Event.None; - case '$onPtyHostUnresponsiveEvent': return this._ptyHostService.onPtyHostUnresponsive || Event.None; - case '$onPtyHostResponsiveEvent': return this._ptyHostService.onPtyHostResponsive || Event.None; - case '$onPtyHostRequestResolveVariablesEvent': return this._ptyHostService.onPtyHostRequestResolveVariables || Event.None; - case '$onProcessDataEvent': return this._ptyHostService.onProcessData; - case '$onProcessReadyEvent': return this._ptyHostService.onProcessReady; - case '$onProcessExitEvent': return this._ptyHostService.onProcessExit; - case '$onProcessReplayEvent': return this._ptyHostService.onProcessReplay; - case '$onProcessOrphanQuestion': return this._ptyHostService.onProcessOrphanQuestion; - case '$onExecuteCommand': return this.onExecuteCommand; - case '$onDidRequestDetach': return this._ptyHostService.onDidRequestDetach || Event.None; - case '$onDidChangeProperty': return this._ptyHostService.onDidChangeProperty; - default: - break; + case RemoteTerminalChannelEvent.OnPtyHostExitEvent: return this._ptyHostService.onPtyHostExit || Event.None; + case RemoteTerminalChannelEvent.OnPtyHostStartEvent: return this._ptyHostService.onPtyHostStart || Event.None; + case RemoteTerminalChannelEvent.OnPtyHostUnresponsiveEvent: return this._ptyHostService.onPtyHostUnresponsive || Event.None; + case RemoteTerminalChannelEvent.OnPtyHostResponsiveEvent: return this._ptyHostService.onPtyHostResponsive || Event.None; + case RemoteTerminalChannelEvent.OnPtyHostRequestResolveVariablesEvent: return this._ptyHostService.onPtyHostRequestResolveVariables || Event.None; + case RemoteTerminalChannelEvent.OnProcessDataEvent: return this._ptyHostService.onProcessData; + case RemoteTerminalChannelEvent.OnProcessReadyEvent: return this._ptyHostService.onProcessReady; + case RemoteTerminalChannelEvent.OnProcessExitEvent: return this._ptyHostService.onProcessExit; + case RemoteTerminalChannelEvent.OnProcessReplayEvent: return this._ptyHostService.onProcessReplay; + case RemoteTerminalChannelEvent.OnProcessOrphanQuestion: return this._ptyHostService.onProcessOrphanQuestion; + case RemoteTerminalChannelEvent.OnExecuteCommand: return this.onExecuteCommand; + case RemoteTerminalChannelEvent.OnDidRequestDetach: return this._ptyHostService.onDidRequestDetach || Event.None; + case RemoteTerminalChannelEvent.OnDidChangeProperty: return this._ptyHostService.onDidChangeProperty; + default: break; } - throw new Error('Not supported'); } diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index 945743bcd51..910bbe0e5d1 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -60,7 +60,7 @@ import { RemoteTerminalChannel } from 'vs/server/node/remoteTerminalChannel'; import { createURITransformer } from 'vs/workbench/api/node/uriTransformer'; import { ServerConnectionToken } from 'vs/server/node/serverConnectionToken'; import { ServerEnvironmentService, ServerParsedArgs } from 'vs/server/node/serverEnvironmentService'; -import { REMOTE_TERMINAL_CHANNEL_NAME } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel'; +import { REMOTE_TERMINAL_CHANNEL_NAME } from 'vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel'; import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from 'vs/workbench/services/remote/common/remoteFileSystemProviderClient'; import { ExtensionHostStatusService, IExtensionHostStatusService } from 'vs/server/node/extensionHostStatusService'; import { IExtensionsScannerService } from 'vs/platform/extensionManagement/common/extensionsScannerService'; diff --git a/src/vs/workbench/contrib/terminal/browser/remotePty.ts b/src/vs/workbench/contrib/terminal/browser/remotePty.ts index c1d0428d18d..112b0bb80d2 100644 --- a/src/vs/workbench/contrib/terminal/browser/remotePty.ts +++ b/src/vs/workbench/contrib/terminal/browser/remotePty.ts @@ -10,7 +10,7 @@ import { mark } from 'vs/base/common/performance'; import { URI } from 'vs/base/common/uri'; import { IPtyHostProcessReplayEvent, ISerializedCommandDetectionCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { IProcessDataEvent, ITerminalChildProcess, ITerminalLaunchError, IProcessProperty, IProcessPropertyMap, ProcessPropertyType, IProcessReadyEvent, ITerminalLogService } from 'vs/platform/terminal/common/terminal'; -import { RemoteTerminalChannelClient } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel'; +import { RemoteTerminalChannelClient } from 'vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; export class RemotePty extends Disposable implements ITerminalChildProcess { diff --git a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts index 7c79670a1f1..3490820c749 100644 --- a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts @@ -22,7 +22,7 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { BaseTerminalBackend } from 'vs/workbench/contrib/terminal/browser/baseTerminalBackend'; import { RemotePty } from 'vs/workbench/contrib/terminal/browser/remotePty'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { RemoteTerminalChannelClient, REMOTE_TERMINAL_CHANNEL_NAME } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel'; +import { RemoteTerminalChannelClient, REMOTE_TERMINAL_CHANNEL_NAME } from 'vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel'; import { ICompleteTerminalConfiguration, ITerminalConfiguration, TERMINAL_CONFIG_SECTION } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalStorageKeys } from 'vs/workbench/contrib/terminal/common/terminalStorageKeys'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; diff --git a/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts b/src/vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel.ts similarity index 73% rename from src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts rename to src/vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel.ts index 7bc8afac147..c66a1ec185a 100644 --- a/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts +++ b/src/vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel.ts @@ -24,6 +24,7 @@ import { ICompleteTerminalConfiguration } from 'vs/workbench/contrib/terminal/co import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/capabilities/capabilities'; import { ISerializableEnvironmentDescriptionMap as ISerializableEnvironmentDescriptionMap, ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; import type * as performance from 'vs/base/common/performance'; +import { RemoteTerminalChannelEvent, RemoteTerminalChannelRequest } from 'vs/workbench/contrib/terminal/common/remote/terminal'; export const REMOTE_TERMINAL_CHANNEL_NAME = 'remoteterminal'; @@ -60,43 +61,43 @@ export interface ICreateTerminalProcessResult { export class RemoteTerminalChannelClient implements IPtyHostController { get onPtyHostExit(): Event { - return this._channel.listen('$onPtyHostExitEvent'); + return this._channel.listen(RemoteTerminalChannelEvent.OnPtyHostExitEvent); } get onPtyHostStart(): Event { - return this._channel.listen('$onPtyHostStartEvent'); + return this._channel.listen(RemoteTerminalChannelEvent.OnPtyHostStartEvent); } get onPtyHostUnresponsive(): Event { - return this._channel.listen('$onPtyHostUnresponsiveEvent'); + return this._channel.listen(RemoteTerminalChannelEvent.OnPtyHostUnresponsiveEvent); } get onPtyHostResponsive(): Event { - return this._channel.listen('$onPtyHostResponsiveEvent'); + return this._channel.listen(RemoteTerminalChannelEvent.OnPtyHostResponsiveEvent); } get onPtyHostRequestResolveVariables(): Event { - return this._channel.listen('$onPtyHostRequestResolveVariablesEvent'); + return this._channel.listen(RemoteTerminalChannelEvent.OnPtyHostRequestResolveVariablesEvent); } get onProcessData(): Event<{ id: number; event: IProcessDataEvent | string }> { - return this._channel.listen<{ id: number; event: IProcessDataEvent | string }>('$onProcessDataEvent'); + return this._channel.listen<{ id: number; event: IProcessDataEvent | string }>(RemoteTerminalChannelEvent.OnProcessDataEvent); } get onProcessExit(): Event<{ id: number; event: number | undefined }> { - return this._channel.listen<{ id: number; event: number | undefined }>('$onProcessExitEvent'); + return this._channel.listen<{ id: number; event: number | undefined }>(RemoteTerminalChannelEvent.OnProcessExitEvent); } get onProcessReady(): Event<{ id: number; event: IProcessReadyEvent }> { - return this._channel.listen<{ id: number; event: IProcessReadyEvent }>('$onProcessReadyEvent'); + return this._channel.listen<{ id: number; event: IProcessReadyEvent }>(RemoteTerminalChannelEvent.OnProcessReadyEvent); } get onProcessReplay(): Event<{ id: number; event: IPtyHostProcessReplayEvent }> { - return this._channel.listen<{ id: number; event: IPtyHostProcessReplayEvent }>('$onProcessReplayEvent'); + return this._channel.listen<{ id: number; event: IPtyHostProcessReplayEvent }>(RemoteTerminalChannelEvent.OnProcessReplayEvent); } get onProcessOrphanQuestion(): Event<{ id: number }> { - return this._channel.listen<{ id: number }>('$onProcessOrphanQuestion'); + return this._channel.listen<{ id: number }>(RemoteTerminalChannelEvent.OnProcessOrphanQuestion); } get onExecuteCommand(): Event<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: any[] }> { - return this._channel.listen<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: any[] }>('$onExecuteCommand'); + return this._channel.listen<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: any[] }>(RemoteTerminalChannelEvent.OnExecuteCommand); } get onDidRequestDetach(): Event<{ requestId: number; workspaceId: string; instanceId: number }> { - return this._channel.listen<{ requestId: number; workspaceId: string; instanceId: number }>('$onDidRequestDetach'); + return this._channel.listen<{ requestId: number; workspaceId: string; instanceId: number }>(RemoteTerminalChannelEvent.OnDidRequestDetach); } get onDidChangeProperty(): Event<{ id: number; property: IProcessProperty }> { - return this._channel.listen<{ id: number; property: IProcessProperty }>('$onDidChangeProperty'); + return this._channel.listen<{ id: number; property: IProcessProperty }>(RemoteTerminalChannelEvent.OnDidChangeProperty); } constructor( @@ -113,7 +114,7 @@ export class RemoteTerminalChannelClient implements IPtyHostController { ) { } restartPtyHost(): Promise { - return this._channel.call('$restartPtyHost', []); + return this._channel.call(RemoteTerminalChannelRequest.RestartPtyHost, []); } async createProcess( @@ -188,87 +189,87 @@ export class RemoteTerminalChannelClient implements IPtyHostController { } requestDetachInstance(workspaceId: string, instanceId: number): Promise { - return this._channel.call('$requestDetachInstance', [workspaceId, instanceId]); + return this._channel.call(RemoteTerminalChannelRequest.RequestDetachInstance, [workspaceId, instanceId]); } acceptDetachInstanceReply(requestId: number, persistentProcessId: number): Promise { - return this._channel.call('$acceptDetachInstanceReply', [requestId, persistentProcessId]); + return this._channel.call(RemoteTerminalChannelRequest.AcceptDetachInstanceReply, [requestId, persistentProcessId]); } attachToProcess(id: number): Promise { - return this._channel.call('$attachToProcess', [id]); + return this._channel.call(RemoteTerminalChannelRequest.AttachToProcess, [id]); } detachFromProcess(id: number, forcePersist?: boolean): Promise { - return this._channel.call('$detachFromProcess', [id, forcePersist]); + return this._channel.call(RemoteTerminalChannelRequest.DetachFromProcess, [id, forcePersist]); } listProcesses(): Promise { - return this._channel.call('$listProcesses'); + return this._channel.call(RemoteTerminalChannelRequest.ListProcesses); } getPerformanceMarks(): Promise { - return this._channel.call('$getPerformanceMarks'); + return this._channel.call(RemoteTerminalChannelRequest.GetPerformanceMarks); } reduceConnectionGraceTime(): Promise { - return this._channel.call('$reduceConnectionGraceTime'); + return this._channel.call(RemoteTerminalChannelRequest.ReduceConnectionGraceTime); } processBinary(id: number, data: string): Promise { - return this._channel.call('$processBinary', [id, data]); + return this._channel.call(RemoteTerminalChannelRequest.ProcessBinary, [id, data]); } start(id: number): Promise { - return this._channel.call('$start', [id]); + return this._channel.call(RemoteTerminalChannelRequest.Start, [id]); } input(id: number, data: string): Promise { - return this._channel.call('$input', [id, data]); + return this._channel.call(RemoteTerminalChannelRequest.Input, [id, data]); } acknowledgeDataEvent(id: number, charCount: number): Promise { - return this._channel.call('$acknowledgeDataEvent', [id, charCount]); + return this._channel.call(RemoteTerminalChannelRequest.AcknowledgeDataEvent, [id, charCount]); } setUnicodeVersion(id: number, version: '6' | '11'): Promise { - return this._channel.call('$setUnicodeVersion', [id, version]); + return this._channel.call(RemoteTerminalChannelRequest.SetUnicodeVersion, [id, version]); } shutdown(id: number, immediate: boolean): Promise { - return this._channel.call('$shutdown', [id, immediate]); + return this._channel.call(RemoteTerminalChannelRequest.Shutdown, [id, immediate]); } resize(id: number, cols: number, rows: number): Promise { - return this._channel.call('$resize', [id, cols, rows]); + return this._channel.call(RemoteTerminalChannelRequest.Resize, [id, cols, rows]); } clearBuffer(id: number): Promise { - return this._channel.call('$clearBuffer', [id]); + return this._channel.call(RemoteTerminalChannelRequest.ClearBuffer, [id]); } getInitialCwd(id: number): Promise { - return this._channel.call('$getInitialCwd', [id]); + return this._channel.call(RemoteTerminalChannelRequest.GetInitialCwd, [id]); } getCwd(id: number): Promise { - return this._channel.call('$getCwd', [id]); + return this._channel.call(RemoteTerminalChannelRequest.GetCwd, [id]); } orphanQuestionReply(id: number): Promise { - return this._channel.call('$orphanQuestionReply', [id]); + return this._channel.call(RemoteTerminalChannelRequest.OrphanQuestionReply, [id]); } sendCommandResult(reqId: number, isError: boolean, payload: any): Promise { - return this._channel.call('$sendCommandResult', [reqId, isError, payload]); + return this._channel.call(RemoteTerminalChannelRequest.SendCommandResult, [reqId, isError, payload]); } freePortKillProcess(port: string): Promise<{ port: string; processId: string }> { - return this._channel.call('$freePortKillProcess', [port]); + return this._channel.call(RemoteTerminalChannelRequest.FreePortKillProcess, [port]); } installAutoReply(match: string, reply: string): Promise { - return this._channel.call('$installAutoReply', [match, reply]); + return this._channel.call(RemoteTerminalChannelRequest.InstallAutoReply, [match, reply]); } uninstallAllAutoReplies(): Promise { - return this._channel.call('$uninstallAllAutoReplies', []); + return this._channel.call(RemoteTerminalChannelRequest.UninstallAllAutoReplies, []); } getDefaultSystemShell(osOverride?: OperatingSystem): Promise { - return this._channel.call('$getDefaultSystemShell', [osOverride]); + return this._channel.call(RemoteTerminalChannelRequest.GetDefaultSystemShell, [osOverride]); } getProfiles(profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise { - return this._channel.call('$getProfiles', [this._workspaceContextService.getWorkspace().id, profiles, defaultProfile, includeDetectedProfiles]); + return this._channel.call(RemoteTerminalChannelRequest.GetProfiles, [this._workspaceContextService.getWorkspace().id, profiles, defaultProfile, includeDetectedProfiles]); } acceptPtyHostResolvedVariables(requestId: number, resolved: string[]): Promise { - return this._channel.call('$acceptPtyHostResolvedVariables', [requestId, resolved]); + return this._channel.call(RemoteTerminalChannelRequest.AcceptPtyHostResolvedVariables, [requestId, resolved]); } getEnvironment(): Promise { - return this._channel.call('$getEnvironment'); + return this._channel.call(RemoteTerminalChannelRequest.GetEnvironment); } getWslPath(original: string, direction: 'unix-to-win' | 'win-to-unix'): Promise { - return this._channel.call('$getWslPath', [original, direction]); + return this._channel.call(RemoteTerminalChannelRequest.GetWslPath, [original, direction]); } setTerminalLayoutInfo(layout?: ITerminalsLayoutInfoById): Promise { @@ -281,19 +282,19 @@ export class RemoteTerminalChannelClient implements IPtyHostController { } updateTitle(id: number, title: string, titleSource: TitleEventSource): Promise { - return this._channel.call('$updateTitle', [id, title, titleSource]); + return this._channel.call(RemoteTerminalChannelRequest.UpdateTitle, [id, title, titleSource]); } updateIcon(id: number, userInitiated: boolean, icon: TerminalIcon, color?: string): Promise { - return this._channel.call('$updateIcon', [id, userInitiated, icon, color]); + return this._channel.call(RemoteTerminalChannelRequest.UpdateIcon, [id, userInitiated, icon, color]); } refreshProperty(id: number, property: T): Promise { - return this._channel.call('$refreshProperty', [id, property]); + return this._channel.call(RemoteTerminalChannelRequest.RefreshProperty, [id, property]); } updateProperty(id: number, property: T, value: IProcessPropertyMap[T]): Promise { - return this._channel.call('$updateProperty', [id, property, value]); + return this._channel.call(RemoteTerminalChannelRequest.UpdateProperty, [id, property, value]); } getTerminalLayoutInfo(): Promise { @@ -305,14 +306,14 @@ export class RemoteTerminalChannelClient implements IPtyHostController { } reviveTerminalProcesses(state: ISerializedTerminalState[], dateTimeFormatLocate: string): Promise { - return this._channel.call('$reviveTerminalProcesses', [state, dateTimeFormatLocate]); + return this._channel.call(RemoteTerminalChannelRequest.ReviveTerminalProcesses, [state, dateTimeFormatLocate]); } getRevivedPtyNewId(id: number): Promise { - return this._channel.call('$getRevivedPtyNewId', [id]); + return this._channel.call(RemoteTerminalChannelRequest.GetRevivedPtyNewId, [id]); } serializeTerminalState(ids: number[]): Promise { - return this._channel.call('$serializeTerminalState', [ids]); + return this._channel.call(RemoteTerminalChannelRequest.SerializeTerminalState, [ids]); } } diff --git a/src/vs/workbench/contrib/terminal/common/remote/terminal.ts b/src/vs/workbench/contrib/terminal/common/remote/terminal.ts new file mode 100644 index 00000000000..a4ddd1af68b --- /dev/null +++ b/src/vs/workbench/contrib/terminal/common/remote/terminal.ts @@ -0,0 +1,99 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { UriComponents } from 'vs/base/common/uri'; +import { IShellLaunchConfigDto, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal'; +import { ICompleteTerminalConfiguration } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ISerializableEnvironmentDescriptionMap as ISerializableEnvironmentDescriptionMap, ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; + +export const REMOTE_TERMINAL_CHANNEL_NAME = 'remoteterminal'; + +export type ITerminalEnvironmentVariableCollections = [string, ISerializableEnvironmentVariableCollection, ISerializableEnvironmentDescriptionMap][]; + +export interface IWorkspaceFolderData { + uri: UriComponents; + name: string; + index: number; +} + +export interface ICreateTerminalProcessArguments { + configuration: ICompleteTerminalConfiguration; + resolvedVariables: { [name: string]: string }; + envVariableCollections: ITerminalEnvironmentVariableCollections; + shellLaunchConfig: IShellLaunchConfigDto; + workspaceId: string; + workspaceName: string; + workspaceFolders: IWorkspaceFolderData[]; + activeWorkspaceFolder: IWorkspaceFolderData | null; + activeFileResource: UriComponents | undefined; + shouldPersistTerminal: boolean; + options: ITerminalProcessOptions; + cols: number; + rows: number; + unicodeVersion: '6' | '11'; + resolverEnv: { [key: string]: string | null } | undefined; +} + +export interface ICreateTerminalProcessResult { + persistentTerminalId: number; + resolvedShellLaunchConfig: IShellLaunchConfigDto; +} + +export const enum RemoteTerminalChannelEvent { + OnPtyHostExitEvent = '$onPtyHostExitEvent', + OnPtyHostStartEvent = '$onPtyHostStartEvent', + OnPtyHostUnresponsiveEvent = '$onPtyHostUnresponsiveEvent', + OnPtyHostResponsiveEvent = '$onPtyHostResponsiveEvent', + OnPtyHostRequestResolveVariablesEvent = '$onPtyHostRequestResolveVariablesEvent', + OnProcessDataEvent = '$onProcessDataEvent', + OnProcessReadyEvent = '$onProcessReadyEvent', + OnProcessExitEvent = '$onProcessExitEvent', + OnProcessReplayEvent = '$onProcessReplayEvent', + OnProcessOrphanQuestion = '$onProcessOrphanQuestion', + OnExecuteCommand = '$onExecuteCommand', + OnDidRequestDetach = '$onDidRequestDetach', + OnDidChangeProperty = '$onDidChangeProperty', +} + +export const enum RemoteTerminalChannelRequest { + RestartPtyHost = '$restartPtyHost', + CreateProcess = '$createProcess', + AttachToProcess = '$attachToProcess', + DetachFromProcess = '$detachFromProcess', + ListProcesses = '$listProcesses', + GetPerformanceMarks = '$getPerformanceMarks', + OrphanQuestionReply = '$orphanQuestionReply', + AcceptPtyHostResolvedVariables = '$acceptPtyHostResolvedVariables', + Start = '$start', + Input = '$input', + AcknowledgeDataEvent = '$acknowledgeDataEvent', + Shutdown = '$shutdown', + Resize = '$resize', + ClearBuffer = '$clearBuffer', + GetInitialCwd = '$getInitialCwd', + GetCwd = '$getCwd', + ProcessBinary = '$processBinary', + SendCommandResult = '$sendCommandResult', + InstallAutoReply = '$installAutoReply', + UninstallAllAutoReplies = '$uninstallAllAutoReplies', + GetDefaultSystemShell = '$getDefaultSystemShell', + GetProfiles = '$getProfiles', + GetEnvironment = '$getEnvironment', + GetWslPath = '$getWslPath', + GetTerminalLayoutInfo = '$getTerminalLayoutInfo', + SetTerminalLayoutInfo = '$setTerminalLayoutInfo', + SerializeTerminalState = '$serializeTerminalState', + ReviveTerminalProcesses = '$reviveTerminalProcesses', + GetRevivedPtyNewId = '$getRevivedPtyNewId', + SetUnicodeVersion = '$setUnicodeVersion', + ReduceConnectionGraceTime = '$reduceConnectionGraceTime', + UpdateIcon = '$updateIcon', + UpdateTitle = '$updateTitle', + UpdateProperty = '$updateProperty', + RefreshProperty = '$refreshProperty', + RequestDetachInstance = '$requestDetachInstance', + AcceptDetachedInstance = '$acceptDetachedInstance', + FreePortKillProcess = '$freePortKillProcess', +} From d630142d45eaea62c284b2d1ed93c5ff6a52016a Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 6 Jul 2023 12:24:18 -0700 Subject: [PATCH 044/119] Add AcceptDetachInstanceReply impl and add ts assert for future --- src/vs/server/node/remoteTerminalChannel.ts | 9 ++++++--- .../workbench/contrib/terminal/common/remote/terminal.ts | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/vs/server/node/remoteTerminalChannel.ts b/src/vs/server/node/remoteTerminalChannel.ts index 245aa816891..45aa12024c4 100644 --- a/src/vs/server/node/remoteTerminalChannel.ts +++ b/src/vs/server/node/remoteTerminalChannel.ts @@ -153,8 +153,10 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< case RemoteTerminalChannelRequest.RequestDetachInstance: return this._ptyHostService.requestDetachInstance(args[0], args[1]); case RemoteTerminalChannelRequest.AcceptDetachedInstance: return this._ptyHostService.acceptDetachInstanceReply(args[0], args[1]); case RemoteTerminalChannelRequest.FreePortKillProcess: return this._ptyHostService.freePortKillProcess.apply(this._ptyHostService, args); - default: break; + case RemoteTerminalChannelRequest.AcceptDetachInstanceReply: return this._ptyHostService.acceptDetachInstanceReply.apply(this._ptyHostService, args); } + + // @ts-expect-error Assert command is never to ensure all messages are handled throw new Error(`IPC Command ${command} not found`); } @@ -173,9 +175,10 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< case RemoteTerminalChannelEvent.OnExecuteCommand: return this.onExecuteCommand; case RemoteTerminalChannelEvent.OnDidRequestDetach: return this._ptyHostService.onDidRequestDetach || Event.None; case RemoteTerminalChannelEvent.OnDidChangeProperty: return this._ptyHostService.onDidChangeProperty; - default: break; } - throw new Error('Not supported'); + + // @ts-expect-error Assert event is never to ensure all messages are handled + throw new Error(`IPC Command ${event} not found`); } private async _createProcess(uriTransformer: IURITransformer, args: ICreateTerminalProcessArguments): Promise { diff --git a/src/vs/workbench/contrib/terminal/common/remote/terminal.ts b/src/vs/workbench/contrib/terminal/common/remote/terminal.ts index a4ddd1af68b..22aa8cf6dc4 100644 --- a/src/vs/workbench/contrib/terminal/common/remote/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/remote/terminal.ts @@ -94,6 +94,7 @@ export const enum RemoteTerminalChannelRequest { UpdateProperty = '$updateProperty', RefreshProperty = '$refreshProperty', RequestDetachInstance = '$requestDetachInstance', + AcceptDetachInstanceReply = '$acceptDetachInstanceReply', AcceptDetachedInstance = '$acceptDetachedInstance', FreePortKillProcess = '$freePortKillProcess', } From 1391e9a686764da51d80cc17f5e050af736649f0 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 6 Jul 2023 12:41:03 -0700 Subject: [PATCH 045/119] Add workspace id to terminal logs Fixes #187080 --- .../terminal/common/terminalLogService.ts | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/terminal/common/terminalLogService.ts b/src/vs/platform/terminal/common/terminalLogService.ts index 318dce06221..3e1e1a5ca69 100644 --- a/src/vs/platform/terminal/common/terminalLogService.ts +++ b/src/vs/platform/terminal/common/terminalLogService.ts @@ -8,6 +8,7 @@ import { Event } from 'vs/base/common/event'; import { localize } from 'vs/nls'; import { ILogger, ILoggerService, LogLevel } from 'vs/platform/log/common/log'; import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; export class TerminalLogService extends Disposable implements ITerminalLogService { declare _serviceBrand: undefined; @@ -15,19 +16,41 @@ export class TerminalLogService extends Disposable implements ITerminalLogServic private readonly _logger: ILogger; + private _workspaceId!: string; + get onDidChangeLogLevel(): Event { return this._logger.onDidChangeLogLevel; } - constructor(@ILoggerService private readonly _loggerService: ILoggerService) { + constructor( + @ILoggerService private readonly _loggerService: ILoggerService, + @IWorkspaceContextService workspaceContextService: IWorkspaceContextService + ) { super(); this._logger = this._loggerService.createLogger('terminal', { name: localize('terminalLoggerName', 'Terminal') }); + this._register(Event.runAndSubscribe(workspaceContextService.onDidChangeWorkspaceFolders, () => { + this._workspaceId = workspaceContextService.getWorkspace().id.substring(0, 7); + })); } getLevel(): LogLevel { return this._logger.getLevel(); } setLevel(level: LogLevel): void { this._logger.setLevel(level); } - trace(message: string, ...args: any[]): void { this._logger.trace(message, args); } - debug(message: string, ...args: any[]): void { this._logger.debug(message, args); } - info(message: string, ...args: any[]): void { this._logger.info(message, args); } - warn(message: string, ...args: any[]): void { this._logger.warn(message, args); } - error(message: string | Error, ...args: any[]): void { this._logger.error(message, args); } flush(): void { this._logger.flush(); } + + trace(message: string, ...args: any[]): void { this._logger.trace(this._formatMessage(message), args); } + debug(message: string, ...args: any[]): void { this._logger.debug(this._formatMessage(message), args); } + info(message: string, ...args: any[]): void { this._logger.info(this._formatMessage(message), args); } + warn(message: string, ...args: any[]): void { this._logger.warn(this._formatMessage(message), args); } + error(message: string | Error, ...args: any[]): void { + if (message instanceof Error) { + this._logger.error(this._formatMessage(''), message, args); + return; + } + this._logger.error(this._formatMessage(message), args); + } + + private _formatMessage(message: string): string { + if (this._logger.getLevel() === LogLevel.Trace) { + return `[${this._workspaceId}] ${message}`; + } + return message; + } } From a50fca31934ac6d93c2ba2122db2016be9be4617 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 6 Jul 2023 12:45:12 -0700 Subject: [PATCH 046/119] Clarify it's talking about the type never --- src/vs/server/node/remoteTerminalChannel.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/server/node/remoteTerminalChannel.ts b/src/vs/server/node/remoteTerminalChannel.ts index 45aa12024c4..df9943918ee 100644 --- a/src/vs/server/node/remoteTerminalChannel.ts +++ b/src/vs/server/node/remoteTerminalChannel.ts @@ -156,7 +156,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< case RemoteTerminalChannelRequest.AcceptDetachInstanceReply: return this._ptyHostService.acceptDetachInstanceReply.apply(this._ptyHostService, args); } - // @ts-expect-error Assert command is never to ensure all messages are handled + // @ts-expect-error Assert command is the `never` type to ensure all messages are handled throw new Error(`IPC Command ${command} not found`); } @@ -177,7 +177,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< case RemoteTerminalChannelEvent.OnDidChangeProperty: return this._ptyHostService.onDidChangeProperty; } - // @ts-expect-error Assert event is never to ensure all messages are handled + // @ts-expect-error Assert event is the `never` type to ensure all messages are handled throw new Error(`IPC Command ${event} not found`); } From 3f96146561ef788a8a7dd2ff80fc264276da167c Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 6 Jul 2023 12:52:20 -0700 Subject: [PATCH 047/119] Register the notebook remote save setting --- .../contrib/notebook/browser/notebook.contribution.ts | 5 +++++ src/vs/workbench/contrib/notebook/common/notebookCommon.ts | 1 + .../workbench/contrib/notebook/common/notebookEditorModel.ts | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index 1766a450421..a73901e182d 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -984,6 +984,11 @@ configurationRegistry.registerConfiguration({ codeOutput: true }, tags: ['notebookLayout'] + }, + [NotebookSetting.remoteSaving]: { + markdownDescription: nls.localize('notebook.remoteSaving', "Enables the incremental saving of notebooks in Remote environment. When enabled, only the changes to the notebook are sent to the extension host, improving performance for large notebooks and slow network connections."), + type: 'boolean', + default: typeof product.quality === 'string' && product.quality !== 'stable' // only enable as default in insiders } } }); diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index e57bc24b374..558f6c04765 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -952,6 +952,7 @@ export const NotebookSetting = { findScope: 'notebook.find.scope', logging: 'notebook.logging', confirmDeleteRunningCell: 'notebook.confirmDeleteRunningCell', + remoteSaving: 'notebook.experimental.remoteSave' } as const; export const enum CellStatusbarAlignment { diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts index 56313cf61a0..6cf8c8f934c 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts @@ -18,7 +18,7 @@ import { IWriteFileOptions, IFileStatWithMetadata } from 'vs/platform/files/comm import { IRevertOptions, ISaveOptions, IUntypedEditorInput } from 'vs/workbench/common/editor'; import { EditorModel } from 'vs/workbench/common/editor/editorModel'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; -import { ICellDto2, INotebookEditorModel, INotebookLoadOptions, IResolvedNotebookEditorModel, NotebookCellsChangeType, NotebookData } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { ICellDto2, INotebookEditorModel, INotebookLoadOptions, IResolvedNotebookEditorModel, NotebookCellsChangeType, NotebookData, NotebookSetting } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookSerializer, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService'; import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { IFileWorkingCopyModelConfiguration } from 'vs/workbench/services/workingCopy/common/fileWorkingCopy'; @@ -215,7 +215,7 @@ export class NotebookFileWorkingCopyModel extends Disposable implements IStoredF }; // Override save behavior to avoid transferring the buffer across the wire 3 times - if (this._configurationService.getValue('notebook.experimental.remoteSave')) { + if (this._configurationService.getValue(NotebookSetting.remoteSaving)) { this.save = async (options: IWriteFileOptions, token: CancellationToken) => { const serializer = await this.getNotebookSerializer(); From eec239dc354300777e464f4bd0cad64aeea4492a Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 6 Jul 2023 23:17:43 +0200 Subject: [PATCH 048/119] Fixes #187164 (#187192) --- .../diffEditorWidget2/diffEditorEditors.ts | 17 ++++++++++------ .../diffEditorWidget2/diffEditorWidget2.ts | 3 +++ .../widget/diffEditorWidget2/diffReview.ts | 20 +++++++++---------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts index ac29835d101..e900b4e55ab 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts @@ -15,6 +15,7 @@ import { IContentSizeChangedEvent } from 'vs/editor/common/editorCommon'; import { localize } from 'vs/nls'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { DiffEditorOptions } from './diffEditorOptions'; +import { IObservable, IReader } from 'vs/base/common/observable'; export class DiffEditorEditors extends Disposable { public readonly modified: CodeEditorWidget; @@ -29,6 +30,7 @@ export class DiffEditorEditors extends Disposable { private readonly _options: DiffEditorOptions, codeEditorWidgetOptions: IDiffCodeEditorWidgetOptions, private readonly _createInnerEditor: (instantiationService: IInstantiationService, container: HTMLElement, options: Readonly, editorWidgetOptions: ICodeEditorWidgetOptions) => CodeEditorWidget, + private readonly _modifiedReadOnlyOverride: IObservable, @IInstantiationService private readonly _instantiationService: IInstantiationService ) { super(); @@ -47,19 +49,21 @@ export class DiffEditorEditors extends Disposable { }, (reader, changeSummary) => { _options.editorOptions.read(reader); - this.modified.updateOptions(this._adjustOptionsForRightHandSide(changeSummary)); - this.original.updateOptions(this._adjustOptionsForLeftHandSide(changeSummary)); + this.modified.updateOptions(this._adjustOptionsForRightHandSide(reader, changeSummary)); + this.original.updateOptions(this._adjustOptionsForLeftHandSide(reader, changeSummary)); })); } private _createLeftHandSideEditor(options: Readonly, codeEditorWidgetOptions: ICodeEditorWidgetOptions): CodeEditorWidget { - const editor = this._constructInnerEditor(this._instantiationService, this.originalEditorElement, this._adjustOptionsForLeftHandSide(options), codeEditorWidgetOptions); + const leftHandSideOptions = this._adjustOptionsForLeftHandSide(undefined, options); + const editor = this._constructInnerEditor(this._instantiationService, this.originalEditorElement, leftHandSideOptions, codeEditorWidgetOptions); editor.setContextValue('isInDiffLeftEditor', true); return editor; } private _createRightHandSideEditor(options: Readonly, codeEditorWidgetOptions: ICodeEditorWidgetOptions): CodeEditorWidget { - const editor = this._constructInnerEditor(this._instantiationService, this.modifiedEditorElement, this._adjustOptionsForRightHandSide(options), codeEditorWidgetOptions); + const rightHandSideOptions = this._adjustOptionsForRightHandSide(undefined, options); + const editor = this._constructInnerEditor(this._instantiationService, this.modifiedEditorElement, rightHandSideOptions, codeEditorWidgetOptions); editor.setContextValue('isInDiffRightEditor', true); return editor; } @@ -81,7 +85,7 @@ export class DiffEditorEditors extends Disposable { return editor; } - private _adjustOptionsForLeftHandSide(changedOptions: Readonly): IEditorConstructionOptions { + private _adjustOptionsForLeftHandSide(_reader: IReader | undefined, changedOptions: Readonly): IEditorConstructionOptions { const result = this._adjustOptionsForSubEditor(changedOptions); if (!this._options.renderSideBySide.get()) { // never wrap hidden editor @@ -101,7 +105,7 @@ export class DiffEditorEditors extends Disposable { return result; } - private _adjustOptionsForRightHandSide(changedOptions: Readonly): IEditorConstructionOptions { + private _adjustOptionsForRightHandSide(reader: IReader | undefined, changedOptions: Readonly): IEditorConstructionOptions { const result = this._adjustOptionsForSubEditor(changedOptions); if (changedOptions.modifiedAriaLabel) { result.ariaLabel = changedOptions.modifiedAriaLabel; @@ -111,6 +115,7 @@ export class DiffEditorEditors extends Disposable { result.revealHorizontalRightPadding = EditorOptions.revealHorizontalRightPadding.defaultValue + OverviewRulerPart.ENTIRE_DIFF_OVERVIEW_WIDTH; result.scrollbar!.verticalHasArrows = false; result.extraEditorClassName = 'modified-in-monaco-diff-editor'; + result.readOnly = this._modifiedReadOnlyOverride.read(reader) || this._options.editorOptions.get().readOnly; return result; } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 34fd95848c7..bf02f92991b 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -96,6 +96,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._rootSizeObserver = this._register(new ObservableElementSizeObserver(this.elements.root, options.dimension)); this._rootSizeObserver.setAutomaticLayout(options.automaticLayout ?? false); + const reviewPaneObservable = observableValue('reviewPane', undefined); this._editors = this._register(this._instantiationService.createInstance( DiffEditorEditors, this.elements.original, @@ -103,6 +104,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._options, codeEditorWidgetOptions, (i, c, o, o2) => this._createInnerEditor(i, c, o, o2), + reviewPaneObservable.map((r, reader) => r?.isVisible.read(reader) ?? false), )); this._sash = derivedWithStore('sash', (reader, store) => { @@ -159,6 +161,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this.elements.root.appendChild(this._reviewPane.domNode.domNode); this.elements.root.appendChild(this._reviewPane.shadow.domNode); this.elements.root.appendChild(this._reviewPane.actionBarContainer.domNode); + reviewPaneObservable.set(this._reviewPane, undefined); this._createDiffEditorContributions(); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts index 94d3a9cda2f..f9821f1f4a6 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts @@ -11,6 +11,7 @@ import { Action } from 'vs/base/common/actions'; import { Codicon } from 'vs/base/common/codicons'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Disposable } from 'vs/base/common/lifecycle'; +import { IObservable, observableValue } from 'vs/base/common/observable'; import { ThemeIcon } from 'vs/base/common/themables'; import { Constants } from 'vs/base/common/uint'; import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; @@ -85,7 +86,7 @@ export class DiffReview2 extends Disposable { private static _ttPolicy = DiffReview._ttPolicy; // TODO inline once DiffReview is deprecated. private readonly _diffEditor: DiffEditorWidget2; - private _isVisible: boolean; + private get _isVisible() { return this._isVisibleObs.get(); } public readonly shadow: FastDomNode; private readonly _actionBar: ActionBar; public readonly actionBarContainer: FastDomNode; @@ -95,6 +96,10 @@ export class DiffReview2 extends Disposable { private _diffs: Diff[]; private _currentDiff: Diff | null; + private readonly _isVisibleObs = observableValue('isVisible', false); + + public readonly isVisible: IObservable = this._isVisibleObs; + constructor( diffEditor: DiffEditorWidget2, @ILanguageService private readonly _languageService: ILanguageService, @@ -103,7 +108,6 @@ export class DiffReview2 extends Disposable { ) { super(); this._diffEditor = diffEditor; - this._isVisible = false; this.shadow = createFastDomNode(document.createElement('div')); this.shadow.setClassName('diff-review-shadow'); @@ -215,7 +219,7 @@ export class DiffReview2 extends Disposable { const entries = this._diffs[index].entries; this._diffEditor.setPosition(new Position(entries[0].modifiedLineStart, 1)); this._diffEditor.setSelection({ startColumn: 1, startLineNumber: entries[0].modifiedLineStart, endColumn: Constants.MAX_SAFE_SMALL_INTEGER, endLineNumber: entries[entries.length - 1].modifiedLineEnd }); - this._isVisible = true; + this._isVisibleObs.set(true, undefined); this.layout(); this._render(); this._goToRow(this._getPrevRow(), 'previous'); @@ -250,7 +254,7 @@ export class DiffReview2 extends Disposable { const entries = this._diffs[index].entries; this._diffEditor.setPosition(new Position(entries[0].modifiedLineStart, 1)); this._diffEditor.setSelection({ startColumn: 1, startLineNumber: entries[0].modifiedLineStart, endColumn: Constants.MAX_SAFE_SMALL_INTEGER, endLineNumber: entries[entries.length - 1].modifiedLineEnd }); - this._isVisible = true; + this._isVisibleObs.set(true, undefined); this.layout(); this._render(); this._goToRow(this._getNextRow(), 'next'); @@ -274,8 +278,7 @@ export class DiffReview2 extends Disposable { } private hide(): void { - this._isVisible = false; - this._diffEditor.updateOptions({ readOnly: false }); + this._isVisibleObs.set(false, undefined); this._diffEditor.focus(); this.layout(); this._render(); @@ -331,10 +334,6 @@ export class DiffReview2 extends Disposable { this.scrollbar.scanDomNode(); } - public isVisible(): boolean { - return this._isVisible; - } - private _width: number = 0; private _top: number = 0; private _height: number = 0; @@ -564,7 +563,6 @@ export class DiffReview2 extends Disposable { return; } - this._diffEditor.updateOptions({ readOnly: true }); const diffIndex = this._findDiffIndex(this._diffEditor.getPosition()!); if (this._diffs[diffIndex] === this._currentDiff) { From 30fde0d36907e2d8f7480cd4011e61d4c34c6db9 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 6 Jul 2023 14:49:31 -0700 Subject: [PATCH 049/119] fix: stall on "starting new singleton" on linux if keychain blocks (#187182) Adds a 5s timeout to keychain access on Linux. We had an issue about this a long time ago, but I never repro'd it until today and can't find the original... If this timeout is hit, it'll fall back to the file-based keychain. --- cli/src/auth.rs | 86 +++++++++++++++++++++++++++--------------- cli/src/util/errors.rs | 4 +- 2 files changed, 59 insertions(+), 31 deletions(-) diff --git a/cli/src/auth.rs b/cli/src/auth.rs index 604b1a6ced7..bc2737afc00 100644 --- a/cli/src/auth.rs +++ b/cli/src/auth.rs @@ -10,7 +10,8 @@ use crate::{ trace, util::{ errors::{ - wrap, AnyError, OAuthError, RefreshTokenNotAvailableError, StatusError, WrappedError, + wrap, AnyError, CodeError, OAuthError, RefreshTokenNotAvailableError, StatusError, + WrappedError, }, input::prompt_options, }, @@ -172,9 +173,9 @@ pub struct Auth { } trait StorageImplementation: Send + Sync { - fn read(&mut self) -> Result, WrappedError>; - fn store(&mut self, value: StoredCredential) -> Result<(), WrappedError>; - fn clear(&mut self) -> Result<(), WrappedError>; + fn read(&mut self) -> Result, AnyError>; + fn store(&mut self, value: StoredCredential) -> Result<(), AnyError>; + fn clear(&mut self) -> Result<(), AnyError>; } // unseal decrypts and deserializes the value @@ -217,16 +218,34 @@ struct ThreadKeyringStorage { } impl ThreadKeyringStorage { - fn thread_op(&mut self, f: Fn) -> R + fn thread_op(&mut self, f: Fn) -> Result where - Fn: 'static + Send + FnOnce(&mut KeyringStorage) -> R, + Fn: 'static + Send + FnOnce(&mut KeyringStorage) -> Result, R: 'static + Send, { - let mut s = self.s.take().unwrap(); - let handler = thread::spawn(move || (f(&mut s), s)); - let (r, s) = handler.join().unwrap(); - self.s = Some(s); - r + let mut s = match self.s.take() { + Some(s) => s, + None => return Err(CodeError::KeyringTimeout.into()), + }; + + // It seems like on Linux communication to the keyring can block indefinitely. + // Fall back after a 5 second timeout. + let (sender, receiver) = std::sync::mpsc::channel(); + let tsender = sender.clone(); + + thread::spawn(move || sender.send(Some((f(&mut s), s)))); + thread::spawn(move || { + thread::sleep(std::time::Duration::from_secs(5)); + let _ = tsender.send(None); + }); + + match receiver.recv().unwrap() { + Some((r, s)) => { + self.s = Some(s); + r + } + None => Err(CodeError::KeyringTimeout.into()), + } } } @@ -239,15 +258,15 @@ impl Default for ThreadKeyringStorage { } impl StorageImplementation for ThreadKeyringStorage { - fn read(&mut self) -> Result, WrappedError> { + fn read(&mut self) -> Result, AnyError> { self.thread_op(|s| s.read()) } - fn store(&mut self, value: StoredCredential) -> Result<(), WrappedError> { + fn store(&mut self, value: StoredCredential) -> Result<(), AnyError> { self.thread_op(move |s| s.store(value)) } - fn clear(&mut self) -> Result<(), WrappedError> { + fn clear(&mut self) -> Result<(), AnyError> { self.thread_op(|s| s.clear()) } } @@ -273,7 +292,7 @@ macro_rules! get_next_entry { } impl StorageImplementation for KeyringStorage { - fn read(&mut self) -> Result, WrappedError> { + fn read(&mut self) -> Result, AnyError> { let mut str = String::new(); for i in 0.. { @@ -281,7 +300,7 @@ impl StorageImplementation for KeyringStorage { let next_chunk = match entry.get_password() { Ok(value) => value, Err(keyring::Error::NoEntry) => return Ok(None), // missing entries? - Err(e) => return Err(wrap(e, "error reading keyring")), + Err(e) => return Err(wrap(e, "error reading keyring").into()), }; if next_chunk.ends_with(CONTINUE_MARKER) { @@ -295,7 +314,7 @@ impl StorageImplementation for KeyringStorage { Ok(unseal(&str)) } - fn store(&mut self, value: StoredCredential) -> Result<(), WrappedError> { + fn store(&mut self, value: StoredCredential) -> Result<(), AnyError> { let sealed = seal(&value); let step_size = KEYCHAIN_ENTRY_LIMIT - CONTINUE_MARKER.len(); @@ -312,14 +331,14 @@ impl StorageImplementation for KeyringStorage { }; if let Err(e) = stored { - return Err(wrap(e, "error updating keyring")); + return Err(wrap(e, "error updating keyring").into()); } } Ok(()) } - fn clear(&mut self) -> Result<(), WrappedError> { + fn clear(&mut self) -> Result<(), AnyError> { self.read().ok(); // make sure component parts are available for entry in self.entries.iter() { entry @@ -335,16 +354,16 @@ impl StorageImplementation for KeyringStorage { struct FileStorage(PersistedState>); impl StorageImplementation for FileStorage { - fn read(&mut self) -> Result, WrappedError> { + fn read(&mut self) -> Result, AnyError> { Ok(self.0.load().and_then(|s| unseal(&s))) } - fn store(&mut self, value: StoredCredential) -> Result<(), WrappedError> { - self.0.save(Some(seal(&value))) + fn store(&mut self, value: StoredCredential) -> Result<(), AnyError> { + self.0.save(Some(seal(&value))).map_err(|e| e.into()) } - fn clear(&mut self) -> Result<(), WrappedError> { - self.0.save(None) + fn clear(&mut self) -> Result<(), AnyError> { + self.0.save(None).map_err(|e| e.into()) } } @@ -374,7 +393,7 @@ impl Auth { let mut file_storage = FileStorage(PersistedState::new(self.file_storage_path.clone())); let keyring_storage_result = match std::env::var("VSCODE_CLI_USE_FILE_KEYCHAIN") { - Ok(_) => Err(wrap("", "user prefers file storage")), + Ok(_) => Err(wrap("", "user prefers file storage").into()), _ => keyring_storage.read(), }; @@ -383,10 +402,17 @@ impl Auth { last_read: Cell::new(Ok(v)), storage: Box::new(keyring_storage), }, - Err(_) => StorageWithLastRead { - last_read: Cell::new(file_storage.read()), - storage: Box::new(file_storage), - }, + Err(e) => { + debug!(self.log, "Using file keychain storage due to: {}", e); + StorageWithLastRead { + last_read: Cell::new( + file_storage + .read() + .map_err(|e| wrap(e, "could not read from file storage")), + ), + storage: Box::new(file_storage), + } + } }; let out = op(&mut storage); @@ -419,7 +445,7 @@ impl Auth { } /// Clears login info from the keyring. - pub fn clear_credentials(&self) -> Result<(), WrappedError> { + pub fn clear_credentials(&self) -> Result<(), AnyError> { self.with_storage(|storage| { storage.storage.clear()?; storage.last_read.set(Ok(None)); diff --git a/cli/src/util/errors.rs b/cli/src/util/errors.rs index 6f4630d0c54..ca6d4bf3d8a 100644 --- a/cli/src/util/errors.rs +++ b/cli/src/util/errors.rs @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -use crate::{ + use crate::{ constants::{APPLICATION_NAME, CONTROL_PORT, DOCUMENTATION_URL, QUALITYLESS_PRODUCT_NAME}, rpc::ResponseError, }; @@ -511,6 +511,8 @@ pub enum CodeError { AuthChallengeNotIssued, #[error("unauthorized client refused")] AuthMismatch, + #[error("keyring communication timed out after 5s")] + KeyringTimeout, } makeAnyError!( From 7061dbd1d2789a8ff9e5222e3d188b696aa22178 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 6 Jul 2023 15:47:50 -0700 Subject: [PATCH 050/119] debug: bump companion to 1.1.2 (#187203) --- product.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/product.json b/product.json index 5c83e0ff30d..6d015e98bd0 100644 --- a/product.json +++ b/product.json @@ -36,8 +36,8 @@ "builtInExtensions": [ { "name": "ms-vscode.js-debug-companion", - "version": "1.1.1", - "sha256": "095dc6d5d45490966dfa74d24add92036b42bf02a37d88c4b0f510dc91deeee6", + "version": "1.1.2", + "sha256": "e034b8b41beb4e97e02c70f7175bd88abe66048374c2bd629f54bb33354bc2aa", "repo": "https://github.com/microsoft/vscode-js-debug-companion", "metadata": { "id": "99cb0b7f-7354-4278-b8da-6cc79972169d", From 13b90156ab7aeb16fe4a3857f59ac8d08146f00e Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Thu, 6 Jul 2023 16:14:29 -0700 Subject: [PATCH 051/119] Strengthen Emmet tests (#187204) --- extensions/emmet/src/test/abbreviationAction.test.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/extensions/emmet/src/test/abbreviationAction.test.ts b/extensions/emmet/src/test/abbreviationAction.test.ts index 3f18a1ffc5d..17ccacfc94a 100644 --- a/extensions/emmet/src/test/abbreviationAction.test.ts +++ b/extensions/emmet/src/test/abbreviationAction.test.ts @@ -47,8 +47,6 @@ const invokeCompletionContext: CompletionContext = { }; suite('Tests for Expand Abbreviations (HTML)', () => { - const oldValueForExcludeLanguages = workspace.getConfiguration('emmet').inspect('excludeLanguages'); - const oldValueForIncludeLanguages = workspace.getConfiguration('emmet').inspect('includeLanguages'); teardown(closeAllEditors); test('Expand snippets (HTML)', () => { @@ -364,6 +362,7 @@ suite('Tests for Expand Abbreviations (HTML)', () => { }); test('Expand html when inside script tag with javascript type if js is mapped to html (HTML)', async () => { + const oldConfig = workspace.getConfiguration('emmet').inspect('includeLanguages')?.globalValue; await workspace.getConfiguration('emmet').update('includeLanguages', { 'javascript': 'html' }, ConfigurationTarget.Global); await withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(24, 10, 24, 10); @@ -374,12 +373,13 @@ suite('Tests for Expand Abbreviations (HTML)', () => { await expandPromise; assert.strictEqual(editor.document.getText(), htmlContents.replace('span.bye', '')); }); - return workspace.getConfiguration('emmet').update('includeLanguages', oldValueForIncludeLanguages || {}, ConfigurationTarget.Global); + await workspace.getConfiguration('emmet').update('includeLanguages', oldConfig, ConfigurationTarget.Global); }); test('Expand html in completion list when inside script tag with javascript type if js is mapped to html (HTML)', async () => { const abbreviation = 'span.bye'; const expandedText = ''; + const oldConfig = workspace.getConfiguration('emmet').inspect('includeLanguages')?.globalValue; await workspace.getConfiguration('emmet').update('includeLanguages', { 'javascript': 'html' }, ConfigurationTarget.Global); await withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => { editor.selection = new Selection(24, 10, 24, 10); @@ -399,7 +399,7 @@ suite('Tests for Expand Abbreviations (HTML)', () => { assert.strictEqual(((emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`); return Promise.resolve(); }); - return workspace.getConfiguration('emmet').update('includeLanguages', oldValueForIncludeLanguages || {}, ConfigurationTarget.Global); + await workspace.getConfiguration('emmet').update('includeLanguages', oldConfig, ConfigurationTarget.Global); }); // test('No expanding when html is excluded in the settings', () => { @@ -411,9 +411,10 @@ suite('Tests for Expand Abbreviations (HTML)', () => { // }); test('No expanding when html is excluded in the settings in completion list', async () => { + const oldConfig = workspace.getConfiguration('emmet').inspect('excludeLanguages')?.globalValue; await workspace.getConfiguration('emmet').update('excludeLanguages', ['html'], ConfigurationTarget.Global); await testHtmlCompletionProvider(new Selection(9, 6, 9, 6), '', '', true); - return workspace.getConfiguration('emmet').update('excludeLanguages', oldValueForExcludeLanguages ? oldValueForExcludeLanguages.globalValue : undefined, ConfigurationTarget.Global); + await workspace.getConfiguration('emmet').update('excludeLanguages', oldConfig, ConfigurationTarget.Global); }); // test('No expanding when php (mapped syntax) is excluded in the settings', () => { From 7ffb51f988ac5ec5c73f024603836c26da636852 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 6 Jul 2023 17:05:04 -0700 Subject: [PATCH 052/119] Avoid kernel picker progress when kernel extensions are disabled (#187210) --- .../notebookKernelQuickPickStrategy.ts | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookKernelQuickPickStrategy.ts b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookKernelQuickPickStrategy.ts index 2da8f490a0e..473d46907b1 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookKernelQuickPickStrategy.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookKernelQuickPickStrategy.ts @@ -36,6 +36,7 @@ import { URI } from 'vs/base/common/uri'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { INotebookTextModel } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { SELECT_KERNEL_ID } from 'vs/workbench/contrib/notebook/browser/controller/coreActions'; +import { EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; type KernelPick = IQuickPickItem & { kernel: INotebookKernel }; function isKernelPick(item: QuickPickInput): item is KernelPick { @@ -287,17 +288,22 @@ abstract class KernelPickerStrategyBase implements IKernelPickerStrategy { ) { // If extension id is provided attempt to install the extension as the user has requested the suggested ones be installed const extensionsToInstall: IExtension[] = []; + const extensionsToEnable: IExtension[] = []; for (const extId of extIds) { const extension = (await extensionWorkbenchService.getExtensions([{ id: extId }], CancellationToken.None))[0]; - const canInstall = await extensionWorkbenchService.canInstall(extension); - if (canInstall) { - extensionsToInstall.push(extension); + if (extension.enablementState === EnablementState.DisabledGlobally || extension.enablementState === EnablementState.DisabledWorkspace || extension.enablementState === EnablementState.DisabledByEnvironment) { + extensionsToEnable.push(extension); + } else { + const canInstall = await extensionWorkbenchService.canInstall(extension); + if (canInstall) { + extensionsToInstall.push(extension); + } } } - if (extensionsToInstall.length) { - await Promise.all(extensionsToInstall.map(async extension => { + if (extensionsToInstall.length || extensionsToEnable.length) { + await Promise.all([...extensionsToInstall.map(async extension => { await extensionWorkbenchService.install( extension, { @@ -306,7 +312,21 @@ abstract class KernelPickerStrategyBase implements IKernelPickerStrategy { }, ProgressLocation.Notification ); - })); + }), ...extensionsToEnable.map(async extension => { + switch (extension.enablementState) { + case EnablementState.DisabledWorkspace: + await extensionWorkbenchService.setEnablement([extension], EnablementState.EnabledWorkspace); + return; + case EnablementState.DisabledGlobally: + await extensionWorkbenchService.setEnablement([extension], EnablementState.EnabledGlobally); + return; + case EnablementState.DisabledByEnvironment: + await extensionWorkbenchService.setEnablement([extension], EnablementState.EnabledByEnvironment); + return; + default: + break; + } + })]); await extensionService.activateByEvent(`onNotebook:${viewType}`); return; @@ -348,7 +368,11 @@ abstract class KernelPickerStrategyBase implements IKernelPickerStrategy { const suggestedExtension: INotebookExtensionRecommendation | undefined = language ? this.getSuggestedKernelFromLanguage(notebookTextModel.viewType, language) : undefined; if (suggestedExtension) { await extensionWorkbenchService.queryLocal(); - const extensions = extensionWorkbenchService.installed.filter(e => suggestedExtension.extensionIds.includes(e.identifier.id)); + + const extensions = extensionWorkbenchService.installed.filter(e => + (e.enablementState === EnablementState.EnabledByEnvironment || e.enablementState === EnablementState.EnabledGlobally || e.enablementState === EnablementState.EnabledWorkspace) + && suggestedExtension.extensionIds.includes(e.identifier.id) + ); if (extensions.length === suggestedExtension.extensionIds.length) { // it's installed but might be detecting kernels @@ -359,7 +383,7 @@ abstract class KernelPickerStrategyBase implements IKernelPickerStrategy { quickPickItems.push({ id: 'installSuggested', description: suggestedExtension.displayName ?? suggestedExtension.extensionIds.join(', '), - label: `$(${Codicon.lightbulb.id}) ` + localize('installSuggestedKernel', 'Install suggested extensions'), + label: `$(${Codicon.lightbulb.id}) ` + localize('installSuggestedKernel', 'Install/Enable suggested extensions'), extensionIds: suggestedExtension.extensionIds } as InstallExtensionPick); } @@ -605,7 +629,7 @@ export class KernelPickerMRUStrategy extends KernelPickerStrategyBase { selectedKernelPickItem.extensionIds, this._productService.quality !== 'stable' ); - return true; + return this.displaySelectAnotherQuickPick(editor, false); } } From 31f183271b0d1f24a2052f6eccbb76bdef45d60b Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 7 Jul 2023 02:05:55 +0200 Subject: [PATCH 053/119] Fixes #187194 (#187211) --- .../inlineCompletions/browser/commands.ts | 4 +-- .../browser/inlineCompletionsModel.ts | 26 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/commands.ts b/src/vs/editor/contrib/inlineCompletions/browser/commands.ts index fbb7b657c8d..2370e210bf3 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/commands.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/commands.ts @@ -97,7 +97,7 @@ export class AcceptNextWordOfInlineCompletion extends EditorAction { public async run(accessor: ServicesAccessor | undefined, editor: ICodeEditor): Promise { const controller = InlineCompletionsController.get(editor); - controller?.model.get()?.acceptNextWord(controller.editor); + await controller?.model.get()?.acceptNextWord(controller.editor); } } @@ -122,7 +122,7 @@ export class AcceptNextLineOfInlineCompletion extends EditorAction { public async run(accessor: ServicesAccessor | undefined, editor: ICodeEditor): Promise { const controller = InlineCompletionsController.get(editor); - controller?.model.get()?.acceptNextLine(controller.editor); + await controller?.model.get()?.acceptNextLine(controller.editor); } } diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index 95346e787b6..c66ec2a6d56 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -306,20 +306,28 @@ export class InlineCompletionsModel extends Disposable { } if (completion.command) { - await this._commandService - .executeCommand(completion.command.id, ...(completion.command.arguments || [])) - .then(undefined, onUnexpectedExternalError); + // Make sure the completion list will not be disposed. + completion.source.addRef(); } + + // Reset before invoking the command, since the command might cause a follow up trigger. transaction(tx => { this._source.clear(tx); // Potentially, isActive will get set back to true by the typing or accept inline suggest event // if automatic inline suggestions are enabled. this._isActive.set(false, tx); }); + + if (completion.command) { + await this._commandService + .executeCommand(completion.command.id, ...(completion.command.arguments || [])) + .then(undefined, onUnexpectedExternalError); + completion.source.removeRef(); + } } - public acceptNextWord(editor: ICodeEditor): void { - this._acceptNext(editor, (pos, text) => { + public async acceptNextWord(editor: ICodeEditor): Promise { + await this._acceptNext(editor, (pos, text) => { const langId = this.textModel.getLanguageIdAtPosition(pos.lineNumber, pos.column); const config = this._languageConfigurationService.getLanguageConfiguration(langId); const wordRegExp = new RegExp(config.wordDefinition.source, config.wordDefinition.flags.replace('g', '')); @@ -347,8 +355,8 @@ export class InlineCompletionsModel extends Disposable { }); } - public acceptNextLine(editor: ICodeEditor): void { - this._acceptNext(editor, (pos, text) => { + public async acceptNextLine(editor: ICodeEditor): Promise { + await this._acceptNext(editor, (pos, text) => { const m = text.match(/\n/); if (m && m.index !== undefined) { return m.index + 1; @@ -357,7 +365,7 @@ export class InlineCompletionsModel extends Disposable { }); } - private _acceptNext(editor: ICodeEditor, getAcceptUntilIndex: (position: Position, text: string) => number): void { + private async _acceptNext(editor: ICodeEditor, getAcceptUntilIndex: (position: Position, text: string) => number): Promise { if (editor.getModel() !== this.textModel) { throw new BugIndicatingError(); } @@ -370,7 +378,7 @@ export class InlineCompletionsModel extends Disposable { if (completion.snippetInfo || completion.filterText !== completion.insertText) { // not in WYSIWYG mode, partial commit might change completion, thus it is not supported - this.accept(editor); + await this.accept(editor); return; } From 2f2bc05fde94f40ec7ec68398c24e5bae71b30c1 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 6 Jul 2023 23:56:43 -0700 Subject: [PATCH 054/119] Don't log when not actually persisting sessions (#187214) --- .../contrib/chat/common/chatServiceImpl.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts index d05c1f1a828..c15379f06c6 100644 --- a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts +++ b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts @@ -152,10 +152,11 @@ export class ChatService extends Disposable implements IChatService { if (sessionData) { this._persistedSessions = this.deserializeChats(sessionData); const countsForLog = Object.keys(this._persistedSessions).length; - this.trace('constructor', `Restored ${countsForLog} persisted sessions`); + if (countsForLog > 0) { + this.trace('constructor', `Restored ${countsForLog} persisted sessions`); + } } else { this._persistedSessions = {}; - this.trace('constructor', 'No persisted sessions'); } this._transferred = this.getTransferredSession(); @@ -176,10 +177,16 @@ export class ChatService extends Disposable implements IChatService { .filter(session => session.requests.length)); allSessions.sort((a, b) => (b.creationDate ?? 0) - (a.creationDate ?? 0)); allSessions = allSessions.slice(0, maxPersistedSessions); - this.trace('onWillSaveState', `Persisting ${allSessions.length} sessions`); + if (allSessions.length) { + this.trace('onWillSaveState', `Persisting ${allSessions.length} sessions`); + } const serialized = JSON.stringify(allSessions); - this.trace('onWillSaveState', `Persisting ${serialized.length} chars`); + + if (allSessions.length) { + this.trace('onWillSaveState', `Persisting ${serialized.length} chars`); + } + this.storageService.store(serializedChatKey, serialized, StorageScope.WORKSPACE, StorageTarget.MACHINE); } From fa37b611fe9bd8c4a72249f88566a1acfbb953a8 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Thu, 6 Jul 2023 23:57:51 -0700 Subject: [PATCH 055/119] search: fix resources with trailing slash (#187106) * search resources with trailing slash in root --- .../contrib/search/browser/searchModel.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/searchModel.ts b/src/vs/workbench/contrib/search/browser/searchModel.ts index 68b2ca8f905..f90c691f08b 100644 --- a/src/vs/workbench/contrib/search/browser/searchModel.ts +++ b/src/vs/workbench/contrib/search/browser/searchModel.ts @@ -1275,6 +1275,8 @@ export class FolderMatch extends Disposable { export class FolderMatchWithResource extends FolderMatch { + protected _normalizedResource: Lazy; + constructor(_resource: URI, _id: string, _index: number, _query: ITextQuery, _parent: SearchResult | FolderMatch, _searchModel: SearchModel, _closestRoot: FolderMatchWorkspaceRoot | null, @IReplaceService replaceService: IReplaceService, @IInstantiationService instantiationService: IInstantiationService, @@ -1282,11 +1284,17 @@ export class FolderMatchWithResource extends FolderMatch { @IUriIdentityService uriIdentityService: IUriIdentityService ) { super(_resource, _id, _index, _query, _parent, _searchModel, _closestRoot, replaceService, instantiationService, labelService, uriIdentityService); + this._normalizedResource = new Lazy(() => this.uriIdentityService.extUri.removeTrailingPathSeparator(this.uriIdentityService.extUri.normalizePath( + this.resource))); } override get resource(): URI { return this._resource!; } + + get normalizedResource(): URI { + return this._normalizedResource.value; + } } /** @@ -1334,15 +1342,14 @@ export class FolderMatchWorkspaceRoot extends FolderMatchWithResource { } const fileMatchParentParts: URI[] = []; - const normalizedResource = this.uriIdentityService.extUri.normalizePath(this.resource); let uri = this.normalizedUriParent(rawFileMatch.resource); - while (!this.uriEquals(normalizedResource, uri)) { + while (!this.uriEquals(this.normalizedResource, uri)) { fileMatchParentParts.unshift(uri); const prevUri = uri; - uri = this.normalizedUriParent(uri); + uri = this.uriIdentityService.extUri.removeTrailingPathSeparator(this.normalizedUriParent(uri)); if (this.uriEquals(prevUri, uri)) { - throw Error(`${rawFileMatch.resource} is not correctly configured as a child of ${normalizedResource}`); + throw Error(`${rawFileMatch.resource} is not correctly configured as a child of ${this.normalizedResource}`); } } From 91749da58973550134a50f32f135121cb2f9a14b Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 7 Jul 2023 11:09:19 +0200 Subject: [PATCH 056/119] use troubleshoot command for confirmation needed action (#187244) --- .github/commands.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/commands.json b/.github/commands.json index 200a47b18c0..15c6cd953c5 100644 --- a/.github/commands.json +++ b/.github/commands.json @@ -215,7 +215,7 @@ "action": "updateLabels", "addLabel": "info-needed", "removeLabel": "~confirmation-needed", - "comment": "Please perform the following **three tasks** to diagnose the root cause of the issue:\n\n* [ ] **1.) Disable Extensions**\n * Select `View` and pick `Command Palette...`\n * Run `Developer: Reload With Extensions Disabled`\n * 👉 See if the issue reproduces\n\n* [ ] **2.) Disable Configuration**\n * Select `View` and pick `Command Palette...`\n * Run `Profiles: Create a Temporary Profile`\n * 👉 See if the issue reproduces\n\n* [ ] **3.) Try VS Code Insiders**\n * Download [VS Code Insiders](https://code.visualstudio.com/insiders/)\n * Install and Run it\n * 👉 See if the issue reproduces\n \nThen pick one of the three resolutions depending on which step has helped:\n\n
\n Disabling my Extensions helped\n\nPlease run the command `Start Extension Bisect` and follow the instructions to find the extension that is causing this issue.\n\nimage\n\nPlease report the issue to the extension causing this.\n
\n\n
\n Disabling my configuration helped\nPlease report back more details about your configuration, including settings.\n
\n\n
\n Using VS Code Insiders has helped\n✅ This likely means that the issue has been addressed already and will be available in an upcoming release. You can safely use VS Code Insiders until the new stable version is available.\n
" + "comment": "Please diagnose the root cause of the issue by running the command `F1 > Help: Troubleshoot Issue` and following the instructions. Once you have done that, please update the issue with the results.\n\nHappy Coding!" }, { "type": "comment", From 4c1e4bb5c570d3e27d8d3df5eeb0a8f5da632b4e Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 7 Jul 2023 13:42:47 +0200 Subject: [PATCH 057/119] Allow additional socks schemes (#158669) --- src/vs/platform/request/common/request.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/request/common/request.ts b/src/vs/platform/request/common/request.ts index 58de4472569..42168d7a59c 100644 --- a/src/vs/platform/request/common/request.ts +++ b/src/vs/platform/request/common/request.ts @@ -138,7 +138,7 @@ function registerProxyConfigurations(scope: ConfigurationScope): void { properties: { 'http.proxy': { type: 'string', - pattern: '^(https?|socks5?)://([^:]*(:[^@]*)?@)?([^:]+|\\[[:0-9a-fA-F]+\\])(:\\d+)?/?$|^$', + pattern: '^(https?|socks|socks4a?|socks5h?)://([^:]*(:[^@]*)?@)?([^:]+|\\[[:0-9a-fA-F]+\\])(:\\d+)?/?$|^$', markdownDescription: localize('proxy', "The proxy setting to use. If not set, will be inherited from the `http_proxy` and `https_proxy` environment variables."), restricted: true }, From e7776fdf9c46a7ba612b049b2a923c594f4d9bf1 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 7 Jul 2023 14:42:49 +0200 Subject: [PATCH 058/119] Fixes #186402 (#187184) --- .../browser/widget/diffEditorWidget2/diffEditorWidget2.ts | 5 +++++ src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index bf02f92991b..7930581e426 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -315,6 +315,11 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { override getModel(): IDiffEditorModel | null { return this._diffModel.get()?.model ?? null; } override setModel(model: IDiffEditorModel | null | IDiffEditorViewModel): void { + if (!model && this._diffModel.get()) { + // Transitioning from a model to no-model + this._reviewPane.hide(); + } + const vm = model ? ('model' in model) ? model : this.createViewModel(model) : undefined; this._editors.original.setModel(vm ? vm.model.original : null); this._editors.modified.setModel(vm ? vm.model.modified : null); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts index f9821f1f4a6..ed1c345f5e5 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffReview.ts @@ -277,7 +277,7 @@ export class DiffReview2 extends Disposable { } } - private hide(): void { + public hide(): void { this._isVisibleObs.set(false, undefined); this._diffEditor.focus(); this.layout(); From d1ae8a6ecc5a48cc7ede36dc7ddc3d218be0e75e Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 7 Jul 2023 16:29:09 +0200 Subject: [PATCH 059/119] Inline Completions: Implements yieldsTo (#187156) Fixes #https://github.com/microsoft/vscode-internalbacklog/issues/4055 --- src/vs/base/common/collections.ts | 8 ++ src/vs/editor/common/languages.ts | 16 ++++ .../browser/provideInlineCompletions.ts | 90 +++++++++++++++++-- src/vs/monaco.d.ts | 13 +++ .../api/browser/mainThreadLanguageFeatures.ts | 7 +- .../workbench/api/common/extHost.api.impl.ts | 7 +- .../workbench/api/common/extHost.protocol.ts | 2 +- .../api/common/extHostLanguageFeatures.ts | 5 +- ...e.proposed.inlineCompletionsAdditions.d.ts | 24 +++++ 9 files changed, 157 insertions(+), 15 deletions(-) diff --git a/src/vs/base/common/collections.ts b/src/vs/base/common/collections.ts index d8ee92f757e..95def40789d 100644 --- a/src/vs/base/common/collections.ts +++ b/src/vs/base/common/collections.ts @@ -101,4 +101,12 @@ export class SetMap { values.forEach(fn); } + + get(key: K): ReadonlySet { + const values = this.map.get(key); + if (!values) { + return new Set(); + } + return new Set(values); + } } diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 60a04c23d0a..364998995e3 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -703,6 +703,8 @@ export interface InlineCompletions { provideInlineCompletions(model: model.ITextModel, position: Position, context: InlineCompletionContext, token: CancellationToken): ProviderResult; @@ -721,6 +723,20 @@ export interface InlineCompletionsProvider { // Important: Don't use position after the await calls, as the model could have been changed in the meantime! const defaultReplaceRange = getDefaultRange(position, model); - const providers = registry.all(model); - const providerResults = await Promise.all(providers.map(async provider => { + + const multiMap = new SetMap>(); + for (const provider of providers) { + if (provider.groupId) { + multiMap.add(provider.groupId, provider); + } + } + + function getPreferredProviders(provider: InlineCompletionsProvider): InlineCompletionsProvider[] { + if (!provider.yieldsToGroupIds) { return []; } + const result: InlineCompletionsProvider[] = []; + for (const groupId of provider.yieldsToGroupIds || []) { + const providers = multiMap.get(groupId); + for (const p of providers) { + result.push(p); + } + } + return result; + } + + type Result = Promise | null | undefined>; + const states = new Map>, Result>(); + + const seen = new Set>>(); + function findPreferredProviderCircle(provider: InlineCompletionsProvider, stack: InlineCompletionsProvider[]): InlineCompletionsProvider[] | undefined { + stack = [...stack, provider]; + if (seen.has(provider)) { return stack; } + + seen.add(provider); try { - const completions = await provider.provideInlineCompletions(model, position, context, token); - return ({ provider, completions }); - } catch (e) { - onUnexpectedExternalError(e); + const preferred = getPreferredProviders(provider); + for (const p of preferred) { + const c = findPreferredProviderCircle(p, stack); + if (c) { return c; } + } + } finally { + seen.delete(provider); } - return ({ provider, completions: undefined }); - })); + return undefined; + } + + function processProvider(provider: InlineCompletionsProvider): Result { + const state = states.get(provider); + if (state) { + return state; + } + + const circle = findPreferredProviderCircle(provider, []); + if (circle) { + onUnexpectedExternalError(new Error(`Inline completions: cyclic yield-to dependency detected. Path: ${circle.map(s => s.toString ? s.toString() : ('' + s)).join(' -> ')}`)); + } + + const deferredPromise = new DeferredPromise | null | undefined>(); + states.set(provider, deferredPromise.p); + + (async () => { + if (!circle) { + const preferred = getPreferredProviders(provider); + for (const p of preferred) { + const result = await processProvider(p); + if (result && result.items.length > 0) { + // Skip provider + return undefined; + } + } + } + + try { + const completions = await provider.provideInlineCompletions(model, position, context, token); + return completions; + } catch (e) { + onUnexpectedExternalError(e); + return undefined; + } + })().then(c => deferredPromise.complete(c), e => deferredPromise.error(e)); + + return deferredPromise.p; + } + + const providerResults = await Promise.all(providers.map(async provider => ({ provider, completions: await processProvider(provider) }))); const itemsByHash = new Map(); const lists: InlineCompletionList[] = []; diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 001b8a6de24..d59db506ee1 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -7090,6 +7090,8 @@ declare namespace monaco.languages { readonly enableForwardStability?: boolean | undefined; } + export type InlineCompletionProviderGroupId = string; + export interface InlineCompletionsProvider { provideInlineCompletions(model: editor.ITextModel, position: Position, context: InlineCompletionContext, token: CancellationToken): ProviderResult; /** @@ -7105,6 +7107,17 @@ declare namespace monaco.languages { * Will be called when a completions list is no longer in use and can be garbage-collected. */ freeInlineCompletions(completions: T): void; + /** + * Only used for {@link yieldsToGroupIds}. + * Multiple providers can have the same group id. + */ + groupId?: InlineCompletionProviderGroupId; + /** + * Returns a list of preferred provider {@link groupId}s. + * The current provider is only requested for completions if no provider with a preferred group id returned a result. + */ + yieldsToGroupIds?: InlineCompletionProviderGroupId[]; + toString?(): string; } export interface CodeAction { diff --git a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts index c34ff9c91da..732637669fb 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts @@ -557,7 +557,7 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread this._registrations.set(handle, this._languageFeaturesService.completionProvider.register(selector, provider)); } - $registerInlineCompletionsSupport(handle: number, selector: IDocumentFilterDto[], supportsHandleEvents: boolean): void { + $registerInlineCompletionsSupport(handle: number, selector: IDocumentFilterDto[], supportsHandleEvents: boolean, extensionId: string, yieldsToExtensionIds: string[]): void { const provider: languages.InlineCompletionsProvider = { provideInlineCompletions: async (model: ITextModel, position: EditorPosition, context: languages.InlineCompletionContext, token: CancellationToken): Promise => { return this._proxy.$provideInlineCompletions(handle, model.uri, position, context, token); @@ -574,6 +574,11 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread }, freeInlineCompletions: (completions: IdentifiableInlineCompletions): void => { this._proxy.$freeInlineCompletionsList(handle, completions.pid); + }, + groupId: extensionId, + yieldsToGroupIds: yieldsToExtensionIds, + toString() { + return `InlineCompletionsProvider(${extensionId})`; } }; this._registrations.set(handle, this._languageFeaturesService.inlineCompletionsProvider.register(selector, provider)); diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 56f66abde2f..1e585c0d3b0 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -578,14 +578,17 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, ...triggerCharacters: string[]): vscode.Disposable { return extHostLanguageFeatures.registerCompletionItemProvider(extension, checkSelector(selector), provider, triggerCharacters); }, - registerInlineCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.InlineCompletionItemProvider): vscode.Disposable { + registerInlineCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.InlineCompletionItemProvider, metadata?: vscode.InlineCompletionItemProviderMetadata): vscode.Disposable { if (provider.handleDidShowCompletionItem) { checkProposedApiEnabled(extension, 'inlineCompletionsAdditions'); } if (provider.handleDidPartiallyAcceptCompletionItem) { checkProposedApiEnabled(extension, 'inlineCompletionsAdditions'); } - return extHostLanguageFeatures.registerInlineCompletionsProvider(extension, checkSelector(selector), provider); + if (metadata) { + checkProposedApiEnabled(extension, 'inlineCompletionsAdditions'); + } + return extHostLanguageFeatures.registerInlineCompletionsProvider(extension, checkSelector(selector), provider, metadata); }, registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable { return extHostLanguageFeatures.registerDocumentLinkProvider(extension, checkSelector(selector), provider); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index c8b82a40e92..413980ad9b3 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -407,7 +407,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable { $emitDocumentSemanticTokensEvent(eventHandle: number): void; $registerDocumentRangeSemanticTokensProvider(handle: number, selector: IDocumentFilterDto[], legend: languages.SemanticTokensLegend): void; $registerCompletionsProvider(handle: number, selector: IDocumentFilterDto[], triggerCharacters: string[], supportsResolveDetails: boolean, extensionId: ExtensionIdentifier): void; - $registerInlineCompletionsSupport(handle: number, selector: IDocumentFilterDto[], supportsHandleDidShowCompletionItem: boolean): void; + $registerInlineCompletionsSupport(handle: number, selector: IDocumentFilterDto[], supportsHandleDidShowCompletionItem: boolean, extensionId: string, yieldsToExtensionIds: string[]): void; $registerSignatureHelpProvider(handle: number, selector: IDocumentFilterDto[], metadata: ISignatureHelpProviderMetadataDto): void; $registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean, eventHandle: number | undefined, displayName: string | undefined): void; $emitInlayHintsEvent(eventHandle: number): void; diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index 8c871feda78..78ecbea0a85 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -2249,10 +2249,11 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF // --- ghost test - registerInlineCompletionsProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.InlineCompletionItemProvider): vscode.Disposable { + registerInlineCompletionsProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.InlineCompletionItemProvider, metadata: vscode.InlineCompletionItemProviderMetadata | undefined): vscode.Disposable { const adapter = new InlineCompletionAdapter(extension, this._documents, provider, this._commands.converter); const handle = this._addNewAdapter(adapter, extension); - this._proxy.$registerInlineCompletionsSupport(handle, this._transformDocumentSelector(selector, extension), adapter.supportsHandleEvents); + this._proxy.$registerInlineCompletionsSupport(handle, this._transformDocumentSelector(selector, extension), adapter.supportsHandleEvents, + ExtensionIdentifier.toKey(extension.identifier.value), metadata?.yieldTo?.map(extId => ExtensionIdentifier.toKey(extId)) || []); return this._createDisposable(handle); } diff --git a/src/vscode-dts/vscode.proposed.inlineCompletionsAdditions.d.ts b/src/vscode-dts/vscode.proposed.inlineCompletionsAdditions.d.ts index 8412aca06ed..c38c4e23671 100644 --- a/src/vscode-dts/vscode.proposed.inlineCompletionsAdditions.d.ts +++ b/src/vscode-dts/vscode.proposed.inlineCompletionsAdditions.d.ts @@ -7,6 +7,22 @@ declare module 'vscode' { // https://github.com/microsoft/vscode/issues/124024 @hediet @alexdima + export namespace languages { + /** + * Registers an inline completion provider. + * + * Multiple providers can be registered for a language. In that case providers are asked in + * parallel and the results are merged. A failing provider (rejected promise or exception) will + * not cause a failure of the whole operation. + * + * @param selector A selector that defines the documents this provider is applicable to. + * @param provider An inline completion provider. + * @param metadata Metadata about the provider. + * @return A {@link Disposable} that unregisters this provider when being disposed. + */ + export function registerInlineCompletionItemProvider(selector: DocumentSelector, provider: InlineCompletionItemProvider, metadata: InlineCompletionItemProviderMetadata): Disposable; + } + export interface InlineCompletionItem { /** * If set to `true`, unopened closing brackets are removed and unclosed opening brackets are closed. @@ -15,6 +31,14 @@ declare module 'vscode' { completeBracketPairs?: boolean; } + export interface InlineCompletionItemProviderMetadata { + /** + * Specifies a list of extension ids that this provider yields to if they return a result. + * If some inline completion provider registered by such an extension returns a result, this provider is not asked. + */ + yieldTo: string[]; + } + export interface InlineCompletionItemProvider { /** * @param completionItem The completion item that was shown. From f639cabe2d5d11b4fc608e9008aa47dabf0f100c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 7 Jul 2023 08:33:46 -0700 Subject: [PATCH 060/119] Log latency stats and remove old unused latency mechanism Fixes #187274 --- src/vs/platform/terminal/common/terminal.ts | 12 +++++++-- .../platform/terminal/node/ptyHostService.ts | 16 ++++++++--- src/vs/platform/terminal/node/ptyService.ts | 9 +++---- .../platform/terminal/node/terminalProcess.ts | 4 --- src/vs/server/node/remoteTerminalChannel.ts | 1 + .../api/browser/mainThreadTerminalService.ts | 23 ---------------- .../api/common/extHostTerminalService.ts | 4 --- .../contrib/terminal/browser/remotePty.ts | 4 --- .../terminal/browser/remoteTerminalBackend.ts | 16 ++++++++++- .../browser/terminalProcessExtHostProxy.ts | 17 ------------ .../browser/terminalProcessManager.ts | 25 +++++++---------- .../common/remote/remoteTerminalChannel.ts | 5 +++- .../terminal/common/remote/terminal.ts | 1 + .../contrib/terminal/common/terminal.ts | 3 --- .../terminal/electron-sandbox/localPty.ts | 4 --- .../electron-sandbox/localTerminalBackend.ts | 27 ++++++++++++++++++- .../browser/terminalProcessManager.test.ts | 1 - .../common/embedderTerminalService.ts | 3 --- 18 files changed, 82 insertions(+), 93 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 550e3dff813..a73f7a7f9fa 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -300,6 +300,10 @@ export interface IPtyService { */ listProcesses(): Promise; getPerformanceMarks(): Promise; + /** + * Measures and returns the latency of the current and all other processes to the pty host. + */ + getLatency(): Promise; start(id: number): Promise; shutdown(id: number, immediate: boolean): Promise; @@ -308,7 +312,6 @@ export interface IPtyService { clearBuffer(id: number): Promise; getInitialCwd(id: number): Promise; getCwd(id: number): Promise; - getLatency(id: number): Promise; acknowledgeDataEvent(id: number, charCount: number): Promise; setUnicodeVersion(id: number, version: '6' | '11'): Promise; processBinary(id: number, data: string): Promise; @@ -367,6 +370,11 @@ export interface IPtyHostController { export interface IPtyHostService extends IPtyService, IPtyHostController { } +export interface IPtyHostLatencyMeasurement { + label: string; + latency: number; +} + /** * Serialized terminal state matching the interface that can be used across versions, the version * should be verified before using the state payload. @@ -739,7 +747,6 @@ export interface ITerminalChildProcess { getInitialCwd(): Promise; getCwd(): Promise; - getLatency(): Promise; refreshProperty(property: T): Promise; updateProperty(property: T, value: IProcessPropertyMap[T]): Promise; } @@ -992,6 +999,7 @@ export interface ITerminalBackend { attachToProcess(id: number): Promise; attachToRevivedProcess(id: number): Promise; listProcesses(): Promise; + getLatency(): Promise; getDefaultSystemShell(osOverride?: OperatingSystem): Promise; getProfiles(profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise; getWslPath(original: string, direction: 'unix-to-win' | 'win-to-unix'): Promise; diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index 59b84827479..a9b9a2e57ae 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -13,13 +13,14 @@ import { RemoteLoggerChannelClient } from 'vs/platform/log/common/logIpc'; import { getResolvedShellEnv } from 'vs/platform/shell/node/shellEnv'; import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/capabilities/capabilities'; import { RequestStore } from 'vs/platform/terminal/common/requestStore'; -import { HeartbeatConstants, IHeartbeatService, IProcessDataEvent, IProcessProperty, IProcessPropertyMap, IProcessReadyEvent, IPtyHostService, IPtyService, IRequestResolveVariablesEvent, ISerializedTerminalState, IShellLaunchConfig, ITerminalLaunchError, ITerminalProcessOptions, ITerminalProfile, ITerminalsLayoutInfo, ProcessPropertyType, TerminalIcon, TerminalIpcChannels, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { HeartbeatConstants, IHeartbeatService, IProcessDataEvent, IProcessProperty, IProcessPropertyMap, IProcessReadyEvent, IPtyHostLatencyMeasurement, IPtyHostService, IPtyService, IRequestResolveVariablesEvent, ISerializedTerminalState, IShellLaunchConfig, ITerminalLaunchError, ITerminalProcessOptions, ITerminalProfile, ITerminalsLayoutInfo, ProcessPropertyType, TerminalIcon, TerminalIpcChannels, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { registerTerminalPlatformConfiguration } from 'vs/platform/terminal/common/terminalPlatformConfiguration'; import { IGetTerminalLayoutInfoArgs, IProcessDetails, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess'; import { IPtyHostConnection, IPtyHostStarter } from 'vs/platform/terminal/node/ptyHost'; import { detectAvailableProfiles } from 'vs/platform/terminal/node/terminalProfiles'; import * as performance from 'vs/base/common/performance'; import { getSystemShell } from 'vs/base/node/shell'; +import { StopWatch } from 'vs/base/common/stopwatch'; enum Constants { MaxRestarts = 5 @@ -272,8 +273,17 @@ export class PtyHostService extends Disposable implements IPtyHostService { getCwd(id: number): Promise { return this._proxy.getCwd(id); } - getLatency(id: number): Promise { - return this._proxy.getLatency(id); + async getLatency(): Promise { + const sw = new StopWatch(); + const results = await this._proxy.getLatency(); + sw.stop(); + return [ + { + label: 'ptyhostservice<->ptyhost', + latency: sw.elapsed() + }, + ...results + ]; } orphanQuestionReply(id: number): Promise { return this._proxy.orphanQuestionReply(id); diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 564b87612f3..4661924d5dc 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri'; import { getSystemShell } from 'vs/base/node/shell'; import { ILogService, LogLevel } from 'vs/platform/log/common/log'; import { RequestStore } from 'vs/platform/terminal/common/requestStore'; -import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IShellLaunchConfig, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, IProcessProperty, TitleEventSource, ProcessPropertyType, IProcessPropertyMap, IFixedTerminalDimensions, IPersistentTerminalProcessLaunchConfig, ICrossVersionSerializedTerminalState, ISerializedTerminalState, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IShellLaunchConfig, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, IProcessProperty, TitleEventSource, ProcessPropertyType, IProcessPropertyMap, IFixedTerminalDimensions, IPersistentTerminalProcessLaunchConfig, ICrossVersionSerializedTerminalState, ISerializedTerminalState, ITerminalProcessOptions, IPtyHostLatencyMeasurement } from 'vs/platform/terminal/common/terminal'; import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment'; import { Terminal as XtermTerminal } from 'xterm-headless'; @@ -399,8 +399,8 @@ export class PtyService extends Disposable implements IPtyService { return this._throwIfNoPty(id).setUnicodeVersion(version); } @traceRpc - async getLatency(id: number): Promise { - return 0; + async getLatency(): Promise { + return []; } @traceRpc async orphanQuestionReply(id: number): Promise { @@ -874,9 +874,6 @@ class PersistentTerminalProcess extends Disposable { getCwd(): Promise { return this._terminalProcess.getCwd(); } - getLatency(): Promise { - return this._terminalProcess.getLatency(); - } async triggerReplay(): Promise { if (this._interactionState.value === InteractionState.None) { diff --git a/src/vs/platform/terminal/node/terminalProcess.ts b/src/vs/platform/terminal/node/terminalProcess.ts index 467007e8728..bfd620a0d60 100644 --- a/src/vs/platform/terminal/node/terminalProcess.ts +++ b/src/vs/platform/terminal/node/terminalProcess.ts @@ -627,10 +627,6 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess return this._initialCwd; } - getLatency(): Promise { - return Promise.resolve(0); - } - getWindowsPty(): IProcessReadyWindowsPty | undefined { return isWindows ? { backend: 'useConpty' in this._ptyOptions && this._ptyOptions.useConpty ? 'conpty' : 'winpty', diff --git a/src/vs/server/node/remoteTerminalChannel.ts b/src/vs/server/node/remoteTerminalChannel.ts index df9943918ee..0918a4855a2 100644 --- a/src/vs/server/node/remoteTerminalChannel.ts +++ b/src/vs/server/node/remoteTerminalChannel.ts @@ -117,6 +117,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< case RemoteTerminalChannelRequest.DetachFromProcess: return this._ptyHostService.detachFromProcess.apply(this._ptyHostService, args); case RemoteTerminalChannelRequest.ListProcesses: return this._ptyHostService.listProcesses.apply(this._ptyHostService, args); + case RemoteTerminalChannelRequest.GetLatency: return this._ptyHostService.getLatency.apply(this._ptyHostService, args); case RemoteTerminalChannelRequest.GetPerformanceMarks: return this._ptyHostService.getPerformanceMarks.apply(this._ptyHostService, args); case RemoteTerminalChannelRequest.OrphanQuestionReply: return this._ptyHostService.orphanQuestionReply.apply(this._ptyHostService, args); case RemoteTerminalChannelRequest.AcceptPtyHostResolvedVariables: return this._ptyHostService.acceptPtyHostResolvedVariables.apply(this._ptyHostService, args); diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index cedec7ba50a..b2f7c9a7dd3 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -7,7 +7,6 @@ import { DisposableStore, Disposable, IDisposable, MutableDisposable } from 'vs/ import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, TerminalLaunchConfig, ITerminalDimensionsDto, ExtHostTerminalIdentifier, TerminalQuickFix } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; import { URI } from 'vs/base/common/uri'; -import { StopWatch } from 'vs/base/common/stopwatch'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; import { IProcessProperty, IProcessReadyWindowsPty, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalOutputMatch, ITerminalOutputMatcher, ProcessPropertyType, TerminalExitReason, TerminalLocation } from 'vs/platform/terminal/common/terminal'; @@ -368,7 +367,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape proxy.onShutdown(immediate => this._proxy.$acceptProcessShutdown(proxy.instanceId, immediate)); proxy.onRequestCwd(() => this._proxy.$acceptProcessRequestCwd(proxy.instanceId)); proxy.onRequestInitialCwd(() => this._proxy.$acceptProcessRequestInitialCwd(proxy.instanceId)); - proxy.onRequestLatency(() => this._onRequestLatency(proxy.instanceId)); } public $sendProcessData(terminalId: number, data: string): void { @@ -387,27 +385,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._terminalProcessProxies.get(terminalId)?.emitProcessProperty(property); } - private async _onRequestLatency(terminalId: number): Promise { - const COUNT = 2; - let sum = 0; - for (let i = 0; i < COUNT; i++) { - const sw = StopWatch.create(); - await this._proxy.$acceptProcessRequestLatency(terminalId); - sw.stop(); - sum += sw.elapsed(); - } - this._getTerminalProcess(terminalId)?.emitLatency(sum / COUNT); - } - - private _getTerminalProcess(terminalId: number): ITerminalProcessExtHostProxy | undefined { - const terminal = this._terminalProcessProxies.get(terminalId); - if (!terminal) { - this._logService.error(`Unknown terminal: ${terminalId}`); - return undefined; - } - return terminal; - } - $setEnvironmentVariableCollection(extensionIdentifier: string, persistent: boolean, collection: ISerializableEnvironmentVariableCollection | undefined, descriptionMap: ISerializableEnvironmentDescriptionMap): void { if (collection) { const translatedCollection = { diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 03d4899d196..a6c7fd37e18 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -313,10 +313,6 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { return Promise.resolve(''); } - getLatency(): Promise { - return Promise.resolve(0); - } - startSendingEvents(initialDimensions: ITerminalDimensionsDto | undefined): void { // Attach the listeners this._pty.onDidWrite(e => this._onProcessData.fire(e)); diff --git a/src/vs/workbench/contrib/terminal/browser/remotePty.ts b/src/vs/workbench/contrib/terminal/browser/remotePty.ts index 112b0bb80d2..8ca70a8726d 100644 --- a/src/vs/workbench/contrib/terminal/browser/remotePty.ts +++ b/src/vs/workbench/contrib/terminal/browser/remotePty.ts @@ -209,8 +209,4 @@ export class RemotePty extends Disposable implements ITerminalChildProcess { handleOrphanQuestion() { this._remoteTerminalChannel.orphanQuestionReply(this.id); } - - async getLatency(): Promise { - return 0; - } } diff --git a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts index 3490820c749..4c6bfa6affc 100644 --- a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts @@ -8,6 +8,7 @@ import { Emitter } from 'vs/base/common/event'; import { revive } from 'vs/base/common/marshalling'; import { PerformanceMark, mark } from 'vs/base/common/performance'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform'; +import { StopWatch } from 'vs/base/common/stopwatch'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -15,7 +16,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { ISerializedTerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities'; -import { IShellLaunchConfig, IShellLaunchConfigDto, ITerminalBackend, ITerminalBackendRegistry, ITerminalChildProcess, ITerminalEnvironment, ITerminalLogService, ITerminalProcessOptions, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, ProcessPropertyType, TerminalExtensions, TerminalIcon, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { IPtyHostLatencyMeasurement, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalBackend, ITerminalBackendRegistry, ITerminalChildProcess, ITerminalEnvironment, ITerminalLogService, ITerminalProcessOptions, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, ProcessPropertyType, TerminalExtensions, TerminalIcon, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { IProcessDetails } from 'vs/platform/terminal/common/terminalProcess'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -260,6 +261,19 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack return this._remoteTerminalChannel.listProcesses(); } + async getLatency(): Promise { + const sw = new StopWatch(); + const results = await this._remoteTerminalChannel.getLatency(); + sw.stop(); + return [ + { + label: 'window<->ptyhost', + latency: sw.elapsed() + }, + ...results + ]; + } + async updateProperty(id: number, property: T, value: any): Promise { await this._remoteTerminalChannel.updateProperty(id, property, value); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy.ts index 3c3e980b9c6..2fc4c40f94c 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy.ts @@ -34,17 +34,13 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal readonly onRequestInitialCwd: Event = this._onRequestInitialCwd.event; private readonly _onRequestCwd = this._register(new Emitter()); readonly onRequestCwd: Event = this._onRequestCwd.event; - private readonly _onRequestLatency = this._register(new Emitter()); - readonly onRequestLatency: Event = this._onRequestLatency.event; private readonly _onDidChangeProperty = this._register(new Emitter>()); readonly onDidChangeProperty = this._onDidChangeProperty.event; private readonly _onProcessExit = this._register(new Emitter()); readonly onProcessExit: Event = this._onProcessExit.event; - private _pendingInitialCwdRequests: ((value: string | PromiseLike) => void)[] = []; private _pendingCwdRequests: ((value: string | PromiseLike) => void)[] = []; - private _pendingLatencyRequests: ((value: number | PromiseLike) => void)[] = []; constructor( public instanceId: number, @@ -112,12 +108,6 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal } } - emitLatency(latency: number): void { - while (this._pendingLatencyRequests.length > 0) { - this._pendingLatencyRequests.pop()!(latency); - } - } - async start(): Promise { return this._terminalService.requestStartExtensionTerminal(this, this._cols, this._rows); } @@ -165,13 +155,6 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal }); } - getLatency(): Promise { - return new Promise(resolve => { - this._onRequestLatency.fire(); - this._pendingLatencyRequests.push(resolve); - }); - } - async refreshProperty(type: T): Promise { // throws if called in extHostTerminalService } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 16e37b75b15..b1add9a6c84 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -38,6 +38,7 @@ import Severity from 'vs/base/common/severity'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IEnvironmentVariableCollection, IMergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; import { generateUuid } from 'vs/base/common/uuid'; +import { runWhenIdle } from 'vs/base/common/async'; const enum ProcessConstants { /** @@ -79,8 +80,6 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce private _process: ITerminalChildProcess | null = null; private _processType: ProcessType = ProcessType.Process; private _preLaunchInputQueue: string[] = []; - private _latency: number = -1; - private _latencyLastMeasured: number = 0; private _initialCwd: string | undefined; private _extEnvironmentVariableCollection: IMergedEnvironmentVariableCollection | undefined; private _ackDataBufferer: AckDataBufferer; @@ -152,7 +151,6 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce super(); this._cwdWorkspaceFolder = terminalEnvironment.getWorkspaceForTerminal(cwd, this._workspaceContextService, this._historyService); this.ptyProcessReady = this._createPtyProcessReadyPromise(); - this.getLatency(); this._ackDataBufferer = new AckDataBufferer(e => this._process?.acknowledgeDataEvent(e)); this._dataFilter = this._instantiationService.createInstance(SeamlessRelaunchDataFilter); this._dataFilter.onProcessData(ev => { @@ -394,6 +392,14 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce // Error return result; } + + // Report the latency to the pty host when idle + runWhenIdle(() => { + this.backend?.getLatency().then(measurements => { + this._logService.info(`Latency measurements for ${this.remoteAuthority ?? 'local'} backend\n${measurements.map(e => `${e.label}: ${e.latency.toFixed(2)}ms`).join('\n')}`); + }); + }); + return undefined; } @@ -605,19 +611,6 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce return this._initialCwd ?? ''; } - async getLatency(): Promise { - await this.ptyProcessReady; - if (!this._process) { - return Promise.resolve(0); - } - if (this._latencyLastMeasured === 0 || this._latencyLastMeasured + ProcessConstants.LatencyMeasuringInterval < Date.now()) { - const latencyRequest = this._process.getLatency(); - this._latency = await latencyRequest; - this._latencyLastMeasured = Date.now(); - } - return Promise.resolve(this._latency); - } - async refreshProperty(type: T): Promise { if (!this._process) { throw new Error('Cannot refresh property when process is not set'); diff --git a/src/vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel.ts b/src/vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel.ts index c66a1ec185a..11b60a4f92f 100644 --- a/src/vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel.ts +++ b/src/vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel.ts @@ -17,7 +17,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { Schemas } from 'vs/base/common/network'; import { ILabelService } from 'vs/platform/label/common/label'; import { IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable'; -import { IProcessDataEvent, IRequestResolveVariablesEvent, IShellLaunchConfigDto, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, IProcessProperty, ProcessPropertyType, IProcessPropertyMap, TitleEventSource, ISerializedTerminalState, IPtyHostController, ITerminalProcessOptions, IProcessReadyEvent, ITerminalLogService } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IRequestResolveVariablesEvent, IShellLaunchConfigDto, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, IProcessProperty, ProcessPropertyType, IProcessPropertyMap, TitleEventSource, ISerializedTerminalState, IPtyHostController, ITerminalProcessOptions, IProcessReadyEvent, ITerminalLogService, IPtyHostLatencyMeasurement } from 'vs/platform/terminal/common/terminal'; import { IGetTerminalLayoutInfoArgs, IProcessDetails, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform'; import { ICompleteTerminalConfiguration } from 'vs/workbench/contrib/terminal/common/terminal'; @@ -203,6 +203,9 @@ export class RemoteTerminalChannelClient implements IPtyHostController { listProcesses(): Promise { return this._channel.call(RemoteTerminalChannelRequest.ListProcesses); } + getLatency(): Promise { + return this._channel.call(RemoteTerminalChannelRequest.GetLatency); + } getPerformanceMarks(): Promise { return this._channel.call(RemoteTerminalChannelRequest.GetPerformanceMarks); } diff --git a/src/vs/workbench/contrib/terminal/common/remote/terminal.ts b/src/vs/workbench/contrib/terminal/common/remote/terminal.ts index 22aa8cf6dc4..54498e30cff 100644 --- a/src/vs/workbench/contrib/terminal/common/remote/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/remote/terminal.ts @@ -63,6 +63,7 @@ export const enum RemoteTerminalChannelRequest { AttachToProcess = '$attachToProcess', DetachFromProcess = '$detachFromProcess', ListProcesses = '$listProcesses', + GetLatency = '$getLatency', GetPerformanceMarks = '$getPerformanceMarks', OrphanQuestionReply = '$orphanQuestionReply', AcceptPtyHostResolvedVariables = '$acceptPtyHostResolvedVariables', diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index aae1d4721bd..c1d5c806b2f 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -299,7 +299,6 @@ export interface ITerminalProcessManager extends IDisposable { acknowledgeDataEvent(charCount: number): void; processBinary(data: string): void; - getLatency(): Promise; refreshProperty(type: T): Promise; updateProperty(property: T, value: IProcessPropertyMap[T]): Promise; getBackendOS(): Promise; @@ -331,7 +330,6 @@ export interface ITerminalProcessExtHostProxy extends IDisposable { emitData(data: string): void; emitProcessProperty(property: IProcessProperty): void; emitReady(pid: number, cwd: string, windowsPty: IProcessReadyWindowsPty | undefined): void; - emitLatency(latency: number): void; emitExit(exitCode: number | undefined): void; onInput: Event; @@ -341,7 +339,6 @@ export interface ITerminalProcessExtHostProxy extends IDisposable { onShutdown: Event; onRequestInitialCwd: Event; onRequestCwd: Event; - onRequestLatency: Event; } export interface IStartExtensionTerminalRequest { diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localPty.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localPty.ts index bb6b8bd174b..fd083280d28 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localPty.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localPty.ts @@ -102,10 +102,6 @@ export class LocalPty extends Disposable implements ITerminalChildProcess { async updateProperty(type: T, value: IProcessPropertyMap[T]): Promise { return this._proxy.updateProperty(this.id, type, value); } - getLatency(): Promise { - // TODO: The idea here was to add the result plus the time it took to get the latency - return this._proxy.getLatency(this.id); - } acknowledgeDataEvent(charCount: number): void { if (this._inReplay) { return; diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts index 4f976936a55..5636c0ad660 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts @@ -12,7 +12,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ILabelService } from 'vs/platform/label/common/label'; import { Registry } from 'vs/platform/registry/common/platform'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { ILocalPtyService, IProcessPropertyMap, IPtyService, IShellLaunchConfig, ITerminalBackend, ITerminalBackendRegistry, ITerminalChildProcess, ITerminalEnvironment, ITerminalLogService, ITerminalProcessOptions, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, ProcessPropertyType, TerminalExtensions, TerminalIpcChannels, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { ILocalPtyService, IProcessPropertyMap, IPtyHostLatencyMeasurement, IPtyService, IShellLaunchConfig, ITerminalBackend, ITerminalBackendRegistry, ITerminalChildProcess, ITerminalEnvironment, ITerminalLogService, ITerminalProcessOptions, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, ProcessPropertyType, TerminalExtensions, TerminalIpcChannels, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { IGetTerminalLayoutInfoArgs, IProcessDetails, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -36,6 +36,7 @@ import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecyc import { DeferredPromise } from 'vs/base/common/async'; import { IStatusbarService } from 'vs/workbench/services/statusbar/browser/statusbar'; import { memoize } from 'vs/base/common/decorators'; +import { StopWatch } from 'vs/base/common/stopwatch'; export class LocalTerminalBackendContribution implements IWorkbenchContribution { constructor( @@ -245,6 +246,30 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke return this._proxy.listProcesses(); } + async getLatency(): Promise { + const measurements: IPtyHostLatencyMeasurement[] = []; + const sw = new StopWatch(); + if (this._directProxy) { + await this._directProxy.getLatency(); + sw.stop(); + measurements.push({ + label: 'window<->ptyhost (message port)', + latency: sw.elapsed() + }); + sw.reset(); + } + const results = await this._localPtyService.getLatency(); + sw.stop(); + measurements.push({ + label: 'window<->main<->ptyhost', + latency: sw.elapsed() + }); + return [ + ...measurements, + ...results + ]; + } + async getPerformanceMarks(): Promise { return this._proxy.getPerformanceMarks(); } diff --git a/src/vs/workbench/contrib/terminal/test/browser/terminalProcessManager.test.ts b/src/vs/workbench/contrib/terminal/test/browser/terminalProcessManager.test.ts index 4d8b79c9d98..b7291fc85f4 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/terminalProcessManager.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/terminalProcessManager.test.ts @@ -51,7 +51,6 @@ class TestTerminalChildProcess implements ITerminalChildProcess { async setUnicodeVersion(version: '6' | '11'): Promise { } async getInitialCwd(): Promise { return ''; } async getCwd(): Promise { return ''; } - async getLatency(): Promise { return 0; } async processBinary(data: string): Promise { } refreshProperty(property: any): Promise { return Promise.resolve(''); } } diff --git a/src/vs/workbench/services/terminal/common/embedderTerminalService.ts b/src/vs/workbench/services/terminal/common/embedderTerminalService.ts index 61c4a433e09..5e322af7a0f 100644 --- a/src/vs/workbench/services/terminal/common/embedderTerminalService.ts +++ b/src/vs/workbench/services/terminal/common/embedderTerminalService.ts @@ -139,9 +139,6 @@ class EmbedderTerminalProcess extends Disposable implements ITerminalChildProces async getCwd(): Promise { return ''; } - async getLatency(): Promise { - return 0; - } refreshProperty(property: ProcessPropertyType): Promise { throw new Error(`refreshProperty is not suppported in EmbedderTerminalProcess. property: ${property}`); } From 6ea4677f1411796d33faa67165915fd67c6aff94 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 7 Jul 2023 08:39:10 -0700 Subject: [PATCH 061/119] Make ptyhostservice label consistent --- .../workbench/contrib/terminal/browser/remoteTerminalBackend.ts | 2 +- .../contrib/terminal/electron-sandbox/localTerminalBackend.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts index 4c6bfa6affc..855d21f39c9 100644 --- a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts @@ -267,7 +267,7 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack sw.stop(); return [ { - label: 'window<->ptyhost', + label: 'window<->ptyhostservice<->ptyhost', latency: sw.elapsed() }, ...results diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts index 5636c0ad660..a07bea61575 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts @@ -261,7 +261,7 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke const results = await this._localPtyService.getLatency(); sw.stop(); measurements.push({ - label: 'window<->main<->ptyhost', + label: 'window<->ptyhostservice<->ptyhost', latency: sw.elapsed() }); return [ From dc189ed8c32ca0edcf10b1a2297319cd9cb503df Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 7 Jul 2023 09:53:58 -0700 Subject: [PATCH 062/119] Ensure layout info is fetched from the pty host on reconnects Fixes #187282 --- .../platform/terminal/node/ptyHostService.ts | 5 +- src/vs/platform/terminal/node/ptyService.ts | 5 +- .../terminal/browser/remoteTerminalBackend.ts | 42 ++++++----- .../electron-sandbox/localTerminalBackend.ts | 70 +++++++++---------- 4 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index a9b9a2e57ae..324e4063d95 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -326,7 +326,10 @@ export class PtyHostService extends Disposable implements IPtyHostService { return this._proxy.setTerminalLayoutInfo(args); } async getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise { - return await this._proxy.getTerminalLayoutInfo(args); + // This is optional as we want reconnect requests to go through only if the pty host exists. + // Revive is handled specially as reviveTerminalProcesses is guaranteed to be called before + // the request for layout info. + return this._optionalProxy?.getTerminalLayoutInfo(args); } async requestDetachInstance(workspaceId: string, instanceId: number): Promise { diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 4661924d5dc..7e017ab5ccd 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -552,8 +552,9 @@ export class PtyService extends Disposable implements IPtyService { }; } catch (e) { this._logService.warn(`Couldn't get layout info, a terminal was probably disconnected`, e.message); - this._logService.info('Reattach to wrong terminal debug info - layout info by id', t); - this._logService.info('Reattach to wrong terminal debug info - _revivePtyIdMap', Array.from(this._revivedPtyIdMap.values())); + this._logService.debug('Reattach to wrong terminal debug info - layout info by id', t); + this._logService.debug('Reattach to wrong terminal debug info - _revivePtyIdMap', Array.from(this._revivedPtyIdMap.values())); + this._logService.debug('Reattach to wrong terminal debug info - _ptys ids', Array.from(this._ptys.keys())); // this will be filtered out and not reconnected return { terminal: null, diff --git a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts index 855d21f39c9..a893c53f6ae 100644 --- a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts @@ -337,29 +337,27 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack // Revive processes if needed const serializedState = this._storageService.get(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE); - const parsed = this._deserializeTerminalState(serializedState); - if (!parsed) { - return undefined; - } - - try { - // Note that remote terminals do not get their environment re-resolved unlike in local terminals - - mark('code/terminal/willReviveTerminalProcessesRemote'); - await this._remoteTerminalChannel.reviveTerminalProcesses(parsed, Intl.DateTimeFormat().resolvedOptions().locale); - mark('code/terminal/didReviveTerminalProcessesRemote'); - this._storageService.remove(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE); - // If reviving processes, send the terminal layout info back to the pty host as it - // will not have been persisted on application exit - const layoutInfo = this._storageService.get(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); - if (layoutInfo) { - mark('code/terminal/willSetTerminalLayoutInfoRemote'); - await this._remoteTerminalChannel.setTerminalLayoutInfo(JSON.parse(layoutInfo)); - mark('code/terminal/didSetTerminalLayoutInfoRemote'); - this._storageService.remove(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); + const reviveBufferState = this._deserializeTerminalState(serializedState); + if (reviveBufferState && reviveBufferState.length > 0) { + try { + // Note that remote terminals do not get their environment re-resolved unlike in local terminals + + mark('code/terminal/willReviveTerminalProcessesRemote'); + await this._remoteTerminalChannel.reviveTerminalProcesses(reviveBufferState, Intl.DateTimeFormat().resolvedOptions().locale); + mark('code/terminal/didReviveTerminalProcessesRemote'); + this._storageService.remove(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE); + // If reviving processes, send the terminal layout info back to the pty host as it + // will not have been persisted on application exit + const layoutInfo = this._storageService.get(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); + if (layoutInfo) { + mark('code/terminal/willSetTerminalLayoutInfoRemote'); + await this._remoteTerminalChannel.setTerminalLayoutInfo(JSON.parse(layoutInfo)); + mark('code/terminal/didSetTerminalLayoutInfoRemote'); + this._storageService.remove(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); + } + } catch (e: unknown) { + this._logService.warn('RemoteTerminalBackend#getTerminalLayoutInfo Error', e && typeof e === 'object' && 'message' in e ? e.message : e); } - } catch (e: unknown) { - this._logService.warn('RemoteTerminalBackend#getTerminalLayoutInfo Error', e && typeof e === 'object' && 'message' in e ? e.message : e); } return this._remoteTerminalChannel.getTerminalLayoutInfo(); diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts index a07bea61575..d89cc49042a 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts @@ -317,43 +317,41 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke // Revive processes if needed const serializedState = this._storageService.get(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE); - const parsed = this._deserializeTerminalState(serializedState); - if (!parsed) { - return undefined; - } - - try { - // Create variable resolver - const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(); - const lastActiveWorkspace = activeWorkspaceRootUri ? withNullAsUndefined(this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri)) : undefined; - const variableResolver = terminalEnvironment.createVariableResolver(lastActiveWorkspace, await this._terminalProfileResolverService.getEnvironment(this.remoteAuthority), this._configurationResolverService); - - // Re-resolve the environments and replace it on the state so local terminals use a fresh - // environment - mark('code/terminal/willGetReviveEnvironments'); - await Promise.all(parsed.map(state => new Promise(r => { - this._resolveEnvironmentForRevive(variableResolver, state.shellLaunchConfig).then(freshEnv => { - state.processLaunchConfig.env = freshEnv; - r(); - }); - }))); - mark('code/terminal/didGetReviveEnvironments'); - - mark('code/terminal/willReviveTerminalProcesses'); - await this._proxy.reviveTerminalProcesses(workspaceId, parsed, Intl.DateTimeFormat().resolvedOptions().locale); - mark('code/terminal/didReviveTerminalProcesses'); - this._storageService.remove(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE); - // If reviving processes, send the terminal layout info back to the pty host as it - // will not have been persisted on application exit - const layoutInfo = this._storageService.get(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); - if (layoutInfo) { - mark('code/terminal/willSetTerminalLayoutInfo'); - await this._proxy.setTerminalLayoutInfo(JSON.parse(layoutInfo)); - mark('code/terminal/didSetTerminalLayoutInfo'); - this._storageService.remove(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); + const reviveBufferState = this._deserializeTerminalState(serializedState); + if (reviveBufferState && reviveBufferState.length > 0) { + try { + // Create variable resolver + const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(); + const lastActiveWorkspace = activeWorkspaceRootUri ? withNullAsUndefined(this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri)) : undefined; + const variableResolver = terminalEnvironment.createVariableResolver(lastActiveWorkspace, await this._terminalProfileResolverService.getEnvironment(this.remoteAuthority), this._configurationResolverService); + + // Re-resolve the environments and replace it on the state so local terminals use a fresh + // environment + mark('code/terminal/willGetReviveEnvironments'); + await Promise.all(reviveBufferState.map(state => new Promise(r => { + this._resolveEnvironmentForRevive(variableResolver, state.shellLaunchConfig).then(freshEnv => { + state.processLaunchConfig.env = freshEnv; + r(); + }); + }))); + mark('code/terminal/didGetReviveEnvironments'); + + mark('code/terminal/willReviveTerminalProcesses'); + await this._proxy.reviveTerminalProcesses(workspaceId, reviveBufferState, Intl.DateTimeFormat().resolvedOptions().locale); + mark('code/terminal/didReviveTerminalProcesses'); + this._storageService.remove(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE); + // If reviving processes, send the terminal layout info back to the pty host as it + // will not have been persisted on application exit + const layoutInfo = this._storageService.get(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); + if (layoutInfo) { + mark('code/terminal/willSetTerminalLayoutInfo'); + await this._proxy.setTerminalLayoutInfo(JSON.parse(layoutInfo)); + mark('code/terminal/didSetTerminalLayoutInfo'); + this._storageService.remove(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE); + } + } catch (e: unknown) { + this._logService.warn('LocalTerminalBackend#getTerminalLayoutInfo Error', e && typeof e === 'object' && 'message' in e ? e.message : e); } - } catch (e: unknown) { - this._logService.warn('LocalTerminalBackend#getTerminalLayoutInfo Error', e && typeof e === 'object' && 'message' in e ? e.message : e); } return this._proxy.getTerminalLayoutInfo(layoutArgs); From e1338bd060b46bcdf35c73580348645165f0fd56 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 7 Jul 2023 19:11:00 +0200 Subject: [PATCH 063/119] Update to @vscode/proxy-agent 0.15.0 --- package.json | 2 +- remote/package.json | 2 +- remote/yarn.lock | 8 ++++---- yarn.lock | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 2673e2279aa..224789cf9ec 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@parcel/watcher": "2.1.0", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/policy-watcher": "^1.1.4", - "@vscode/proxy-agent": "^0.14.1", + "@vscode/proxy-agent": "^0.15.0", "@vscode/ripgrep": "^1.15.5", "@vscode/spdlog": "^0.13.10", "@vscode/sqlite3": "5.1.6-vscode", diff --git a/remote/package.json b/remote/package.json index 2f5f6ce57b8..832b8d5dbd3 100644 --- a/remote/package.json +++ b/remote/package.json @@ -7,7 +7,7 @@ "@microsoft/1ds-post-js": "^3.2.2", "@parcel/watcher": "2.1.0", "@vscode/iconv-lite-umd": "0.7.0", - "@vscode/proxy-agent": "^0.14.1", + "@vscode/proxy-agent": "^0.15.0", "@vscode/ripgrep": "^1.15.5", "@vscode/spdlog": "^0.13.10", "@vscode/vscode-languagedetection": "1.0.21", diff --git a/remote/yarn.lock b/remote/yarn.lock index 0539567ca2d..531ba983765 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -58,10 +58,10 @@ resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48" integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg== -"@vscode/proxy-agent@^0.14.1": - version "0.14.1" - resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.14.1.tgz#61866221a8fbd5143f73a14c29deccdf85f13113" - integrity sha512-bJxCO9E6zDpy90TiViAZgFjAgo83gS0Lh5CUIu/JZ8p5UwwQ37Y6LZH2f2l6kBr2RGdNSRbORTFrfmLtr1faRA== +"@vscode/proxy-agent@^0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.15.0.tgz#b8fb8b89180a71295a8f8682775f69ab1dcf6860" + integrity sha512-HpD4A9CUOwKbC6vLa0+MEsCo/qlgbue9U9s8Z7NzJDdf2YEGjUaYf9Mvj5T1LhJX20Hv1COvkGcc7zPhtIbgbA== dependencies: "@tootallnate/once" "^1.1.2" agent-base "^6.0.2" diff --git a/yarn.lock b/yarn.lock index 689f60907af..8ebb45b9118 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1309,10 +1309,10 @@ bindings "^1.5.0" node-addon-api "^6.0.0" -"@vscode/proxy-agent@^0.14.1": - version "0.14.1" - resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.14.1.tgz#61866221a8fbd5143f73a14c29deccdf85f13113" - integrity sha512-bJxCO9E6zDpy90TiViAZgFjAgo83gS0Lh5CUIu/JZ8p5UwwQ37Y6LZH2f2l6kBr2RGdNSRbORTFrfmLtr1faRA== +"@vscode/proxy-agent@^0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.15.0.tgz#b8fb8b89180a71295a8f8682775f69ab1dcf6860" + integrity sha512-HpD4A9CUOwKbC6vLa0+MEsCo/qlgbue9U9s8Z7NzJDdf2YEGjUaYf9Mvj5T1LhJX20Hv1COvkGcc7zPhtIbgbA== dependencies: "@tootallnate/once" "^1.1.2" agent-base "^6.0.2" From e954d50a4c77e919cd7513040c5eee3b7597819f Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 7 Jul 2023 20:02:26 +0200 Subject: [PATCH 064/119] Fixes #187140 (#187291) --- .../textMate/browser/worker/textMateWorkerModel.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/textMate/browser/worker/textMateWorkerModel.ts b/src/vs/workbench/services/textMate/browser/worker/textMateWorkerModel.ts index cb2f98adff9..db68091ac5f 100644 --- a/src/vs/workbench/services/textMate/browser/worker/textMateWorkerModel.ts +++ b/src/vs/workbench/services/textMate/browser/worker/textMateWorkerModel.ts @@ -3,21 +3,22 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { importAMDNodeModule } from 'vs/amdX'; import { RunOnceScheduler } from 'vs/base/common/async'; import { observableValue } from 'vs/base/common/observable'; +import { setTimeout0 } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { LanguageId } from 'vs/editor/common/encodedTokenAttributes'; import { IModelChangedEvent, MirrorTextModel } from 'vs/editor/common/model/mirrorTextModel'; import { TokenizerWithStateStore } from 'vs/editor/common/model/textModelTokens'; -import type { diffStateStacksRefEq, StateStack, StackDiff } from 'vscode-textmate'; import { ContiguousMultilineTokensBuilder } from 'vs/editor/common/tokens/contiguousMultilineTokensBuilder'; import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; import { TextMateTokenizationSupport } from 'vs/workbench/services/textMate/browser/tokenizationSupport/textMateTokenizationSupport'; import { TokenizationSupportWithLineLimit } from 'vs/workbench/services/textMate/browser/tokenizationSupport/tokenizationSupportWithLineLimit'; import { StateDeltas } from 'vs/workbench/services/textMate/browser/workerHost/textMateWorkerHost'; +import type { StackDiff, StateStack, diffStateStacksRefEq } from 'vscode-textmate'; import { TextMateTokenizationWorker } from './textMate.worker'; -import { importAMDNodeModule } from 'vs/amdX'; export class TextMateWorkerModel extends MirrorTextModel { private _tokenizationStateStore: TokenizerWithStateStore | null = null; @@ -169,7 +170,7 @@ export class TextMateWorkerModel extends MirrorTextModel { const deltaMs = new Date().getTime() - startTime; if (deltaMs > 20) { // yield to check for changes - setTimeout(() => this._tokenize(), 3); + setTimeout0(() => this._tokenize()); return; } } From 66b0f928408be2f70fb477f12bd4501175f7d14b Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Fri, 7 Jul 2023 11:08:51 -0700 Subject: [PATCH 065/119] treat soon to be saved by auto-save as saving --- .../contrib/notebook/common/notebookEditorInput.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts index 9db655f6a63..940d887c0f1 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts @@ -24,7 +24,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { IWorkingCopyIdentifier } from 'vs/workbench/services/workingCopy/common/workingCopy'; import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider'; import { NotebookPerfMarks } from 'vs/workbench/contrib/notebook/common/notebookPerformance'; -import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { localize } from 'vs/nls'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -216,6 +216,14 @@ export class NotebookEditorInput extends AbstractResourceEditorInput { return await this._editorModelReference.object.saveAs(target); } + override isSaving(): boolean { + if (this.isDirty() && !this.hasCapability(EditorInputCapabilities.Untitled) && this.filesConfigurationService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { + return true; // will be saved soon + } + + return super.isSaving(); + } + private async _suggestName(provider: NotebookProviderInfo, suggestedFilename: string) { // guess file extensions const firstSelector = provider.selectors[0]; From 437342409bf7e695ca03d9299c2661bfc9fc0376 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Fri, 7 Jul 2023 11:27:09 -0700 Subject: [PATCH 066/119] Force new window for remote -> local Continue On (#187301) Force new window for remote -> local clone --- extensions/git/src/commands.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 4213aafa495..ef9b0a56fad 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -750,15 +750,22 @@ export class CommandCenter { if (uri !== undefined) { // Launch desktop client if currently in web + let target = `${env.uriScheme}://vscode.git/clone?url=${encodeURIComponent(uri)}`; if (env.uiKind === UIKind.Web) { - let target = `${env.uriScheme}://vscode.git/clone?url=${encodeURIComponent(uri)}`; if (ref !== undefined) { target += `&ref=${encodeURIComponent(ref)}`; } return Uri.parse(target); } - // If already in desktop client, directly clone + // If already in desktop client but in a remote window, we need to force a new window + // so that the git extension can access the local filesystem for cloning + if (env.remoteName !== undefined) { + target += `&windowId=_blank`; + return Uri.parse(target); + } + + // Otherwise, directly clone void this.clone(uri, undefined, { ref: ref }); } } From 9e390f32b43a43ee3f331b90e1a79db2c295431a Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 7 Jul 2023 20:28:14 +0200 Subject: [PATCH 067/119] Fixes #186393 (#187295) --- .../diffEditorDecorations.ts | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts index 78f20246013..8a821c0b135 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts @@ -6,7 +6,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IObservable, derived } from 'vs/base/common/observable'; import { isDefined } from 'vs/base/common/types'; -import { arrowRevertChange, diffAddDecoration, diffAddDecorationEmpty, diffDeleteDecoration, diffDeleteDecorationEmpty, diffLineAddDecorationBackground, diffLineAddDecorationBackgroundWithIndicator, diffLineDeleteDecorationBackground, diffLineDeleteDecorationBackgroundWithIndicator } from 'vs/editor/browser/widget/diffEditorWidget2/decorations'; +import { arrowRevertChange, diffAddDecoration, diffAddDecorationEmpty, diffDeleteDecoration, diffDeleteDecorationEmpty, diffLineAddDecorationBackground, diffLineAddDecorationBackgroundWithIndicator, diffLineDeleteDecorationBackground, diffLineDeleteDecorationBackgroundWithIndicator, diffWholeLineAddDecoration, diffWholeLineDeleteDecoration } from 'vs/editor/browser/widget/diffEditorWidget2/decorations'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; import { DiffEditorOptions } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions'; import { DiffEditorViewModel } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; @@ -54,19 +54,28 @@ export class DiffEditorDecorations extends Disposable { modifiedDecorations.push({ range, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground }); } - for (const i of m.lineRangeMapping.innerChanges || []) { - if (currentMove - && (currentMove.lineRangeMapping.originalRange.intersect(new LineRange(i.originalRange.startLineNumber, i.originalRange.endLineNumber)) - || currentMove.lineRangeMapping.modifiedRange.intersect(new LineRange(i.modifiedRange.startLineNumber, i.modifiedRange.endLineNumber)))) { - continue; + if (m.lineRangeMapping.modifiedRange.isEmpty || m.lineRangeMapping.originalRange.isEmpty) { + for (const range of fullRangeOriginal) { + originalDecorations.push({ range, options: diffWholeLineDeleteDecoration }); } - - // Don't show empty markers outside the line range - if (m.lineRangeMapping.originalRange.contains(i.originalRange.startLineNumber)) { - originalDecorations.push({ range: i.originalRange, options: (i.originalRange.isEmpty() && showEmptyDecorations) ? diffDeleteDecorationEmpty : diffDeleteDecoration }); + for (const range of fullRangeModified) { + modifiedDecorations.push({ range, options: diffWholeLineAddDecoration }); } - if (m.lineRangeMapping.modifiedRange.contains(i.modifiedRange.startLineNumber)) { - modifiedDecorations.push({ range: i.modifiedRange, options: (i.modifiedRange.isEmpty() && showEmptyDecorations) ? diffAddDecorationEmpty : diffAddDecoration }); + } else { + for (const i of m.lineRangeMapping.innerChanges || []) { + if (currentMove + && (currentMove.lineRangeMapping.originalRange.intersect(new LineRange(i.originalRange.startLineNumber, i.originalRange.endLineNumber)) + || currentMove.lineRangeMapping.modifiedRange.intersect(new LineRange(i.modifiedRange.startLineNumber, i.modifiedRange.endLineNumber)))) { + continue; + } + + // Don't show empty markers outside the line range + if (m.lineRangeMapping.originalRange.contains(i.originalRange.startLineNumber)) { + originalDecorations.push({ range: i.originalRange, options: (i.originalRange.isEmpty() && showEmptyDecorations) ? diffDeleteDecorationEmpty : diffDeleteDecoration }); + } + if (m.lineRangeMapping.modifiedRange.contains(i.modifiedRange.startLineNumber)) { + modifiedDecorations.push({ range: i.modifiedRange, options: (i.modifiedRange.isEmpty() && showEmptyDecorations) ? diffAddDecorationEmpty : diffAddDecoration }); + } } } From ad791ef3d26b99963da31636af697afd86575435 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 7 Jul 2023 20:42:45 +0200 Subject: [PATCH 068/119] fix installing extension from CLI (#187305) --- src/vs/code/node/cliProcessMain.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 73268f714f7..0065a8da62e 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -62,6 +62,7 @@ import { ExtensionsProfileScannerService } from 'vs/platform/extensionManagement import { LogService } from 'vs/platform/log/common/logService'; import { LoggerService } from 'vs/platform/log/node/loggerService'; import { localize } from 'vs/nls'; +import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider'; class CliMain extends Disposable { @@ -145,6 +146,10 @@ class CliMain extends Disposable { const diskFileSystemProvider = this._register(new DiskFileSystemProvider(logService)); fileService.registerProvider(Schemas.file, diskFileSystemProvider); + // Use FileUserDataProvider for user data to + // enable atomic read / write operations. + fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, logService)); + // Uri Identity const uriIdentityService = new UriIdentityService(fileService); services.set(IUriIdentityService, uriIdentityService); From 0917209e9acd6a4fe11ee65ef762bce783a2c285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 7 Jul 2023 20:45:35 +0200 Subject: [PATCH 069/119] Always publish build artifacts, if built (#187134) * always publish build artifacts, if built fixes #187122 * fix windows build * fix builds * fix * more fixes * further debug * fix yarn * remove debug * remove 7zip dependency * fix snap --- .../alpine/product-build-alpine.yml | 56 ++++----- .../darwin/product-build-darwin-test.yml | 10 +- .../darwin/product-build-darwin.yml | 59 +++++----- .../azure-pipelines/linux/prepare-publish.sh | 66 ----------- .../linux/product-build-linux-test.yml | 10 +- .../linux/product-build-linux.yml | 89 ++++++++++----- .../linux/snap-build-linux.yml | 6 +- .../azure-pipelines/web/product-build-web.yml | 25 ++-- .../azure-pipelines/win32/prepare-publish.ps1 | 40 ------- .../win32/product-build-win32-test.yml | 15 ++- .../win32/product-build-win32.yml | 107 ++++++++++++++---- build/gulpfile.vscode.win32.js | 20 ---- package.json | 1 - yarn.lock | 5 - 14 files changed, 232 insertions(+), 277 deletions(-) delete mode 100755 build/azure-pipelines/linux/prepare-publish.sh delete mode 100644 build/azure-pipelines/win32/prepare-publish.ps1 diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index 04f9ad2fcf2..704f4814ae9 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -104,55 +104,47 @@ steps: - script: | set -e - TARGET=$([ "$VSCODE_ARCH" == "x64" ] && echo "linux-alpine" || echo "alpine-arm64") + TARGET=$([ "$VSCODE_ARCH" == "x64" ] && echo "linux-alpine" || echo "alpine-arm64") # TODO@joaomoreno yarn gulp vscode-reh-$TARGET-min-ci - yarn gulp vscode-reh-web-$TARGET-min-ci + (cd .. && mv vscode-reh-$TARGET vscode-server-$TARGET) # TODO@joaomoreno + ARCHIVE_PATH=".build/linux/server/vscode-server-$TARGET.tar.gz" + mkdir -p $(dirname $ARCHIVE_PATH) + tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-$TARGET + echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" - displayName: Build + displayName: Build server - script: | set -e TARGET=$([ "$VSCODE_ARCH" == "x64" ] && echo "linux-alpine" || echo "alpine-arm64") - REPO="$(pwd)" - ROOT="$REPO/.." - - # Publish Remote Extension Host - LEGACY_SERVER_BUILD_NAME="vscode-reh-$TARGET" - SERVER_BUILD_NAME="vscode-server-$TARGET" - SERVER_TARBALL_FILENAME="vscode-server-$TARGET.tar.gz" - SERVER_TARBALL_PATH="$ROOT/$SERVER_TARBALL_FILENAME" - - rm -rf $ROOT/vscode-server-*.tar.* - (cd $ROOT && mv $LEGACY_SERVER_BUILD_NAME $SERVER_BUILD_NAME && tar --owner=0 --group=0 -czf $SERVER_TARBALL_PATH $SERVER_BUILD_NAME) - - # Publish Remote Extension Host (Web) - LEGACY_SERVER_BUILD_NAME="vscode-reh-web-$TARGET" - SERVER_BUILD_NAME="vscode-server-$TARGET-web" - SERVER_TARBALL_FILENAME="vscode-server-$TARGET-web.tar.gz" - SERVER_TARBALL_PATH="$ROOT/$SERVER_TARBALL_FILENAME" - - rm -rf $ROOT/vscode-server-*-web.tar.* - (cd $ROOT && mv $LEGACY_SERVER_BUILD_NAME $SERVER_BUILD_NAME && tar --owner=0 --group=0 -czf $SERVER_TARBALL_PATH $SERVER_BUILD_NAME) - displayName: Prepare for publish + yarn gulp vscode-reh-web-$TARGET-min-ci + (cd .. && mv vscode-reh-web-$TARGET vscode-server-$TARGET-web) # TODO@joaomoreno + ARCHIVE_PATH=".build/linux/web/vscode-server-$TARGET-web.tar.gz" + mkdir -p $(dirname $ARCHIVE_PATH) + tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-$TARGET-web + echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Build server (web) - - publish: $(Agent.BuildDirectory)/vscode-server-alpine-$(VSCODE_ARCH).tar.gz + - publish: $(SERVER_PATH) artifact: vscode_server_alpine_$(VSCODE_ARCH)_archive-unsigned displayName: Publish server archive - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'x64')) + condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], ''), ne(variables['VSCODE_ARCH'], 'x64')) - - publish: $(Agent.BuildDirectory)/vscode-server-alpine-$(VSCODE_ARCH)-web.tar.gz + - publish: $(WEB_PATH) artifact: vscode_web_alpine_$(VSCODE_ARCH)_archive-unsigned displayName: Publish web server archive - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'x64')) + condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], ''), ne(variables['VSCODE_ARCH'], 'x64')) # Legacy x64 artifact name - - publish: $(Agent.BuildDirectory)/vscode-server-linux-alpine.tar.gz + - publish: $(SERVER_PATH) artifact: vscode_server_linux_alpine_archive-unsigned displayName: Publish x64 server archive - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) + condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], ''), eq(variables['VSCODE_ARCH'], 'x64')) - - publish: $(Agent.BuildDirectory)/vscode-server-linux-alpine-web.tar.gz + - publish: $(WEB_PATH) artifact: vscode_web_linux_alpine_archive-unsigned displayName: Publish x64 web server archive - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) + condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], ''), eq(variables['VSCODE_ARCH'], 'x64')) diff --git a/build/azure-pipelines/darwin/product-build-darwin-test.yml b/build/azure-pipelines/darwin/product-build-darwin-test.yml index 0b445933265..955b19749a6 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-test.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-test.yml @@ -84,13 +84,13 @@ steps: INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \ ./scripts/test-integration.sh --build --tfs "Integration Tests" env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-reh-darwin-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH) displayName: Run integration tests (Electron) timeoutInMinutes: 20 - script: ./scripts/test-web-integration.sh --browser webkit env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-reh-web-darwin-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web displayName: Run integration tests (Browser, Webkit) timeoutInMinutes: 20 @@ -101,7 +101,7 @@ steps: INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \ ./scripts/test-remote-integration.sh env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-reh-darwin-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH) displayName: Run integration tests (Remote) timeoutInMinutes: 20 @@ -133,7 +133,7 @@ steps: - script: yarn smoketest-no-compile --web --tracing --headless env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-reh-web-darwin-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web timeoutInMinutes: 20 displayName: Run smoke tests (Browser, Chromium) @@ -144,7 +144,7 @@ steps: APP_NAME="`ls $APP_ROOT | head -n 1`" yarn smoketest-no-compile --tracing --remote --build "$APP_ROOT/$APP_NAME" env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-reh-darwin-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH) timeoutInMinutes: 20 displayName: Run smoke tests (Remote) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index f7810b6f076..95d81431089 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -111,17 +111,34 @@ steps: - template: ../common/install-builtin-extensions.yml - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: yarn gulp vscode-darwin-$(VSCODE_ARCH)-min-ci + - script: | + set -e + yarn gulp vscode-darwin-$(VSCODE_ARCH)-min-ci + echo "##vso[task.setvariable variable=BUILT_CLIENT]true" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build client - - script: yarn gulp vscode-reh-darwin-$(VSCODE_ARCH)-min-ci + - script: | + set -e + yarn gulp vscode-reh-darwin-$(VSCODE_ARCH)-min-ci + mv ../vscode-reh-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH) # TODO@joaomoreno + ARCHIVE_PATH=".build/darwin/server/vscode-server-darwin-$(VSCODE_ARCH).zip" + mkdir -p $(dirname $ARCHIVE_PATH) + (cd .. && zip -Xry $(Build.SourcesDirectory)/$ARCHIVE_PATH vscode-server-darwin-$(VSCODE_ARCH)) + echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server - - script: yarn gulp vscode-reh-web-darwin-$(VSCODE_ARCH)-min-ci + - script: | + set -e + yarn gulp vscode-reh-web-darwin-$(VSCODE_ARCH)-min-ci + mv ../vscode-reh-web-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH)-web # TODO@joaomoreno + ARCHIVE_PATH=".build/darwin/server/vscode-server-darwin-$(VSCODE_ARCH)-web.zip" + mkdir -p $(dirname $ARCHIVE_PATH) + (cd .. && zip -Xry $(Build.SourcesDirectory)/$ARCHIVE_PATH vscode-server-darwin-$(VSCODE_ARCH)-web) + echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server (web) @@ -176,18 +193,14 @@ steps: DEBUG=electron-osx-sign* node build/darwin/sign.js $(agent.builddirectory) displayName: Set Hardened Entitlements - - script: cd $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) && zip -r -X -y $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH).zip * - displayName: Archive build - - script: | set -e - - # package Remote Extension Host - pushd .. && mv vscode-reh-darwin-$(VSCODE_ARCH) vscode-server-darwin-$(VSCODE_ARCH) && zip -Xry vscode-server-darwin-$(VSCODE_ARCH).zip vscode-server-darwin-$(VSCODE_ARCH) && popd - - # package Remote Extension Host (Web) - pushd .. && mv vscode-reh-web-darwin-$(VSCODE_ARCH) vscode-server-darwin-$(VSCODE_ARCH)-web && zip -Xry vscode-server-darwin-$(VSCODE_ARCH)-web.zip vscode-server-darwin-$(VSCODE_ARCH)-web && popd - displayName: Prepare to publish servers + ARCHIVE_PATH=".build/darwin/client/VSCode-darwin-$(VSCODE_ARCH).zip" + mkdir -p $(dirname $ARCHIVE_PATH) + (cd ../VSCode-darwin-$(VSCODE_ARCH) && zip -Xry $(Build.SourcesDirectory)/$ARCHIVE_PATH *) + echo "##vso[task.setvariable variable=CLIENT_PATH]$ARCHIVE_PATH" + condition: and(succeededOrFailed(), eq(variables['BUILT_CLIENT'], 'true')) + displayName: Package client - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 displayName: Generate SBOM (client) @@ -209,25 +222,17 @@ steps: displayName: Publish SBOM (server) artifact: vscode_server_darwin_$(VSCODE_ARCH)_sbom - - publish: $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH).zip + - publish: $(CLIENT_PATH) artifact: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive + condition: and(succeededOrFailed(), ne(variables['CLIENT_PATH'], '')) displayName: Publish client archive - - publish: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH).zip + - publish: $(SERVER_PATH) artifact: vscode_server_darwin_$(VSCODE_ARCH)_archive-unsigned + condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], '')) displayName: Publish server archive - - publish: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web.zip + - publish: $(WEB_PATH) artifact: vscode_web_darwin_$(VSCODE_ARCH)_archive-unsigned + condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], '')) displayName: Publish web server archive - - - task: AzureCLI@2 - inputs: - azureSubscription: "vscode-builds-subscription" - scriptType: pscore - scriptLocation: inlineScript - addSpnToEnvironment: true - inlineScript: | - Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId" - Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId" - Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey" diff --git a/build/azure-pipelines/linux/prepare-publish.sh b/build/azure-pipelines/linux/prepare-publish.sh deleted file mode 100755 index 891fa8024ef..00000000000 --- a/build/azure-pipelines/linux/prepare-publish.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env bash -set -e -REPO="$(pwd)" -ROOT="$REPO/.." - -# Publish tarball -PLATFORM_LINUX="linux-$VSCODE_ARCH" -BUILDNAME="VSCode-$PLATFORM_LINUX" -BUILD_VERSION="$(date +%s)" -[ -z "$VSCODE_QUALITY" ] && TARBALL_FILENAME="code-$VSCODE_ARCH-$BUILD_VERSION.tar.gz" || TARBALL_FILENAME="code-$VSCODE_QUALITY-$VSCODE_ARCH-$BUILD_VERSION.tar.gz" -TARBALL_PATH="$ROOT/$TARBALL_FILENAME" - -rm -rf $ROOT/code-*.tar.* -(cd $ROOT && tar -czf $TARBALL_PATH $BUILDNAME) - -# Publish Remote Extension Host -LEGACY_SERVER_BUILD_NAME="vscode-reh-$PLATFORM_LINUX" -SERVER_BUILD_NAME="vscode-server-$PLATFORM_LINUX" -SERVER_TARBALL_FILENAME="vscode-server-$PLATFORM_LINUX.tar.gz" -SERVER_TARBALL_PATH="$ROOT/$SERVER_TARBALL_FILENAME" - -rm -rf $ROOT/vscode-server-*.tar.* -(cd $ROOT && mv $LEGACY_SERVER_BUILD_NAME $SERVER_BUILD_NAME && tar --owner=0 --group=0 -czf $SERVER_TARBALL_PATH $SERVER_BUILD_NAME) - -# Publish Remote Extension Host (Web) -LEGACY_SERVER_BUILD_NAME="vscode-reh-web-$PLATFORM_LINUX" -SERVER_BUILD_NAME="vscode-server-$PLATFORM_LINUX-web" -SERVER_TARBALL_FILENAME="vscode-server-$PLATFORM_LINUX-web.tar.gz" -SERVER_TARBALL_PATH="$ROOT/$SERVER_TARBALL_FILENAME" - -rm -rf $ROOT/vscode-server-*-web.tar.* -(cd $ROOT && mv $LEGACY_SERVER_BUILD_NAME $SERVER_BUILD_NAME && tar --owner=0 --group=0 -czf $SERVER_TARBALL_PATH $SERVER_BUILD_NAME) - -# Publish DEB -case $VSCODE_ARCH in - x64) DEB_ARCH="amd64" ;; - *) DEB_ARCH="$VSCODE_ARCH" ;; -esac - -PLATFORM_DEB="linux-deb-$VSCODE_ARCH" -DEB_FILENAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/)" -DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME" - -# Publish RPM -case $VSCODE_ARCH in - x64) RPM_ARCH="x86_64" ;; - armhf) RPM_ARCH="armv7hl" ;; - arm64) RPM_ARCH="aarch64" ;; - *) RPM_ARCH="$VSCODE_ARCH" ;; -esac - -PLATFORM_RPM="linux-rpm-$VSCODE_ARCH" -RPM_FILENAME="$(ls $REPO/.build/linux/rpm/$RPM_ARCH/ | grep .rpm)" -RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME" - -# Publish Snap -# Pack snap tarball artifact, in order to preserve file perms -mkdir -p $REPO/.build/linux/snap-tarball -SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$VSCODE_ARCH.tar.gz" -rm -rf $SNAP_TARBALL_PATH -(cd .build/linux && tar -czf $SNAP_TARBALL_PATH snap) - -# Export DEB_PATH, RPM_PATH -echo "##vso[task.setvariable variable=DEB_PATH]$DEB_PATH" -echo "##vso[task.setvariable variable=RPM_PATH]$RPM_PATH" -echo "##vso[task.setvariable variable=TARBALL_PATH]$TARBALL_PATH" diff --git a/build/azure-pipelines/linux/product-build-linux-test.yml b/build/azure-pipelines/linux/product-build-linux-test.yml index 75e73b679a8..7532c43c7c9 100644 --- a/build/azure-pipelines/linux/product-build-linux-test.yml +++ b/build/azure-pipelines/linux/product-build-linux-test.yml @@ -122,13 +122,13 @@ steps: INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ ./scripts/test-integration.sh --build --tfs "Integration Tests" env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH) displayName: Run integration tests (Electron) timeoutInMinutes: 20 - script: ./scripts/test-web-integration.sh --browser chromium env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)-web displayName: Run integration tests (Browser, Chromium) timeoutInMinutes: 20 @@ -140,7 +140,7 @@ steps: INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ ./scripts/test-remote-integration.sh env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH) displayName: Run integration tests (Remote) timeoutInMinutes: 20 @@ -180,7 +180,7 @@ steps: - script: yarn smoketest-no-compile --web --tracing --headless --electronArgs="--disable-dev-shm-usage" env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)-web timeoutInMinutes: 20 displayName: Run smoke tests (Browser, Chromium) @@ -188,7 +188,7 @@ steps: set -e yarn gulp compile-extension:vscode-test-resolver APP_PATH=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)" \ yarn smoketest-no-compile --tracing --remote --build "$APP_PATH" timeoutInMinutes: 20 displayName: Run smoke tests (Remote) diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 38522b2d00e..fa307a37628 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -101,7 +101,7 @@ steps: azureSubscriptionEndpoint: "vscode-builds-subscription" azureContainerRegistry: vscodehub.azurecr.io command: "Run an image" - imageName: vscode-linux-build-agent:centos7-devtoolset8-${{ parameters.VSCODE_ARCH }} + imageName: vscode-linux-build-agent:centos7-devtoolset8-$(VSCODE_ARCH) containerCommand: uname condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -159,7 +159,7 @@ steps: PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" ${{ if and(ne(parameters.VSCODE_QUALITY, 'oss'), or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64'))) }}: - VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME: vscodehub.azurecr.io/vscode-linux-build-agent:centos7-devtoolset8-${{ parameters.VSCODE_ARCH }} + VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME: vscodehub.azurecr.io/vscode-linux-build-agent:centos7-devtoolset8-$(VSCODE_ARCH) displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -183,17 +183,37 @@ steps: - template: ../common/install-builtin-extensions.yml - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: yarn gulp vscode-linux-$(VSCODE_ARCH)-min-ci + - script: | + set -e + yarn gulp vscode-linux-$(VSCODE_ARCH)-min-ci + ARCHIVE_PATH=".build/linux/client/code-${{ parameters.VSCODE_QUALITY }}-$(VSCODE_ARCH)-$(date +%s).tar.gz" + mkdir -p $(dirname $ARCHIVE_PATH) + tar -czf $ARCHIVE_PATH -C .. VSCode-linux-$(VSCODE_ARCH) + echo "##vso[task.setvariable variable=CLIENT_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build client - - script: yarn gulp vscode-reh-linux-$(VSCODE_ARCH)-min-ci + - script: | + set -e + yarn gulp vscode-reh-linux-$(VSCODE_ARCH)-min-ci + mv ../vscode-reh-linux-$(VSCODE_ARCH) ../vscode-server-linux-$(VSCODE_ARCH) # TODO@joaomoreno + ARCHIVE_PATH=".build/linux/server/vscode-server-linux-$(VSCODE_ARCH).tar.gz" + mkdir -p $(dirname $ARCHIVE_PATH) + tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-linux-$(VSCODE_ARCH) + echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server - - script: yarn gulp vscode-reh-web-linux-$(VSCODE_ARCH)-min-ci + - script: | + set -e + yarn gulp vscode-reh-web-linux-$(VSCODE_ARCH)-min-ci + mv ../vscode-reh-web-linux-$(VSCODE_ARCH) ../vscode-server-linux-$(VSCODE_ARCH)-web # TODO@joaomoreno + ARCHIVE_PATH=".build/linux/web/vscode-server-linux-$(VSCODE_ARCH)-web.tar.gz" + mkdir -p $(dirname $ARCHIVE_PATH) + tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-linux-$(VSCODE_ARCH)-web + echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server (web) @@ -228,13 +248,25 @@ steps: mv $(Build.ArtifactStagingDirectory)/cli/$APP_NAME $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/$CLI_APP_NAME displayName: Make CLI executable - - script: yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-deb" + - script: | + set -e + yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-deb" + echo "##vso[task.setvariable variable=DEB_PATH]$(ls .build/linux/deb/*/deb/*.deb)" displayName: Build deb package - - script: yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-rpm" + - script: | + set -e + yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-rpm" + echo "##vso[task.setvariable variable=RPM_PATH]$(ls .build/linux/rpm/*/*.rpm)" displayName: Build rpm package - - script: yarn gulp "vscode-linux-$(VSCODE_ARCH)-prepare-snap" + - script: | + set -e + yarn gulp "vscode-linux-$(VSCODE_ARCH)-prepare-snap" + ARCHIVE_PATH=".build/linux/snap-tarball/snap-$(VSCODE_ARCH).tar.gz" + mkdir -p $(dirname $ARCHIVE_PATH) + tar -czf $ARCHIVE_PATH -C .build/linux snap + echo "##vso[task.setvariable variable=SNAP_PATH]$ARCHIVE_PATH" displayName: Prepare snap package - task: UseDotNet@2 @@ -248,8 +280,8 @@ steps: - script: node build/azure-pipelines/common/sign $(Agent.ToolsDirectory)/esrpclient/*/*/net6.0/esrpcli.dll rpm $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) .build/linux/rpm '*.rpm' displayName: Codesign rpm - - script: ./build/azure-pipelines/linux/prepare-publish.sh - displayName: Prepare for Publish + # - script: ./build/azure-pipelines/linux/prepare-publish.sh + # displayName: Prepare for Publish - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 displayName: Generate SBOM (client) @@ -271,28 +303,33 @@ steps: displayName: Publish SBOM (server) artifact: vscode_server_linux_$(VSCODE_ARCH)_sbom - - publish: $(DEB_PATH) - artifact: vscode_client_linux_$(VSCODE_ARCH)_deb-package - displayName: Publish deb package - - - publish: $(RPM_PATH) - artifact: vscode_client_linux_$(VSCODE_ARCH)_rpm-package - displayName: Publish rpm package - - - publish: $(TARBALL_PATH) + - publish: $(CLIENT_PATH) artifact: vscode_client_linux_$(VSCODE_ARCH)_archive-unsigned + condition: and(succeededOrFailed(), ne(variables['CLIENT_PATH'], '')) displayName: Publish client archive - - publish: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH).tar.gz + - publish: $(SERVER_PATH) artifact: vscode_server_linux_$(VSCODE_ARCH)_archive-unsigned + condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], '')) displayName: Publish server archive - - publish: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH)-web.tar.gz + - publish: $(WEB_PATH) artifact: vscode_web_linux_$(VSCODE_ARCH)_archive-unsigned + condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], '')) displayName: Publish web server archive - - task: PublishPipelineArtifact@0 - displayName: "Publish Pipeline Artifact" - inputs: - artifactName: "snap-$(VSCODE_ARCH)" - targetPath: .build/linux/snap-tarball + - publish: $(DEB_PATH) + artifact: vscode_client_linux_$(VSCODE_ARCH)_deb-package + condition: and(succeededOrFailed(), ne(variables['DEB_PATH'], '')) + displayName: Publish deb package + + - publish: $(RPM_PATH) + artifact: vscode_client_linux_$(VSCODE_ARCH)_rpm-package + condition: and(succeededOrFailed(), ne(variables['RPM_PATH'], '')) + displayName: Publish rpm package + + - publish: $(SNAP_PATH) + artifact: snap-$(VSCODE_ARCH) + condition: and(succeededOrFailed(), ne(variables['SNAP_PATH'], '')) + displayName: Publish snap pre-package + diff --git a/build/azure-pipelines/linux/snap-build-linux.yml b/build/azure-pipelines/linux/snap-build-linux.yml index 9002fcff5d7..c028cc58e04 100644 --- a/build/azure-pipelines/linux/snap-build-linux.yml +++ b/build/azure-pipelines/linux/snap-build-linux.yml @@ -27,15 +27,13 @@ steps: sudo apt-get install -y yarn # Define variables - REPO="$(pwd)" - SNAP_ROOT="$REPO/.build/linux/snap/$(VSCODE_ARCH)" + SNAP_ROOT="$(pwd)/.build/linux/snap/$(VSCODE_ARCH)" # Install build dependencies (cd build && yarn) # Unpack snap tarball artifact, in order to preserve file perms - SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$(VSCODE_ARCH).tar.gz" - (cd .build/linux && tar -xzf $SNAP_TARBALL_PATH) + (cd .build/linux && tar -xzf snap-tarball/snap-$(VSCODE_ARCH).tar.gz) # Create snap package BUILD_VERSION="$(date +%s)" diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 556f1f23efa..1b42ebaaaf9 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -87,7 +87,13 @@ steps: - template: ../common/install-builtin-extensions.yml - - script: yarn gulp vscode-web-min-ci + - script: | + set -e + yarn gulp vscode-web-min-ci + ARCHIVE_PATH=".build/web/vscode-web.tar.gz" + mkdir -p $(dirname $ARCHIVE_PATH) + tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-web + echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build @@ -133,20 +139,7 @@ steps: node build/azure-pipelines/upload-nlsmetadata displayName: Upload NLS Metadata - - script: | - set -e - REPO="$(pwd)" - ROOT="$REPO/.." - - WEB_BUILD_NAME="vscode-web" - WEB_TARBALL_FILENAME="vscode-web.tar.gz" - WEB_TARBALL_PATH="$ROOT/$WEB_TARBALL_FILENAME" - - rm -rf $ROOT/vscode-web.tar.* - - cd $ROOT && tar --owner=0 --group=0 -czf $WEB_TARBALL_PATH $WEB_BUILD_NAME - displayName: Prepare for publish - - - publish: $(Agent.BuildDirectory)/vscode-web.tar.gz + - publish: $(WEB_PATH) artifact: vscode_web_linux_standalone_archive-unsigned + condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], '')) displayName: Publish web archive diff --git a/build/azure-pipelines/win32/prepare-publish.ps1 b/build/azure-pipelines/win32/prepare-publish.ps1 deleted file mode 100644 index d2870fe7871..00000000000 --- a/build/azure-pipelines/win32/prepare-publish.ps1 +++ /dev/null @@ -1,40 +0,0 @@ -. build/azure-pipelines/win32/exec.ps1 -$ErrorActionPreference = "Stop" - -$Arch = "$env:VSCODE_ARCH" -$Repo = "$(pwd)" -$Root = "$Repo\.." -$SystemExe = "$Repo\.build\win32-$Arch\system-setup\VSCodeSetup.exe" -$UserExe = "$Repo\.build\win32-$Arch\user-setup\VSCodeSetup.exe" -$Zip = "$Repo\.build\win32-$Arch\archive\VSCode-win32-$Arch.zip" -$LegacyServer = "$Root\vscode-reh-win32-$Arch" -$Server = "$Root\vscode-server-win32-$Arch" -$ServerZip = "$Repo\.build\vscode-server-win32-$Arch.zip" -$LegacyWeb = "$Root\vscode-reh-web-win32-$Arch" -$Web = "$Root\vscode-server-win32-$Arch-web" -$WebZip = "$Repo\.build\vscode-server-win32-$Arch-web.zip" -$Build = "$Root\VSCode-win32-$Arch" - -# Create server archive -if ("$Arch" -ne "arm64") { - exec { xcopy $LegacyServer $Server /H /E /I } - exec { .\node_modules\7zip\7zip-lite\7z.exe a -tzip $ServerZip $Server -r } - exec { xcopy $LegacyWeb $Web /H /E /I } - exec { .\node_modules\7zip\7zip-lite\7z.exe a -tzip $WebZip $Web -r } -} - -# get version -$PackageJson = Get-Content -Raw -Path "$Build\resources\app\package.json" | ConvertFrom-Json -$Version = $PackageJson.version - -$ARCHIVE_NAME = "VSCode-win32-$Arch-$Version.zip" -$SYSTEM_SETUP_NAME = "VSCodeSetup-$Arch-$Version.exe" -$USER_SETUP_NAME = "VSCodeUserSetup-$Arch-$Version.exe" - -# Set variables for upload -Move-Item $Zip "$Repo\.build\win32-$Arch\archive\$ARCHIVE_NAME" -Write-Host "##vso[task.setvariable variable=ARCHIVE_NAME]$ARCHIVE_NAME" -Move-Item $SystemExe "$Repo\.build\win32-$Arch\system-setup\$SYSTEM_SETUP_NAME" -Write-Host "##vso[task.setvariable variable=SYSTEM_SETUP_NAME]$SYSTEM_SETUP_NAME" -Move-Item $UserExe "$Repo\.build\win32-$Arch\user-setup\$USER_SETUP_NAME" -Write-Host "##vso[task.setvariable variable=USER_SETUP_NAME]$USER_SETUP_NAME" diff --git a/build/azure-pipelines/win32/product-build-win32-test.yml b/build/azure-pipelines/win32/product-build-win32-test.yml index 6ad4f2dffbc..ab4240f689c 100644 --- a/build/azure-pipelines/win32/product-build-win32-test.yml +++ b/build/azure-pipelines/win32/product-build-win32-test.yml @@ -89,14 +89,17 @@ steps: $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" $AppProductJson = Get-Content -Raw -Path "$AppRoot\resources\app\product.json" | ConvertFrom-Json $AppNameShort = $AppProductJson.nameShort - exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)"; .\scripts\test-integration.bat --build --tfs "Integration Tests" } + $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe" + $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-server-win32-$(VSCODE_ARCH)" + exec { .\scripts\test-integration.bat --build --tfs "Integration Tests" } displayName: Run integration tests (Electron) timeoutInMinutes: 20 - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" - exec { $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-web-win32-$(VSCODE_ARCH)"; .\scripts\test-web-integration.bat --browser firefox } + $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-server-win32-$(VSCODE_ARCH)-web" + exec { .\scripts\test-web-integration.bat --browser firefox } displayName: Run integration tests (Browser, Firefox) timeoutInMinutes: 20 @@ -106,7 +109,9 @@ steps: $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" $AppProductJson = Get-Content -Raw -Path "$AppRoot\resources\app\product.json" | ConvertFrom-Json $AppNameShort = $AppProductJson.nameShort - exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)"; .\scripts\test-remote-integration.bat } + $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe" + $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-server-win32-$(VSCODE_ARCH)" + exec { .\scripts\test-remote-integration.bat } displayName: Run integration tests (Remote) timeoutInMinutes: 20 @@ -134,7 +139,7 @@ steps: - powershell: yarn smoketest-no-compile --web --tracing --headless env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)\vscode-reh-web-win32-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)\vscode-server-win32-$(VSCODE_ARCH)-web displayName: Run smoke tests (Browser, Chromium) timeoutInMinutes: 20 @@ -144,7 +149,7 @@ steps: - powershell: yarn smoketest-no-compile --tracing --remote --build "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" env: - VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH: $(agent.builddirectory)\vscode-server-win32-$(VSCODE_ARCH) displayName: Run smoke tests (Remote) timeoutInMinutes: 20 diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index ab985554bb7..7bca3e5ef8a 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -154,25 +154,34 @@ steps: . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-min-ci" } + exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-inno-updater" } + echo "##vso[task.setvariable variable=BUILT_CLIENT]true" echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" - displayName: Build + displayName: Build client - - powershell: yarn gulp "vscode-win32-$(VSCODE_ARCH)-inno-updater" + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { yarn gulp "vscode-reh-win32-$(VSCODE_ARCH)-min-ci" } + mv ..\vscode-reh-win32-$(VSCODE_ARCH) ..\vscode-server-win32-$(VSCODE_ARCH) # TODO@joaomoreno + echo "##vso[task.setvariable variable=BUILT_SERVER]true" + echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(agent.builddirectory)/vscode-server-win32-$(VSCODE_ARCH)" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" - displayName: Prepare Setup Package + displayName: Build server + condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" - exec { yarn gulp "vscode-reh-win32-$(VSCODE_ARCH)-min-ci" } exec { yarn gulp "vscode-reh-web-win32-$(VSCODE_ARCH)-min-ci" } - echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(agent.builddirectory)/vscode-reh-win32-$(VSCODE_ARCH)" + mv ..\vscode-reh-web-win32-$(VSCODE_ARCH) ..\vscode-server-win32-$(VSCODE_ARCH)-web # TODO@joaomoreno + echo "##vso[task.setvariable variable=BUILT_WEB]true" env: GITHUB_TOKEN: "$(github-distro-mixin-password)" - displayName: Build Servers + displayName: Build server (web) condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) - ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: @@ -229,8 +238,42 @@ steps: displayName: Codesign context menu appx package - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: yarn gulp "vscode-win32-$(VSCODE_ARCH)-archive" - displayName: Package archive + - powershell: | + $PackageJson = Get-Content -Raw -Path ..\VSCode-win32-$(VSCODE_ARCH)\resources\app\package.json | ConvertFrom-Json + $Version = $PackageJson.version + echo "##vso[task.setvariable variable=VSCODE_VERSION]$Version" + condition: succeededOrFailed() + displayName: Get product version + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $ArchivePath = ".build\win32-$(VSCODE_ARCH)\VSCode-win32-$(VSCODE_ARCH)-$(VSCODE_VERSION).zip" + New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force + exec { 7z.exe a -tzip $ArchivePath -x!CodeSignSummary*.md ..\VSCode-win32-$(VSCODE_ARCH) -r } + echo "##vso[task.setvariable variable=CLIENT_PATH]$ArchivePath" + condition: and(succeededOrFailed(), eq(variables['BUILT_CLIENT'], 'true')) + displayName: Package client + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH).zip" + New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force + exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH) -r } + echo "##vso[task.setvariable variable=SERVER_PATH]$ArchivePath" + condition: and(succeededOrFailed(), eq(variables['BUILT_SERVER'], 'true')) + displayName: Package server + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH)-web.zip" + New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force + exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)-web -r } + echo "##vso[task.setvariable variable=WEB_PATH]$ArchivePath" + condition: and(succeededOrFailed(), eq(variables['BUILT_WEB'], 'true')) + displayName: Package server (web) - powershell: | . build/azure-pipelines/win32/exec.ps1 @@ -239,11 +282,22 @@ steps: $env:ESRPAADUsername = "$(esrp-aad-username)" $env:ESRPAADPassword = "$(esrp-aad-password)" exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-system-setup" --sign } - exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-user-setup" --sign } - displayName: Package setups + $SetupPath = ".build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup-$(VSCODE_ARCH)-$(VSCODE_VERSION).exe" + mv .build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup.exe $SetupPath + echo "##vso[task.setvariable variable=SYSTEM_SETUP_PATH]$SetupPath" + displayName: Build system setup - - powershell: .\build\azure-pipelines\win32\prepare-publish.ps1 - displayName: Publish + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $env:ESRPPKI = "$(ESRP-PKI)" + $env:ESRPAADUsername = "$(esrp-aad-username)" + $env:ESRPAADPassword = "$(esrp-aad-password)" + exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-user-setup" --sign } + $SetupPath = ".build\win32-$(VSCODE_ARCH)\user-setup\VSCodeSetup-$(VSCODE_ARCH)-$(VSCODE_VERSION).exe" + mv .build\win32-$(VSCODE_ARCH)\user-setup\VSCodeSetup.exe $SetupPath + echo "##vso[task.setvariable variable=USER_SETUP_PATH]$SetupPath" + displayName: Build user setup - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 displayName: Generate SBOM (client) @@ -267,24 +321,27 @@ steps: artifact: vscode_server_win32_$(VSCODE_ARCH)_sbom condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) - - publish: $(System.DefaultWorkingDirectory)\.build\win32-$(VSCODE_ARCH)\archive\$(ARCHIVE_NAME) + - publish: $(CLIENT_PATH) artifact: vscode_client_win32_$(VSCODE_ARCH)_archive + condition: and(succeededOrFailed(), ne(variables['CLIENT_PATH'], '')) displayName: Publish archive - - publish: $(System.DefaultWorkingDirectory)\.build\win32-$(VSCODE_ARCH)\system-setup\$(SYSTEM_SETUP_NAME) - artifact: vscode_client_win32_$(VSCODE_ARCH)_setup - displayName: Publish system setup - - - publish: $(System.DefaultWorkingDirectory)\.build\win32-$(VSCODE_ARCH)\user-setup\$(USER_SETUP_NAME) - artifact: vscode_client_win32_$(VSCODE_ARCH)_user-setup - displayName: Publish user setup - - - publish: $(System.DefaultWorkingDirectory)\.build\vscode-server-win32-$(VSCODE_ARCH).zip + - publish: $(SERVER_PATH) artifact: vscode_server_win32_$(VSCODE_ARCH)_archive + condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], ''), ne(variables['VSCODE_ARCH'], 'arm64')) displayName: Publish server archive - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) - - publish: $(System.DefaultWorkingDirectory)\.build\vscode-server-win32-$(VSCODE_ARCH)-web.zip + - publish: $(WEB_PATH) artifact: vscode_web_win32_$(VSCODE_ARCH)_archive + condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], ''), ne(variables['VSCODE_ARCH'], 'arm64')) displayName: Publish web server archive - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) + + - publish: $(SYSTEM_SETUP_PATH) + artifact: vscode_client_win32_$(VSCODE_ARCH)_setup + condition: and(succeededOrFailed(), ne(variables['SYSTEM_SETUP_PATH'], '')) + displayName: Publish system setup + + - publish: $(USER_SETUP_PATH) + artifact: vscode_client_win32_$(VSCODE_ARCH)_user-setup + condition: and(succeededOrFailed(), ne(variables['USER_SETUP_PATH'], '')) + displayName: Publish user setup diff --git a/build/gulpfile.vscode.win32.js b/build/gulpfile.vscode.win32.js index 6e9a6f331ba..2d6f14551b3 100644 --- a/build/gulpfile.vscode.win32.js +++ b/build/gulpfile.vscode.win32.js @@ -10,7 +10,6 @@ const path = require('path'); const fs = require('fs'); const assert = require('assert'); const cp = require('child_process'); -const _7z = require('7zip')['7z']; const util = require('./lib/util'); const task = require('./lib/task'); const pkg = require('../package.json'); @@ -21,8 +20,6 @@ const mkdirp = require('mkdirp'); const repoPath = path.dirname(__dirname); const buildPath = (/** @type {string} */ arch) => path.join(path.dirname(repoPath), `VSCode-win32-${arch}`); -const zipDir = (/** @type {string} */ arch) => path.join(repoPath, '.build', `win32-${arch}`, 'archive'); -const zipPath = (/** @type {string} */ arch) => path.join(zipDir(arch), `VSCode-win32-${arch}.zip`); const setupDir = (/** @type {string} */ arch, /** @type {string} */ target) => path.join(repoPath, '.build', `win32-${arch}`, `${target}-setup`); const issPath = path.join(__dirname, 'win32', 'code.iss'); const innoSetupPath = path.join(path.dirname(path.dirname(require.resolve('innosetup'))), 'bin', 'ISCC.exe'); @@ -142,23 +139,6 @@ defineWin32SetupTasks('ia32', 'user'); defineWin32SetupTasks('x64', 'user'); defineWin32SetupTasks('arm64', 'user'); -/** - * @param {string} arch - */ -function archiveWin32Setup(arch) { - return cb => { - const args = ['a', '-tzip', zipPath(arch), '-x!CodeSignSummary*.md', '.', '-r']; - - cp.spawn(_7z, args, { stdio: 'inherit', cwd: buildPath(arch) }) - .on('error', cb) - .on('exit', () => cb(null)); - }; -} - -gulp.task(task.define('vscode-win32-ia32-archive', task.series(util.rimraf(zipDir('ia32')), archiveWin32Setup('ia32')))); -gulp.task(task.define('vscode-win32-x64-archive', task.series(util.rimraf(zipDir('x64')), archiveWin32Setup('x64')))); -gulp.task(task.define('vscode-win32-arm64-archive', task.series(util.rimraf(zipDir('arm64')), archiveWin32Setup('arm64')))); - /** * @param {string} arch */ diff --git a/package.json b/package.json index 224789cf9ec..7f011f15bbd 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,6 @@ "yazl": "^2.4.3" }, "devDependencies": { - "7zip": "0.0.6", "@playwright/test": "^1.34.3", "@swc/cli": "0.1.62", "@swc/core": "1.3.62", diff --git a/yarn.lock b/yarn.lock index 8ebb45b9118..1318986ce96 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"7zip@0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30" - integrity sha1-nK+xca+CMpSQNTtIFvAzR6oVCjA= - "@ampproject/remapping@^2.1.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" From 8f5865475784bfb666e88732395fa2380a50445c Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 7 Jul 2023 20:47:17 +0200 Subject: [PATCH 070/119] Fixes #184848 (#187306) --- .../inlineCompletions/browser/inlineCompletionContextKeys.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys.ts index bcd18d70301..b027df1b39c 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys.ts @@ -32,8 +32,7 @@ export class InlineCompletionContextKeys extends Disposable { const model = this.model.read(reader); const suggestion = model?.selectedInlineCompletion.read(reader); const ghostText = model?.ghostText.read(reader); - const selectedSuggestItem = model?.selectedSuggestItem.read(reader); - this.inlineCompletionVisible.set(selectedSuggestItem === undefined && ghostText !== undefined && !ghostText.isEmpty()); + this.inlineCompletionVisible.set(ghostText !== undefined && !ghostText.isEmpty()); if (ghostText && suggestion) { this.suppressSuggestions.set(suggestion.inlineCompletion.source.inlineCompletions.suppressSuggestions); From 020b2d5c8e8c2121c2ec484bdeed1fb1d71efbfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 7 Jul 2023 21:02:36 +0200 Subject: [PATCH 071/119] Make sure shift on Windows/Linux only works when hovering (#187308) fixes #187265 --- .../browser/menuEntryActionViewItem.ts | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts index f2e783f211f..54400220a8e 100644 --- a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts +++ b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { $, addDisposableListener, append, asCSSUrl, EventType, IModifierKeyStatus, ModifierKeyEmitter, prepend } from 'vs/base/browser/dom'; +import { $, addDisposableListener, append, asCSSUrl, EventType, ModifierKeyEmitter, prepend } from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ActionViewItem, BaseActionViewItem, SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { DropdownMenuActionViewItem, IDropdownMenuActionViewItemOptions } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem'; @@ -160,8 +160,13 @@ export class MenuEntryActionViewItem extends ActionViewItem { } if (this._menuItemAction.alt) { - const updateAltState = (keyStatus: IModifierKeyStatus) => { - const wantsAltCommand = !!this._commandAction.alt?.enabled && (keyStatus.altKey || ((isWindows || isLinux) && keyStatus.shiftKey)); + let mouseOverOnWindowsOrLinux = false; + + const updateAltState = () => { + const wantsAltCommand = !!this._menuItemAction.alt?.enabled && ( + this._altKey.keyStatus.altKey + || (this._altKey.keyStatus.shiftKey && mouseOverOnWindowsOrLinux) + ); if (wantsAltCommand !== this._wantsAltCommand) { this._wantsAltCommand = wantsAltCommand; @@ -172,7 +177,20 @@ export class MenuEntryActionViewItem extends ActionViewItem { }; this._register(this._altKey.event(updateAltState)); - updateAltState(this._altKey.keyStatus); + + if (isWindows || isLinux) { + this._register(addDisposableListener(container, 'mouseleave', _ => { + mouseOverOnWindowsOrLinux = false; + updateAltState(); + })); + + this._register(addDisposableListener(container, 'mouseenter', _ => { + mouseOverOnWindowsOrLinux = true; + updateAltState(); + })); + } + + updateAltState(); } } From 0e5c0111e868d4b270273f850c36ee334d690468 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 7 Jul 2023 13:18:13 -0700 Subject: [PATCH 072/119] fix task reconnection --- .../tasks/browser/abstractTaskService.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 12fc22bd477..87563e2b78c 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -47,7 +47,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile import { ITerminalGroupService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal'; -import { ConfiguringTask, ContributedTask, CustomTask, ExecutionEngine, InMemoryTask, ITaskEvent, ITaskIdentifier, ITaskSet, JsonSchemaVersion, KeyedTaskIdentifier, RuntimeType, Task, TaskDefinition, TaskEventKind, TaskGroup, TaskRunSource, TaskSettingId, TaskSorter, TaskSourceKind, TasksSchemaProperties, TASK_RUNNING_STATE, USER_TASKS_GROUP_KEY } from 'vs/workbench/contrib/tasks/common/tasks'; +import { ConfiguringTask, ContributedTask, CustomTask, ExecutionEngine, InMemoryTask, ITaskEvent, ITaskIdentifier, ITaskSet, JsonSchemaVersion, KeyedTaskIdentifier, RuntimeType, Task, TASK_RUNNING_STATE, TaskDefinition, TaskEventKind, TaskGroup, TaskRunSource, TaskSettingId, TaskSorter, TaskSourceKind, TasksSchemaProperties, USER_TASKS_GROUP_KEY } from 'vs/workbench/contrib/tasks/common/tasks'; import { CustomExecutionSupportedContext, ICustomizationProperties, IProblemMatcherRunOptions, ITaskFilter, ITaskProvider, ITaskService, IWorkspaceFolderTaskResult, ProcessExecutionSupportedContext, ServerlessWebContext, ShellExecutionSupportedContext, TaskCommandsRegistered, TaskExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService'; import { ITaskExecuteResult, ITaskResolver, ITaskSummary, ITaskSystem, ITaskSystemInfo, ITaskTerminateResponse, TaskError, TaskErrors, TaskExecuteKind } from 'vs/workbench/contrib/tasks/common/taskSystem'; import { getTemplates as getTaskTemplates } from 'vs/workbench/contrib/tasks/common/taskTemplates'; @@ -60,15 +60,18 @@ import { IQuickInputService, IQuickPick, IQuickPickItem, IQuickPickSeparator, Qu import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { TaskDefinitionRegistry } from 'vs/workbench/contrib/tasks/common/taskDefinitionRegistry'; +import { raceTimeout } from 'vs/base/common/async'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { once } from 'vs/base/common/functional'; import { toFormattedString } from 'vs/base/common/jsonFormatter'; import { Schemas } from 'vs/base/common/network'; +import { ThemeIcon } from 'vs/base/common/themables'; import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService'; import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; +import { TerminalExitReason } from 'vs/platform/terminal/common/terminal'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ThemeIcon } from 'vs/base/common/themables'; import { IWorkspaceTrustManagementService, IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/workspaceTrust'; import { VirtualWorkspaceContext } from 'vs/workbench/common/contextkeys'; import { EditorResourceAccessor, SaveReason } from 'vs/workbench/common/editor'; @@ -79,10 +82,7 @@ import { ILifecycleService, ShutdownReason, StartupKind } from 'vs/workbench/ser import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; import { IPathService } from 'vs/workbench/services/path/common/pathService'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; -import { TerminalExitReason } from 'vs/platform/terminal/common/terminal'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { raceTimeout } from 'vs/base/common/async'; const QUICKOPEN_HISTORY_LIMIT_CONFIG = 'task.quickOpen.history'; const PROBLEM_MATCHER_NEVER_CONFIG = 'task.problemMatchers.neverPrompt'; @@ -224,7 +224,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer protected _outputChannel: IOutputChannel; protected readonly _onDidStateChange: Emitter; private _waitForSupportedExecutions: Promise; + private _waitForAllSupportedExecutions: Promise; private _onDidRegisterSupportedExecutions: Emitter = new Emitter(); + private _onDidRegisterAllSupportedExecutions: Emitter = new Emitter(); private _onDidChangeTaskSystemInfo: Emitter = new Emitter(); private _willRestart: boolean = false; public onDidChangeTaskSystemInfo: Event = this._onDidChangeTaskSystemInfo.event; @@ -336,6 +338,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._waitForSupportedExecutions = new Promise(resolve => { once(this._onDidRegisterSupportedExecutions.event)(() => resolve()); }); + this._waitForAllSupportedExecutions = new Promise(resolve => { + once(this._onDidRegisterAllSupportedExecutions.event)(() => resolve()); + }); if (this._terminalService.getReconnectedTerminals('Task')?.length) { this._attemptTaskReconnection(); } else { @@ -2202,6 +2207,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return new Map(); } await this._waitForSupportedExecutions; + if (runSource === TaskRunSource.Reconnect) { + await raceTimeout(this._waitForAllSupportedExecutions, 3000, () => { + console.warn('Timed out waiting for all supported executions for task reconnection'); + }); + } await this._whenTaskSystemReady; if (this._workspaceTasksPromise) { return this._workspaceTasksPromise; From dc37566b2ce107bd28a047d3450bc98ffe624453 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 7 Jul 2023 13:22:30 -0700 Subject: [PATCH 073/119] decrease time --- .../workbench/contrib/tasks/browser/abstractTaskService.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 87563e2b78c..0bb0287040a 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -370,6 +370,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer // update tasks so an incomplete list isn't returned when getWorkspaceTasks is called this._workspaceTasksPromise = undefined; this._onDidRegisterSupportedExecutions.fire(); + if (custom && shell && process) { + this._onDidRegisterAllSupportedExecutions.fire(); + } } private _attemptTaskReconnection(): void { @@ -2208,7 +2211,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } await this._waitForSupportedExecutions; if (runSource === TaskRunSource.Reconnect) { - await raceTimeout(this._waitForAllSupportedExecutions, 3000, () => { + await raceTimeout(this._waitForAllSupportedExecutions, 500, () => { console.warn('Timed out waiting for all supported executions for task reconnection'); }); } From 9a665005673c04e9333fc1276901c4fcc9133784 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 7 Jul 2023 13:40:42 -0700 Subject: [PATCH 074/119] fix #187088 --- .../workbench/contrib/terminal/browser/terminalInstance.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 9ecf7d39c00..6889de6378d 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -59,7 +59,6 @@ import { IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/work import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; import { IViewDescriptorService, IViewsService, ViewContainerLocation } from 'vs/workbench/common/views'; import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; -import { TaskSettingId } from 'vs/workbench/contrib/tasks/common/tasks'; import { IRequestAddInstanceToGroupEvent, ITerminalContribution, ITerminalInstance, TerminalDataTransfers } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalLaunchHelpAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; @@ -677,7 +676,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } get persistentProcessId(): number | undefined { return this._processManager.persistentProcessId; } - get shouldPersist(): boolean { return this._processManager.shouldPersist && !this.shellLaunchConfig.isTransient && (!this.reconnectionProperties || this._configurationService.getValue(TaskSettingId.Reconnection) === true); } + get shouldPersist(): boolean { return this._processManager.shouldPersist && !this.shellLaunchConfig.isTransient && (!this.reconnectionProperties || this._configurationService.getValue('task.reconnection') === true); } public static getXtermConstructor(keybindingService: IKeybindingService, contextKeyService: IContextKeyService) { const keybinding = keybindingService.lookupKeybinding(TerminalCommandId.FocusAccessibleBuffer, contextKeyService); @@ -2098,7 +2097,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // Has not been interacted with !this._processManager.hasWrittenData && // Not a feature terminal or is a reconnecting task terminal (TODO: Need to explain the latter case) - (!this._shellLaunchConfig.isFeatureTerminal || (this.reconnectionProperties && this._configurationService.getValue(TaskSettingId.Reconnection) === true)) && + (!this._shellLaunchConfig.isFeatureTerminal || (this.reconnectionProperties && this._configurationService.getValue('task.reconnection') === true)) && // Not a custom pty !this._shellLaunchConfig.customPtyImplementation && // Not an extension owned terminal From 19a963829361c19924a6a66c30458a7a4334d864 Mon Sep 17 00:00:00 2001 From: Viknet Date: Sat, 8 Jul 2023 01:07:50 +0300 Subject: [PATCH 075/119] resolvers: fallback to one authority when resolving nesting remote authorities fail (#187276) * resolvers: fallback to the old behaviour for nesting remote authorities * style fix * log warning * improve error handling v2 * fix condition --- .../remote/common/remoteAuthorityResolver.ts | 7 ++++- .../api/common/extHostExtensionService.ts | 27 ++++++++++++------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/vs/platform/remote/common/remoteAuthorityResolver.ts b/src/vs/platform/remote/common/remoteAuthorityResolver.ts index c67541b0bc6..e3c17feb4c9 100644 --- a/src/vs/platform/remote/common/remoteAuthorityResolver.ts +++ b/src/vs/platform/remote/common/remoteAuthorityResolver.ts @@ -91,7 +91,8 @@ export enum RemoteAuthorityResolverErrorCode { Unknown = 'Unknown', NotAvailable = 'NotAvailable', TemporarilyNotAvailable = 'TemporarilyNotAvailable', - NoResolverFound = 'NoResolverFound' + NoResolverFound = 'NoResolverFound', + InvalidAuthority = 'InvalidAuthority' } export class RemoteAuthorityResolverError extends ErrorNoTelemetry { @@ -108,6 +109,10 @@ export class RemoteAuthorityResolverError extends ErrorNoTelemetry { return (err instanceof RemoteAuthorityResolverError) && err._code === RemoteAuthorityResolverErrorCode.NoResolverFound; } + public static isInvalidAuthority(err: any): boolean { + return (err instanceof RemoteAuthorityResolverError) && err._code === RemoteAuthorityResolverErrorCode.InvalidAuthority; + } + public static isHandled(err: any): boolean { return (err instanceof RemoteAuthorityResolverError) && err.isHandled; } diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 6e5e3e2c100..82618146832 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -795,7 +795,7 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme private async _activateAndGetResolver(remoteAuthority: string): Promise<{ authorityPrefix: string; resolver: vscode.RemoteAuthorityResolver | undefined }> { const authorityPlusIndex = remoteAuthority.indexOf('+'); if (authorityPlusIndex === -1) { - throw new Error(`Not an authority that can be resolved!`); + throw new RemoteAuthorityResolverError(`Not an authority that can be resolved!`, RemoteAuthorityResolverErrorCode.InvalidAuthority); } const authorityPrefix = remoteAuthority.substr(0, authorityPlusIndex); @@ -809,6 +809,7 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme const sw = StopWatch.create(false); const prefix = () => `[resolveAuthority(${getRemoteAuthorityPrefix(remoteAuthorityChain)},${resolveAttempt})][${sw.elapsed()}ms] `; const logInfo = (msg: string) => this._logService.info(`${prefix()}${msg}`); + const logWarning = (msg: string) => this._logService.warn(`${prefix()}${msg}`); const logError = (msg: string, err: any = undefined) => this._logService.error(`${prefix()}${msg}`, err); const normalizeError = (err: unknown) => { if (err instanceof RemoteAuthorityResolverError) { @@ -824,20 +825,26 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme throw err; }; + const getResolver = async (remoteAuthority: string) => { + logInfo(`activating resolver for ${remoteAuthority}...`); + const { resolver, authorityPrefix } = await this._activateAndGetResolver(remoteAuthority); + if (!resolver) { + logError(`no resolver for ${authorityPrefix}`); + throw new RemoteAuthorityResolverError(`No remote extension installed to resolve ${authorityPrefix}.`, RemoteAuthorityResolverErrorCode.NoResolverFound); + } + return { resolver, authorityPrefix, remoteAuthority }; + }; + const chain = remoteAuthorityChain.split(/@|%40/g).reverse(); logInfo(`activating remote resolvers ${chain.join(' -> ')}`); let resolvers; try { - resolvers = await Promise.all(chain.map(async remoteAuthority => { - logInfo(`activating resolver...`); - const { resolver, authorityPrefix } = await this._activateAndGetResolver(remoteAuthority); - if (!resolver) { - logError(`no resolver`); - throw new RemoteAuthorityResolverError(`No remote extension installed to resolve ${authorityPrefix}.`, RemoteAuthorityResolverErrorCode.NoResolverFound); - } - return { resolver, authorityPrefix, remoteAuthority }; - })); + resolvers = await Promise.all(chain.map(getResolver)).catch(async (e: Error) => { + if (!(e instanceof RemoteAuthorityResolverError) || e._code !== RemoteAuthorityResolverErrorCode.InvalidAuthority) { throw e; } + logWarning(`resolving nested authorities failed: ${e.message}`); + return [await getResolver(remoteAuthorityChain)]; + }); } catch (e) { return normalizeError(e); } From 5150ef0ce77ef5516e55af4b8272f25907b55953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Sat, 8 Jul 2023 00:47:05 +0200 Subject: [PATCH 076/119] disable tests on win32-ia32 (#187313) --- build/azure-pipelines/product-build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 7407cd1825b..d0a5f753431 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -346,9 +346,9 @@ stages: parameters: VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_CIBUILD: ${{ variables.VSCODE_CIBUILD }} - VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} + VSCODE_RUN_UNIT_TESTS: false + VSCODE_RUN_INTEGRATION_TESTS: false + VSCODE_RUN_SMOKE_TESTS: false - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}: - job: WindowsARM64 From afacb63ab5fbefa94b2fb76efe950fd1679f6989 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 10:03:51 +0200 Subject: [PATCH 077/119] Bump tough-cookie from 4.1.2 to 4.1.3 in /extensions/notebook-renderers (#187410) Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 4.1.2 to 4.1.3. - [Release notes](https://github.com/salesforce/tough-cookie/releases) - [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md) - [Commits](https://github.com/salesforce/tough-cookie/compare/v4.1.2...v4.1.3) --- updated-dependencies: - dependency-name: tough-cookie dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- extensions/notebook-renderers/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/notebook-renderers/yarn.lock b/extensions/notebook-renderers/yarn.lock index ba3ff6b48d9..fac17bd8f60 100644 --- a/extensions/notebook-renderers/yarn.lock +++ b/extensions/notebook-renderers/yarn.lock @@ -334,9 +334,9 @@ symbol-tree@^3.2.4: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== tough-cookie@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" From dccc793f79fa850393e7a0668788340a1a6813d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 10:04:17 +0200 Subject: [PATCH 078/119] Bump tough-cookie from 4.0.0 to 4.1.3 (#187385) Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 4.0.0 to 4.1.3. - [Release notes](https://github.com/salesforce/tough-cookie/releases) - [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md) - [Commits](https://github.com/salesforce/tough-cookie/compare/v4.0.0...v4.1.3) --- updated-dependencies: - dependency-name: tough-cookie dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1318986ce96..13650bd8310 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8319,6 +8319,11 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + queue-tick@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" @@ -8588,6 +8593,11 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + resolve-alpn@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" @@ -9851,13 +9861,14 @@ token-types@^5.0.0-alpha.2: ieee754 "^1.2.1" tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" - universalify "^0.1.2" + universalify "^0.2.0" + url-parse "^1.5.3" tr46@~0.0.3: version "0.0.3" @@ -10122,11 +10133,16 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== -universalify@^0.1.0, universalify@^0.1.2: +universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + unquote@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" @@ -10165,6 +10181,14 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" From 8c8e8600b6ec20279e2fa977ff242d0238f486c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 10:05:01 +0200 Subject: [PATCH 079/119] Bump semver from 5.5.1 to 7.5.2 in /extensions/typescript-language-features (#185968) Bump semver in /extensions/typescript-language-features Bumps [semver](https://github.com/npm/node-semver) from 5.5.1 to 7.5.2. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v5.5.1...v7.5.2) --- updated-dependencies: - dependency-name: semver dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../typescript-language-features/package.json | 2 +- .../typescript-language-features/yarn.lock | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index b9b63d61495..c7cf530dbb9 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -35,7 +35,7 @@ "dependencies": { "@vscode/extension-telemetry": "0.7.5", "jsonc-parser": "^3.2.0", - "semver": "5.5.1", + "semver": "7.5.2", "vscode-tas-client": "^0.1.63", "@vscode/sync-api-client": "^0.7.2", "@vscode/sync-api-common": "^0.7.2", diff --git a/extensions/typescript-language-features/yarn.lock b/extensions/typescript-language-features/yarn.lock index a86d12d0e3f..d3d03733ceb 100644 --- a/extensions/typescript-language-features/yarn.lock +++ b/extensions/typescript-language-features/yarn.lock @@ -348,6 +348,13 @@ jsonc-parser@^3.2.0: resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -365,10 +372,12 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -semver@5.5.1: - version "5.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" - integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw== +semver@7.5.2: + version "7.5.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" + integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ== + dependencies: + lru-cache "^6.0.0" semver@^5.3.0, semver@^5.4.1: version "5.7.1" @@ -413,3 +422,8 @@ vscode-uri@3.0.3, vscode-uri@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.3.tgz#a95c1ce2e6f41b7549f86279d19f47951e4f4d84" integrity sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== From 00db67e44079d78850922701c0e63e3053d48640 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 10 Jul 2023 11:07:58 +0200 Subject: [PATCH 080/119] Skip failing integration tests (#187424) Part of #187245 --- extensions/emmet/src/test/abbreviationAction.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/emmet/src/test/abbreviationAction.test.ts b/extensions/emmet/src/test/abbreviationAction.test.ts index 17ccacfc94a..beb3bfa1ef3 100644 --- a/extensions/emmet/src/test/abbreviationAction.test.ts +++ b/extensions/emmet/src/test/abbreviationAction.test.ts @@ -410,7 +410,7 @@ suite('Tests for Expand Abbreviations (HTML)', () => { // }); // }); - test('No expanding when html is excluded in the settings in completion list', async () => { + test.skip('No expanding when html is excluded in the settings in completion list', async () => { const oldConfig = workspace.getConfiguration('emmet').inspect('excludeLanguages')?.globalValue; await workspace.getConfiguration('emmet').update('excludeLanguages', ['html'], ConfigurationTarget.Global); await testHtmlCompletionProvider(new Selection(9, 6, 9, 6), '', '', true); @@ -469,7 +469,7 @@ suite('Tests for jsx, xml and xsl', () => { }); }); - test('Expand abbreviation with no self closing tags for html', () => { + test.skip('Expand abbreviation with no self closing tags for html', () => { return withRandomFileEditor('img', 'html', async (editor, _doc) => { editor.selection = new Selection(0, 6, 0, 6); await expandEmmetAbbreviation({ language: 'html' }); From 71935eff90daf4b5d7423b01fc48b2f019150b41 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 10 Jul 2023 11:11:34 +0200 Subject: [PATCH 081/119] Fixes https://github.com/microsoft/monaco-editor/issues/4021 (#187318) --- .../browser/controller/textAreaHandler.ts | 2 + src/vs/editor/common/config/editorOptions.ts | 9 + .../common/standalone/standaloneEnums.ts | 281 ++++++++--------- src/vs/monaco.d.ts | 286 +++++++++--------- 4 files changed, 298 insertions(+), 280 deletions(-) diff --git a/src/vs/editor/browser/controller/textAreaHandler.ts b/src/vs/editor/browser/controller/textAreaHandler.ts index 0d5c3317051..bc95af4fe9e 100644 --- a/src/vs/editor/browser/controller/textAreaHandler.ts +++ b/src/vs/editor/browser/controller/textAreaHandler.ts @@ -177,6 +177,7 @@ export class TextAreaHandler extends ViewPart { this.textArea.setAttribute('autocomplete', 'off'); this.textArea.setAttribute('spellcheck', 'false'); this.textArea.setAttribute('aria-label', this._getAriaLabel(options)); + this.textArea.setAttribute('aria-required', options.get(EditorOption.ariaRequired) ? 'true' : 'false'); this.textArea.setAttribute('tabindex', String(options.get(EditorOption.tabIndex))); this.textArea.setAttribute('role', 'textbox'); this.textArea.setAttribute('aria-roledescription', nls.localize('editor', "editor")); @@ -601,6 +602,7 @@ export class TextAreaHandler extends ViewPart { const { tabSize } = this._context.viewModel.model.getOptions(); this.textArea.domNode.style.tabSize = `${tabSize * this._fontInfo.spaceWidth}px`; this.textArea.setAttribute('aria-label', this._getAriaLabel(options)); + this.textArea.setAttribute('aria-required', options.get(EditorOption.ariaRequired) ? 'true' : 'false'); this.textArea.setAttribute('tabindex', String(options.get(EditorOption.tabIndex))); if (e.hasChanged(EditorOption.domReadOnly) || e.hasChanged(EditorOption.readOnly)) { diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index b2f09749f2f..96dbb05c275 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -58,6 +58,11 @@ export interface IEditorOptions { * The aria label for the editor's textarea (when it is focused). */ ariaLabel?: string; + + /** + * Whether the aria-required attribute should be set on the editors textarea. + */ + ariaRequired?: boolean; /** * Control whether a screen reader announces inline suggestion content immediately. */ @@ -4972,6 +4977,7 @@ export const enum EditorOption { accessibilitySupport, accessibilityPageSize, ariaLabel, + ariaRequired, autoClosingBrackets, screenReaderAnnounceInlineSuggestion, autoClosingDelete, @@ -5142,6 +5148,9 @@ export const EditorOptions = { ariaLabel: register(new EditorStringOption( EditorOption.ariaLabel, 'ariaLabel', nls.localize('editorViewAccessibleLabel', "Editor content") )), + ariaRequired: register(new EditorBooleanOption( + EditorOption.ariaRequired, 'ariaRequired', false, undefined + )), screenReaderAnnounceInlineSuggestion: register(new EditorBooleanOption( EditorOption.screenReaderAnnounceInlineSuggestion, 'screenReaderAnnounceInlineSuggestion', true, { diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index d48dc8f7aa1..d92f0c1272e 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -178,146 +178,147 @@ export enum EditorOption { accessibilitySupport = 2, accessibilityPageSize = 3, ariaLabel = 4, - autoClosingBrackets = 5, - screenReaderAnnounceInlineSuggestion = 6, - autoClosingDelete = 7, - autoClosingOvertype = 8, - autoClosingQuotes = 9, - autoIndent = 10, - automaticLayout = 11, - autoSurround = 12, - bracketPairColorization = 13, - guides = 14, - codeLens = 15, - codeLensFontFamily = 16, - codeLensFontSize = 17, - colorDecorators = 18, - colorDecoratorsLimit = 19, - columnSelection = 20, - comments = 21, - contextmenu = 22, - copyWithSyntaxHighlighting = 23, - cursorBlinking = 24, - cursorSmoothCaretAnimation = 25, - cursorStyle = 26, - cursorSurroundingLines = 27, - cursorSurroundingLinesStyle = 28, - cursorWidth = 29, - disableLayerHinting = 30, - disableMonospaceOptimizations = 31, - domReadOnly = 32, - dragAndDrop = 33, - dropIntoEditor = 34, - emptySelectionClipboard = 35, - experimentalWhitespaceRendering = 36, - extraEditorClassName = 37, - fastScrollSensitivity = 38, - find = 39, - fixedOverflowWidgets = 40, - folding = 41, - foldingStrategy = 42, - foldingHighlight = 43, - foldingImportsByDefault = 44, - foldingMaximumRegions = 45, - unfoldOnClickAfterEndOfLine = 46, - fontFamily = 47, - fontInfo = 48, - fontLigatures = 49, - fontSize = 50, - fontWeight = 51, - fontVariations = 52, - formatOnPaste = 53, - formatOnType = 54, - glyphMargin = 55, - gotoLocation = 56, - hideCursorInOverviewRuler = 57, - hover = 58, - inDiffEditor = 59, - inlineSuggest = 60, - letterSpacing = 61, - lightbulb = 62, - lineDecorationsWidth = 63, - lineHeight = 64, - lineNumbers = 65, - lineNumbersMinChars = 66, - linkedEditing = 67, - links = 68, - matchBrackets = 69, - minimap = 70, - mouseStyle = 71, - mouseWheelScrollSensitivity = 72, - mouseWheelZoom = 73, - multiCursorMergeOverlapping = 74, - multiCursorModifier = 75, - multiCursorPaste = 76, - multiCursorLimit = 77, - occurrencesHighlight = 78, - overviewRulerBorder = 79, - overviewRulerLanes = 80, - padding = 81, - pasteAs = 82, - parameterHints = 83, - peekWidgetDefaultFocus = 84, - definitionLinkOpensInPeek = 85, - quickSuggestions = 86, - quickSuggestionsDelay = 87, - readOnly = 88, - readOnlyMessage = 89, - renameOnType = 90, - renderControlCharacters = 91, - renderFinalNewline = 92, - renderLineHighlight = 93, - renderLineHighlightOnlyWhenFocus = 94, - renderValidationDecorations = 95, - renderWhitespace = 96, - revealHorizontalRightPadding = 97, - roundedSelection = 98, - rulers = 99, - scrollbar = 100, - scrollBeyondLastColumn = 101, - scrollBeyondLastLine = 102, - scrollPredominantAxis = 103, - selectionClipboard = 104, - selectionHighlight = 105, - selectOnLineNumbers = 106, - showFoldingControls = 107, - showUnused = 108, - snippetSuggestions = 109, - smartSelect = 110, - smoothScrolling = 111, - stickyScroll = 112, - stickyTabStops = 113, - stopRenderingLineAfter = 114, - suggest = 115, - suggestFontSize = 116, - suggestLineHeight = 117, - suggestOnTriggerCharacters = 118, - suggestSelection = 119, - tabCompletion = 120, - tabIndex = 121, - unicodeHighlighting = 122, - unusualLineTerminators = 123, - useShadowDOM = 124, - useTabStops = 125, - wordBreak = 126, - wordSeparators = 127, - wordWrap = 128, - wordWrapBreakAfterCharacters = 129, - wordWrapBreakBeforeCharacters = 130, - wordWrapColumn = 131, - wordWrapOverride1 = 132, - wordWrapOverride2 = 133, - wrappingIndent = 134, - wrappingStrategy = 135, - showDeprecated = 136, - inlayHints = 137, - editorClassName = 138, - pixelRatio = 139, - tabFocusMode = 140, - layoutInfo = 141, - wrappingInfo = 142, - defaultColorDecorators = 143, - colorDecoratorsActivatedOn = 144 + ariaRequired = 5, + autoClosingBrackets = 6, + screenReaderAnnounceInlineSuggestion = 7, + autoClosingDelete = 8, + autoClosingOvertype = 9, + autoClosingQuotes = 10, + autoIndent = 11, + automaticLayout = 12, + autoSurround = 13, + bracketPairColorization = 14, + guides = 15, + codeLens = 16, + codeLensFontFamily = 17, + codeLensFontSize = 18, + colorDecorators = 19, + colorDecoratorsLimit = 20, + columnSelection = 21, + comments = 22, + contextmenu = 23, + copyWithSyntaxHighlighting = 24, + cursorBlinking = 25, + cursorSmoothCaretAnimation = 26, + cursorStyle = 27, + cursorSurroundingLines = 28, + cursorSurroundingLinesStyle = 29, + cursorWidth = 30, + disableLayerHinting = 31, + disableMonospaceOptimizations = 32, + domReadOnly = 33, + dragAndDrop = 34, + dropIntoEditor = 35, + emptySelectionClipboard = 36, + experimentalWhitespaceRendering = 37, + extraEditorClassName = 38, + fastScrollSensitivity = 39, + find = 40, + fixedOverflowWidgets = 41, + folding = 42, + foldingStrategy = 43, + foldingHighlight = 44, + foldingImportsByDefault = 45, + foldingMaximumRegions = 46, + unfoldOnClickAfterEndOfLine = 47, + fontFamily = 48, + fontInfo = 49, + fontLigatures = 50, + fontSize = 51, + fontWeight = 52, + fontVariations = 53, + formatOnPaste = 54, + formatOnType = 55, + glyphMargin = 56, + gotoLocation = 57, + hideCursorInOverviewRuler = 58, + hover = 59, + inDiffEditor = 60, + inlineSuggest = 61, + letterSpacing = 62, + lightbulb = 63, + lineDecorationsWidth = 64, + lineHeight = 65, + lineNumbers = 66, + lineNumbersMinChars = 67, + linkedEditing = 68, + links = 69, + matchBrackets = 70, + minimap = 71, + mouseStyle = 72, + mouseWheelScrollSensitivity = 73, + mouseWheelZoom = 74, + multiCursorMergeOverlapping = 75, + multiCursorModifier = 76, + multiCursorPaste = 77, + multiCursorLimit = 78, + occurrencesHighlight = 79, + overviewRulerBorder = 80, + overviewRulerLanes = 81, + padding = 82, + pasteAs = 83, + parameterHints = 84, + peekWidgetDefaultFocus = 85, + definitionLinkOpensInPeek = 86, + quickSuggestions = 87, + quickSuggestionsDelay = 88, + readOnly = 89, + readOnlyMessage = 90, + renameOnType = 91, + renderControlCharacters = 92, + renderFinalNewline = 93, + renderLineHighlight = 94, + renderLineHighlightOnlyWhenFocus = 95, + renderValidationDecorations = 96, + renderWhitespace = 97, + revealHorizontalRightPadding = 98, + roundedSelection = 99, + rulers = 100, + scrollbar = 101, + scrollBeyondLastColumn = 102, + scrollBeyondLastLine = 103, + scrollPredominantAxis = 104, + selectionClipboard = 105, + selectionHighlight = 106, + selectOnLineNumbers = 107, + showFoldingControls = 108, + showUnused = 109, + snippetSuggestions = 110, + smartSelect = 111, + smoothScrolling = 112, + stickyScroll = 113, + stickyTabStops = 114, + stopRenderingLineAfter = 115, + suggest = 116, + suggestFontSize = 117, + suggestLineHeight = 118, + suggestOnTriggerCharacters = 119, + suggestSelection = 120, + tabCompletion = 121, + tabIndex = 122, + unicodeHighlighting = 123, + unusualLineTerminators = 124, + useShadowDOM = 125, + useTabStops = 126, + wordBreak = 127, + wordSeparators = 128, + wordWrap = 129, + wordWrapBreakAfterCharacters = 130, + wordWrapBreakBeforeCharacters = 131, + wordWrapColumn = 132, + wordWrapOverride1 = 133, + wordWrapOverride2 = 134, + wrappingIndent = 135, + wrappingStrategy = 136, + showDeprecated = 137, + inlayHints = 138, + editorClassName = 139, + pixelRatio = 140, + tabFocusMode = 141, + layoutInfo = 142, + wrappingInfo = 143, + defaultColorDecorators = 144, + colorDecoratorsActivatedOn = 145 } /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index d59db506ee1..9e2a863d592 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3221,6 +3221,10 @@ declare namespace monaco.editor { * The aria label for the editor's textarea (when it is focused). */ ariaLabel?: string; + /** + * Whether the aria-required attribute should be set on the editors textarea. + */ + ariaRequired?: boolean; /** * Control whether a screen reader announces inline suggestion content immediately. */ @@ -4861,146 +4865,147 @@ declare namespace monaco.editor { accessibilitySupport = 2, accessibilityPageSize = 3, ariaLabel = 4, - autoClosingBrackets = 5, - screenReaderAnnounceInlineSuggestion = 6, - autoClosingDelete = 7, - autoClosingOvertype = 8, - autoClosingQuotes = 9, - autoIndent = 10, - automaticLayout = 11, - autoSurround = 12, - bracketPairColorization = 13, - guides = 14, - codeLens = 15, - codeLensFontFamily = 16, - codeLensFontSize = 17, - colorDecorators = 18, - colorDecoratorsLimit = 19, - columnSelection = 20, - comments = 21, - contextmenu = 22, - copyWithSyntaxHighlighting = 23, - cursorBlinking = 24, - cursorSmoothCaretAnimation = 25, - cursorStyle = 26, - cursorSurroundingLines = 27, - cursorSurroundingLinesStyle = 28, - cursorWidth = 29, - disableLayerHinting = 30, - disableMonospaceOptimizations = 31, - domReadOnly = 32, - dragAndDrop = 33, - dropIntoEditor = 34, - emptySelectionClipboard = 35, - experimentalWhitespaceRendering = 36, - extraEditorClassName = 37, - fastScrollSensitivity = 38, - find = 39, - fixedOverflowWidgets = 40, - folding = 41, - foldingStrategy = 42, - foldingHighlight = 43, - foldingImportsByDefault = 44, - foldingMaximumRegions = 45, - unfoldOnClickAfterEndOfLine = 46, - fontFamily = 47, - fontInfo = 48, - fontLigatures = 49, - fontSize = 50, - fontWeight = 51, - fontVariations = 52, - formatOnPaste = 53, - formatOnType = 54, - glyphMargin = 55, - gotoLocation = 56, - hideCursorInOverviewRuler = 57, - hover = 58, - inDiffEditor = 59, - inlineSuggest = 60, - letterSpacing = 61, - lightbulb = 62, - lineDecorationsWidth = 63, - lineHeight = 64, - lineNumbers = 65, - lineNumbersMinChars = 66, - linkedEditing = 67, - links = 68, - matchBrackets = 69, - minimap = 70, - mouseStyle = 71, - mouseWheelScrollSensitivity = 72, - mouseWheelZoom = 73, - multiCursorMergeOverlapping = 74, - multiCursorModifier = 75, - multiCursorPaste = 76, - multiCursorLimit = 77, - occurrencesHighlight = 78, - overviewRulerBorder = 79, - overviewRulerLanes = 80, - padding = 81, - pasteAs = 82, - parameterHints = 83, - peekWidgetDefaultFocus = 84, - definitionLinkOpensInPeek = 85, - quickSuggestions = 86, - quickSuggestionsDelay = 87, - readOnly = 88, - readOnlyMessage = 89, - renameOnType = 90, - renderControlCharacters = 91, - renderFinalNewline = 92, - renderLineHighlight = 93, - renderLineHighlightOnlyWhenFocus = 94, - renderValidationDecorations = 95, - renderWhitespace = 96, - revealHorizontalRightPadding = 97, - roundedSelection = 98, - rulers = 99, - scrollbar = 100, - scrollBeyondLastColumn = 101, - scrollBeyondLastLine = 102, - scrollPredominantAxis = 103, - selectionClipboard = 104, - selectionHighlight = 105, - selectOnLineNumbers = 106, - showFoldingControls = 107, - showUnused = 108, - snippetSuggestions = 109, - smartSelect = 110, - smoothScrolling = 111, - stickyScroll = 112, - stickyTabStops = 113, - stopRenderingLineAfter = 114, - suggest = 115, - suggestFontSize = 116, - suggestLineHeight = 117, - suggestOnTriggerCharacters = 118, - suggestSelection = 119, - tabCompletion = 120, - tabIndex = 121, - unicodeHighlighting = 122, - unusualLineTerminators = 123, - useShadowDOM = 124, - useTabStops = 125, - wordBreak = 126, - wordSeparators = 127, - wordWrap = 128, - wordWrapBreakAfterCharacters = 129, - wordWrapBreakBeforeCharacters = 130, - wordWrapColumn = 131, - wordWrapOverride1 = 132, - wordWrapOverride2 = 133, - wrappingIndent = 134, - wrappingStrategy = 135, - showDeprecated = 136, - inlayHints = 137, - editorClassName = 138, - pixelRatio = 139, - tabFocusMode = 140, - layoutInfo = 141, - wrappingInfo = 142, - defaultColorDecorators = 143, - colorDecoratorsActivatedOn = 144 + ariaRequired = 5, + autoClosingBrackets = 6, + screenReaderAnnounceInlineSuggestion = 7, + autoClosingDelete = 8, + autoClosingOvertype = 9, + autoClosingQuotes = 10, + autoIndent = 11, + automaticLayout = 12, + autoSurround = 13, + bracketPairColorization = 14, + guides = 15, + codeLens = 16, + codeLensFontFamily = 17, + codeLensFontSize = 18, + colorDecorators = 19, + colorDecoratorsLimit = 20, + columnSelection = 21, + comments = 22, + contextmenu = 23, + copyWithSyntaxHighlighting = 24, + cursorBlinking = 25, + cursorSmoothCaretAnimation = 26, + cursorStyle = 27, + cursorSurroundingLines = 28, + cursorSurroundingLinesStyle = 29, + cursorWidth = 30, + disableLayerHinting = 31, + disableMonospaceOptimizations = 32, + domReadOnly = 33, + dragAndDrop = 34, + dropIntoEditor = 35, + emptySelectionClipboard = 36, + experimentalWhitespaceRendering = 37, + extraEditorClassName = 38, + fastScrollSensitivity = 39, + find = 40, + fixedOverflowWidgets = 41, + folding = 42, + foldingStrategy = 43, + foldingHighlight = 44, + foldingImportsByDefault = 45, + foldingMaximumRegions = 46, + unfoldOnClickAfterEndOfLine = 47, + fontFamily = 48, + fontInfo = 49, + fontLigatures = 50, + fontSize = 51, + fontWeight = 52, + fontVariations = 53, + formatOnPaste = 54, + formatOnType = 55, + glyphMargin = 56, + gotoLocation = 57, + hideCursorInOverviewRuler = 58, + hover = 59, + inDiffEditor = 60, + inlineSuggest = 61, + letterSpacing = 62, + lightbulb = 63, + lineDecorationsWidth = 64, + lineHeight = 65, + lineNumbers = 66, + lineNumbersMinChars = 67, + linkedEditing = 68, + links = 69, + matchBrackets = 70, + minimap = 71, + mouseStyle = 72, + mouseWheelScrollSensitivity = 73, + mouseWheelZoom = 74, + multiCursorMergeOverlapping = 75, + multiCursorModifier = 76, + multiCursorPaste = 77, + multiCursorLimit = 78, + occurrencesHighlight = 79, + overviewRulerBorder = 80, + overviewRulerLanes = 81, + padding = 82, + pasteAs = 83, + parameterHints = 84, + peekWidgetDefaultFocus = 85, + definitionLinkOpensInPeek = 86, + quickSuggestions = 87, + quickSuggestionsDelay = 88, + readOnly = 89, + readOnlyMessage = 90, + renameOnType = 91, + renderControlCharacters = 92, + renderFinalNewline = 93, + renderLineHighlight = 94, + renderLineHighlightOnlyWhenFocus = 95, + renderValidationDecorations = 96, + renderWhitespace = 97, + revealHorizontalRightPadding = 98, + roundedSelection = 99, + rulers = 100, + scrollbar = 101, + scrollBeyondLastColumn = 102, + scrollBeyondLastLine = 103, + scrollPredominantAxis = 104, + selectionClipboard = 105, + selectionHighlight = 106, + selectOnLineNumbers = 107, + showFoldingControls = 108, + showUnused = 109, + snippetSuggestions = 110, + smartSelect = 111, + smoothScrolling = 112, + stickyScroll = 113, + stickyTabStops = 114, + stopRenderingLineAfter = 115, + suggest = 116, + suggestFontSize = 117, + suggestLineHeight = 118, + suggestOnTriggerCharacters = 119, + suggestSelection = 120, + tabCompletion = 121, + tabIndex = 122, + unicodeHighlighting = 123, + unusualLineTerminators = 124, + useShadowDOM = 125, + useTabStops = 126, + wordBreak = 127, + wordSeparators = 128, + wordWrap = 129, + wordWrapBreakAfterCharacters = 130, + wordWrapBreakBeforeCharacters = 131, + wordWrapColumn = 132, + wordWrapOverride1 = 133, + wordWrapOverride2 = 134, + wrappingIndent = 135, + wrappingStrategy = 136, + showDeprecated = 137, + inlayHints = 138, + editorClassName = 139, + pixelRatio = 140, + tabFocusMode = 141, + layoutInfo = 142, + wrappingInfo = 143, + defaultColorDecorators = 144, + colorDecoratorsActivatedOn = 145 } export const EditorOptions: { @@ -5009,6 +5014,7 @@ declare namespace monaco.editor { accessibilitySupport: IEditorOption; accessibilityPageSize: IEditorOption; ariaLabel: IEditorOption; + ariaRequired: IEditorOption; screenReaderAnnounceInlineSuggestion: IEditorOption; autoClosingBrackets: IEditorOption; autoClosingDelete: IEditorOption; From 293e46b36015307d159b3ea38ec8dbe534be9c76 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 10 Jul 2023 11:24:03 +0200 Subject: [PATCH 082/119] Fixes #187153 (#187289) --- .../diffEditorWidget2/diffEditorViewModel.ts | 102 ++++++++++-------- 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index bcb4c13371d..f9d77296cea 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -59,6 +59,50 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo const contentChangedSignal = observableSignal('contentChangedSignal'); const debouncer = this._register(new RunOnceScheduler(() => contentChangedSignal.trigger(undefined), 200)); + const updateUnchangedRegions = (result: IDocumentDiff, tx: ITransaction) => { + const newUnchangedRegions = UnchangedRegion.fromDiffs(result.changes, model.original.getLineCount(), model.modified.getLineCount()); + + // Transfer state from cur state + const lastUnchangedRegions = this._unchangedRegions.get(); + const lastUnchangedRegionsOrigRanges = lastUnchangedRegions.originalDecorationIds + .map(id => model.original.getDecorationRange(id)) + .filter(r => !!r) + .map(r => LineRange.fromRange(r!)); + const lastUnchangedRegionsModRanges = lastUnchangedRegions.modifiedDecorationIds + .map(id => model.modified.getDecorationRange(id)) + .filter(r => !!r) + .map(r => LineRange.fromRange(r!)); + + const originalDecorationIds = model.original.deltaDecorations( + lastUnchangedRegions.originalDecorationIds, + newUnchangedRegions.map(r => ({ range: r.originalRange.toInclusiveRange()!, options: { description: 'unchanged' } })) + ); + const modifiedDecorationIds = model.modified.deltaDecorations( + lastUnchangedRegions.modifiedDecorationIds, + newUnchangedRegions.map(r => ({ range: r.modifiedRange.toInclusiveRange()!, options: { description: 'unchanged' } })) + ); + + + for (const r of newUnchangedRegions) { + for (let i = 0; i < lastUnchangedRegions.regions.length; i++) { + if (r.originalRange.intersectsStrict(lastUnchangedRegionsOrigRanges[i]) + && r.modifiedRange.intersectsStrict(lastUnchangedRegionsModRanges[i])) { + r.setHiddenModifiedRange(lastUnchangedRegions.regions[i].getHiddenModifiedRange(undefined), tx); + break; + } + } + } + this._unchangedRegions.set( + { + regions: newUnchangedRegions, + originalDecorationIds, + modifiedDecorationIds + }, + tx + ); + }; + + this._register(model.modified.onDidChangeContent((e) => { const diff = this._diff.get(); if (!diff) { @@ -69,9 +113,12 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo const result = applyModifiedEdits(this._lastDiff!, textEdits, model.original, model.modified); if (result) { this._lastDiff = result; - this._diff.set(DiffState.fromDiffResult(this._lastDiff), undefined); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff.moves.find(m => m.lineRangeMapping.modifiedRange.intersect(currentSyncedMovedText.lineRangeMapping.modifiedRange)) : undefined, undefined); + transaction(tx => { + this._diff.set(DiffState.fromDiffResult(this._lastDiff!), tx); + updateUnchangedRegions(result, tx); + const currentSyncedMovedText = this.syncedMovedTexts.get(); + this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modifiedRange.intersect(currentSyncedMovedText.lineRangeMapping.modifiedRange)) : undefined, tx); + }); } debouncer.schedule(); @@ -86,9 +133,12 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo const result = applyOriginalEdits(this._lastDiff!, textEdits, model.original, model.modified); if (result) { this._lastDiff = result; - this._diff.set(DiffState.fromDiffResult(this._lastDiff), undefined); - const currentSyncedMovedText = this.syncedMovedTexts.get(); - this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff.moves.find(m => m.lineRangeMapping.modifiedRange.intersect(currentSyncedMovedText.lineRangeMapping.modifiedRange)) : undefined, undefined); + transaction(tx => { + this._diff.set(DiffState.fromDiffResult(this._lastDiff!), tx); + updateUnchangedRegions(result, tx); + const currentSyncedMovedText = this.syncedMovedTexts.get(); + this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff!.moves.find(m => m.lineRangeMapping.modifiedRange.intersect(currentSyncedMovedText.lineRangeMapping.modifiedRange)) : undefined, tx); + }); } debouncer.schedule(); @@ -124,38 +174,9 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo result = applyOriginalEdits(result, originalTextEditInfos, model.original, model.modified) ?? result; result = applyModifiedEdits(result, modifiedTextEditInfos, model.original, model.modified) ?? result; - const newUnchangedRegions = UnchangedRegion.fromDiffs(result.changes, model.original.getLineCount(), model.modified.getLineCount()); - - // Transfer state from cur state - const lastUnchangedRegions = this._unchangedRegions.get(); - const lastUnchangedRegionsOrigRanges = lastUnchangedRegions.originalDecorationIds - .map(id => model.original.getDecorationRange(id)) - .filter(r => !!r) - .map(r => LineRange.fromRange(r!)); - const lastUnchangedRegionsModRanges = lastUnchangedRegions.modifiedDecorationIds - .map(id => model.modified.getDecorationRange(id)) - .filter(r => !!r) - .map(r => LineRange.fromRange(r!)); - - const originalDecorationIds = model.original.deltaDecorations( - lastUnchangedRegions.originalDecorationIds, - newUnchangedRegions.map(r => ({ range: r.originalRange.toInclusiveRange()!, options: { description: 'unchanged' } })) - ); - const modifiedDecorationIds = model.modified.deltaDecorations( - lastUnchangedRegions.modifiedDecorationIds, - newUnchangedRegions.map(r => ({ range: r.modifiedRange.toInclusiveRange()!, options: { description: 'unchanged' } })) - ); transaction(tx => { - for (const r of newUnchangedRegions) { - for (let i = 0; i < lastUnchangedRegions.regions.length; i++) { - if (r.originalRange.intersectsStrict(lastUnchangedRegionsOrigRanges[i]) - && r.modifiedRange.intersectsStrict(lastUnchangedRegionsModRanges[i])) { - r.setHiddenModifiedRange(lastUnchangedRegions.regions[i].getHiddenModifiedRange(undefined), tx); - break; - } - } - } + updateUnchangedRegions(result, tx); this._lastDiff = result; const state = DiffState.fromDiffResult(result); @@ -163,15 +184,6 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo this._isDiffUpToDate.set(true, tx); const currentSyncedMovedText = this.syncedMovedTexts.get(); this.syncedMovedTexts.set(currentSyncedMovedText ? this._lastDiff.moves.find(m => m.lineRangeMapping.modifiedRange.intersect(currentSyncedMovedText.lineRangeMapping.modifiedRange)) : undefined, tx); - - this._unchangedRegions.set( - { - regions: newUnchangedRegions, - originalDecorationIds, - modifiedDecorationIds - }, - tx - ); }); })); } From b7b88e4dbb934b06f227ec75ab1f72565a8648ae Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 10 Jul 2023 12:19:33 +0200 Subject: [PATCH 083/119] Opt the team into the new create PR view (#187434) --- .vscode/settings.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 85e608eb901..5d2930c5a92 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -135,6 +135,7 @@ "git", "sash" ], + "githubPullRequests.experimental.createView": true, "debug.javascript.terminalOptions": { "outFiles": [ "${workspaceFolder}/out/**/*.js", From 68a99e2f46d36f624ff0b1f57509411022785319 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 10 Jul 2023 14:27:07 +0200 Subject: [PATCH 084/119] Fixes inline completion/suggest widget issue. (#187458) --- .../inlineCompletions/browser/commands.ts | 5 ++++- .../browser/inlineCompletionsModel.ts | 16 +++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/commands.ts b/src/vs/editor/contrib/inlineCompletions/browser/commands.ts index 2370e210bf3..799433568e0 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/commands.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/commands.ts @@ -11,6 +11,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { showNextInlineSuggestionActionId, showPreviousInlineSuggestionActionId, inlineSuggestCommitId } from 'vs/editor/contrib/inlineCompletions/browser/commandIds'; import { InlineCompletionContextKeys } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys'; import { InlineCompletionsController } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController'; +import { Context as SuggestContext } from 'vs/editor/contrib/suggest/browser/suggest'; import * as nls from 'vs/nls'; import { MenuId, Action2 } from 'vs/platform/actions/common/actions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -85,6 +86,7 @@ export class AcceptNextWordOfInlineCompletion extends EditorAction { kbOpts: { weight: KeybindingWeight.EditorContrib + 1, primary: KeyMod.CtrlCmd | KeyCode.RightArrow, + kbExpr: ContextKeyExpr.and(EditorContextKeys.writable, InlineCompletionContextKeys.inlineSuggestionVisible), }, menuOpts: [{ menuId: MenuId.InlineSuggestionToolbar, @@ -145,7 +147,8 @@ export class AcceptInlineCompletion extends EditorAction { kbExpr: ContextKeyExpr.and( InlineCompletionContextKeys.inlineSuggestionVisible, EditorContextKeys.tabMovesFocus.toNegated(), - InlineCompletionContextKeys.inlineSuggestionHasIndentationLessThanTabSize + InlineCompletionContextKeys.inlineSuggestionHasIndentationLessThanTabSize, + SuggestContext.Visible.toNegated() ), } }); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index c66ec2a6d56..01946f09986 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -278,11 +278,11 @@ export class InlineCompletionsModel extends Disposable { throw new BugIndicatingError(); } - const ghostText = this.ghostText.get(); - const completion = this.selectedInlineCompletion.get()?.toInlineCompletion(undefined); - if (!ghostText || !completion) { + const state = this.state.get(); + if (!state || state.ghostText.isEmpty() || !state.completion) { return; } + const completion = state.completion.toInlineCompletion(undefined); editor.pushUndoStop(); if (completion.snippetInfo) { @@ -370,11 +370,12 @@ export class InlineCompletionsModel extends Disposable { throw new BugIndicatingError(); } - const ghostText = this.ghostText.get(); - const completion = this.selectedInlineCompletion.get()?.toInlineCompletion(undefined); - if (!ghostText || !completion) { + const state = this.state.get(); + if (!state || state.ghostText.isEmpty() || !state.completion) { return; } + const ghostText = state.ghostText; + const completion = state.completion.toInlineCompletion(undefined); if (completion.snippetInfo || completion.filterText !== completion.insertText) { // not in WYSIWYG mode, partial commit might change completion, thus it is not supported @@ -382,9 +383,6 @@ export class InlineCompletionsModel extends Disposable { return; } - if (ghostText.parts.length === 0) { - return; - } const firstPart = ghostText.parts[0]; const position = new Position(ghostText.lineNumber, firstPart.column); const line = firstPart.lines.join('\n'); From 2ff3c9a7e7d77b801643685e6eaaa76074656462 Mon Sep 17 00:00:00 2001 From: "Rickey K. Liang" Date: Mon, 10 Jul 2023 13:48:51 +0100 Subject: [PATCH 085/119] Revert Python docstring color (#184938) Revert b4368691e928191228076c0c329d815972e07fe1 all color themes: treat comment docstrings as comments too (#182162) --- .../theme-abyss/themes/abyss-color-theme.json | 7 +- extensions/theme-defaults/themes/dark_vs.json | 6 +- .../theme-defaults/themes/hc_black.json | 6 +- .../theme-defaults/themes/hc_light.json | 6 +- .../theme-defaults/themes/light_vs.json | 6 +- .../themes/kimbie-dark-color-theme.json | 3 +- .../themes/dimmed-monokai-color-theme.json | 7 +- .../themes/monokai-color-theme.json | 7 +- .../themes/quietlight-color-theme.json | 3 +- .../theme-red/themes/Red-color-theme.json | 7 +- .../themes/solarized-dark-color-theme.json | 7 +- .../themes/solarized-light-color-theme.json | 7 +- .../tomorrow-night-blue-color-theme.json | 7 +- .../test/colorize-results/test_py.json | 288 +++++++++--------- 14 files changed, 164 insertions(+), 203 deletions(-) diff --git a/extensions/theme-abyss/themes/abyss-color-theme.json b/extensions/theme-abyss/themes/abyss-color-theme.json index 4202bdd7d2a..e81c3b9adca 100644 --- a/extensions/theme-abyss/themes/abyss-color-theme.json +++ b/extensions/theme-abyss/themes/abyss-color-theme.json @@ -17,11 +17,8 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "name": "Comment", + "scope": "comment", "settings": { "foreground": "#384887" } diff --git a/extensions/theme-defaults/themes/dark_vs.json b/extensions/theme-defaults/themes/dark_vs.json index 04e33e07063..38af44cd2c1 100644 --- a/extensions/theme-defaults/themes/dark_vs.json +++ b/extensions/theme-defaults/themes/dark_vs.json @@ -57,11 +57,7 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "scope": "comment", "settings": { "foreground": "#6A9955" } diff --git a/extensions/theme-defaults/themes/hc_black.json b/extensions/theme-defaults/themes/hc_black.json index dbc3d2808c2..b8eda7974b7 100644 --- a/extensions/theme-defaults/themes/hc_black.json +++ b/extensions/theme-defaults/themes/hc_black.json @@ -43,11 +43,7 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "scope": "comment", "settings": { "foreground": "#7ca668" } diff --git a/extensions/theme-defaults/themes/hc_light.json b/extensions/theme-defaults/themes/hc_light.json index 5a06c116a1a..83a4083f90b 100644 --- a/extensions/theme-defaults/themes/hc_light.json +++ b/extensions/theme-defaults/themes/hc_light.json @@ -27,11 +27,7 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "scope": "comment", "settings": { "foreground": "#515151" } diff --git a/extensions/theme-defaults/themes/light_vs.json b/extensions/theme-defaults/themes/light_vs.json index 2cfe0ec0448..89589bb0e74 100644 --- a/extensions/theme-defaults/themes/light_vs.json +++ b/extensions/theme-defaults/themes/light_vs.json @@ -62,11 +62,7 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "scope": "comment", "settings": { "foreground": "#008000" } diff --git a/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json b/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json index b8f95bf86aa..eeb4eeb6b88 100644 --- a/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json +++ b/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json @@ -81,8 +81,7 @@ "name": "Comments", "scope": [ "comment", - "punctuation.definition.comment", - "string.quoted.docstring" + "punctuation.definition.comment" ], "settings": { "foreground": "#a57a4c" diff --git a/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json b/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json index 2ed1bcc96e0..ea84bededd5 100644 --- a/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json +++ b/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json @@ -78,11 +78,8 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "name": "Comment", + "scope": "comment", "settings": { "fontStyle": "", "foreground": "#9A9B99" diff --git a/extensions/theme-monokai/themes/monokai-color-theme.json b/extensions/theme-monokai/themes/monokai-color-theme.json index 2fddaa5972c..6489b0dd39c 100644 --- a/extensions/theme-monokai/themes/monokai-color-theme.json +++ b/extensions/theme-monokai/themes/monokai-color-theme.json @@ -118,11 +118,8 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "name": "Comment", + "scope": "comment", "settings": { "foreground": "#88846f" } diff --git a/extensions/theme-quietlight/themes/quietlight-color-theme.json b/extensions/theme-quietlight/themes/quietlight-color-theme.json index a01c73d3ec5..9d55f2e362b 100644 --- a/extensions/theme-quietlight/themes/quietlight-color-theme.json +++ b/extensions/theme-quietlight/themes/quietlight-color-theme.json @@ -20,8 +20,7 @@ "name": "Comments", "scope": [ "comment", - "punctuation.definition.comment", - "string.quoted.docstring" + "punctuation.definition.comment" ], "settings": { "fontStyle": "italic", diff --git a/extensions/theme-red/themes/Red-color-theme.json b/extensions/theme-red/themes/Red-color-theme.json index cf0f69316b2..c139400dc56 100644 --- a/extensions/theme-red/themes/Red-color-theme.json +++ b/extensions/theme-red/themes/Red-color-theme.json @@ -77,11 +77,8 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "name": "Comment", + "scope": "comment", "settings": { "fontStyle": "italic", "foreground": "#e7c0c0ff" diff --git a/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json b/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json index 3abb94bd426..e10c6e67403 100644 --- a/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json +++ b/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json @@ -17,11 +17,8 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "name": "Comment", + "scope": "comment", "settings": { "fontStyle": "italic", "foreground": "#586E75" diff --git a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json index 19ccf4fc92e..8b4074c9a07 100644 --- a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json +++ b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json @@ -17,11 +17,8 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "name": "Comment", + "scope": "comment", "settings": { "fontStyle": "italic", "foreground": "#93A1A1" diff --git a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json index 5591d39f1a9..8e24e6fe4de 100644 --- a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json +++ b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json @@ -78,11 +78,8 @@ } }, { - "name": "Comments", - "scope": [ - "comment", - "string.quoted.docstring" - ], + "name": "Comment", + "scope": "comment", "settings": { "foreground": "#7285B7" } diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_py.json b/extensions/vscode-colorize-tests/test/colorize-results/test_py.json index 9d40766533d..e858cd5f201 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_py.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_py.json @@ -395,42 +395,42 @@ "c": "'''", "t": "source.python string.quoted.docstring.multi.python punctuation.definition.string.begin.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": "Make the monkey eat N bananas!", "t": "source.python string.quoted.docstring.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": "'''", "t": "source.python string.quoted.docstring.multi.python punctuation.definition.string.end.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { @@ -3181,42 +3181,42 @@ "c": "\"\"\"", "t": "source.python string.quoted.docstring.multi.python punctuation.definition.string.begin.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": "Berechnung der zu zahlenden Steuern fuer ein zu versteuerndes Einkommen von x", "t": "source.python string.quoted.docstring.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": "\"\"\"", "t": "source.python string.quoted.docstring.multi.python punctuation.definition.string.end.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { @@ -7423,56 +7423,56 @@ "c": "'''", "t": "source.python string.quoted.docstring.raw.multi.python punctuation.definition.string.begin.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": "Module docstring", "t": "source.python string.quoted.docstring.raw.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": " Some text followed by code sample:", "t": "source.python string.quoted.docstring.raw.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": " ", "t": "source.python string.quoted.docstring.raw.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { @@ -7493,28 +7493,28 @@ "c": "for a in foo(2, b=1,", "t": "source.python string.quoted.docstring.raw.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": " ", "t": "source.python string.quoted.docstring.raw.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { @@ -7535,28 +7535,28 @@ "c": " c=3):", "t": "source.python string.quoted.docstring.raw.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": " ", "t": "source.python string.quoted.docstring.raw.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { @@ -7577,56 +7577,56 @@ "c": " print(a)", "t": "source.python string.quoted.docstring.raw.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": " 0", "t": "source.python string.quoted.docstring.raw.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": " 1", "t": "source.python string.quoted.docstring.raw.multi.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } }, { "c": "'''", "t": "source.python string.quoted.docstring.raw.multi.python punctuation.definition.string.end.python", "r": { - "dark_plus": "string.quoted.docstring: #6A9955", - "light_plus": "string.quoted.docstring: #008000", - "dark_vs": "string.quoted.docstring: #6A9955", - "light_vs": "string.quoted.docstring: #008000", - "hc_black": "string.quoted.docstring: #7CA668", - "dark_modern": "string.quoted.docstring: #6A9955", - "hc_light": "string.quoted.docstring: #515151", - "light_modern": "string.quoted.docstring: #008000" + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178", + "dark_modern": "string: #CE9178", + "hc_light": "string: #0F4A85", + "light_modern": "string: #A31515" } } ] \ No newline at end of file From 060dfba0dd0c6b103abd26c2c0fc873539735d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 10 Jul 2023 15:15:06 +0200 Subject: [PATCH 086/119] simplify screencast keyboard options (#187469) fixes #179541 --- .../browser/actions/developerActions.ts | 80 +++++++++++-------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts index b8d2fd75363..91297a82197 100644 --- a/src/vs/workbench/browser/actions/developerActions.ts +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -92,6 +92,13 @@ class InspectContextKeysAction extends Action2 { } } +interface IScreencastKeyboardOptions { + readonly showKeys?: boolean; + readonly showCommands?: boolean; + readonly showCommandGroups?: boolean; + readonly showSingleEditorCursorMoves?: boolean; +} + class ToggleScreencastModeAction extends Action2 { static disposable: IDisposable | undefined; @@ -259,11 +266,12 @@ class ToggleScreencastModeAction extends Action2 { return; } + const options = configurationService.getValue('screencastMode.keyboardOptions'); const event = new StandardKeyboardEvent(e); const shortcut = keybindingService.softDispatch(event, event.target); // Hide the single arrow key pressed - if (shortcut.kind === ResultKind.KbFound && shortcut.commandId && configurationService.getValue('screencastMode.hideSingleEditorCursorMoves') && ( + if (shortcut.kind === ResultKind.KbFound && shortcut.commandId && !(options.showSingleEditorCursorMoves ?? true) && ( ['cursorLeft', 'cursorRight', 'cursorUp', 'cursorDown'].includes(shortcut.commandId)) ) { return; @@ -280,18 +288,17 @@ class ToggleScreencastModeAction extends Action2 { length = 0; } - const format = configurationService.getValue<'keys' | 'command' | 'commandWithGroup' | 'commandAndKeys' | 'commandWithGroupAndKeys'>('screencastMode.keyboardShortcutsFormat'); const keybinding = keybindingService.resolveKeyboardEvent(event); const command = (this._isKbFound(shortcut) && shortcut.commandId) ? MenuRegistry.getCommand(shortcut.commandId) : null; - let titleLabel = ''; + let commandAndGroupLabel = ''; let keyLabel: string | undefined | null = keybinding.getLabel(); if (command) { - titleLabel = typeof command.title === 'string' ? command.title : command.title.value; + commandAndGroupLabel = typeof command.title === 'string' ? command.title : command.title.value; - if ((format === 'commandWithGroup' || format === 'commandWithGroupAndKeys') && command.category) { - titleLabel = `${typeof command.category === 'string' ? command.category : command.category.value}: ${titleLabel} `; + if ((options.showCommandGroups ?? false) && command.category) { + commandAndGroupLabel = `${typeof command.category === 'string' ? command.category : command.category.value}: ${commandAndGroupLabel} `; } if (this._isKbFound(shortcut) && shortcut.commandId) { @@ -304,13 +311,11 @@ class ToggleScreencastModeAction extends Action2 { } } - const onlyKeyboardShortcuts = configurationService.getValue('screencastMode.onlyKeyboardShortcuts'); - - if (format !== 'keys' && titleLabel && !onlyKeyboardShortcuts) { - append(keyboardMarker, $('span.title', {}, `${titleLabel} `)); + if ((options.showCommands ?? true) && commandAndGroupLabel) { + append(keyboardMarker, $('span.title', {}, `${commandAndGroupLabel} `)); } - if (onlyKeyboardShortcuts || !titleLabel || (this._isKbFound(shortcut) && shortcut.commandId) && (format === 'keys' || format === 'commandAndKeys' || format === 'commandWithGroupAndKeys')) { + if (options.showKeys ?? true) { // Fix label for arrow keys keyLabel = keyLabel?.replace('UpArrow', '↑') ?.replace('DownArrow', '↓') @@ -421,27 +426,38 @@ configurationRegistry.registerConfiguration({ maximum: 100, description: localize('screencastMode.fontSize', "Controls the font size (in pixels) of the screencast mode keyboard.") }, - 'screencastMode.keyboardShortcutsFormat': { - enum: ['keys', 'command', 'commandWithGroup', 'commandAndKeys', 'commandWithGroupAndKeys'], - enumDescriptions: [ - localize('keyboardShortcutsFormat.keys', "Keys."), - localize('keyboardShortcutsFormat.command', "Command title."), - localize('keyboardShortcutsFormat.commandWithGroup', "Command title prefixed by its group."), - localize('keyboardShortcutsFormat.commandAndKeys', "Command title and keys."), - localize('keyboardShortcutsFormat.commandWithGroupAndKeys', "Command title and keys, with the command prefixed by its group.") - ], - description: localize('screencastMode.keyboardShortcutsFormat', "Controls what is displayed in the keyboard overlay when showing shortcuts."), - default: 'commandAndKeys' - }, - 'screencastMode.onlyKeyboardShortcuts': { - type: 'boolean', - description: localize('screencastMode.onlyKeyboardShortcuts', "Show only keyboard shortcuts in screencast mode (do not include action names)."), - default: false - }, - 'screencastMode.hideSingleEditorCursorMoves': { - type: 'boolean', - description: localize('screencastMode.hideSingleEditorCursorMoves', "Hide the single editor cursor move commands in screencast mode."), - default: false + 'screencastMode.keyboardOptions': { + type: 'object', + description: localize('screencastMode.keyboardOptions.description', "Options for customizing the keyboard overlay in screencast mode."), + properties: { + 'showKeys': { + type: 'boolean', + default: true, + description: localize('screencastMode.keyboardOptions.showKeys', "Show raw keys.") + }, + 'showCommands': { + type: 'boolean', + default: true, + description: localize('screencastMode.keyboardOptions.showCommands', "Show command names.") + }, + 'showCommandGroups': { + type: 'boolean', + default: false, + description: localize('screencastMode.keyboardOptions.showCommandGroups', "Show command group names, when commands are also shown.") + }, + 'showSingleEditorCursorMoves': { + type: 'boolean', + default: true, + description: localize('screencastMode.keyboardOptions.showSingleEditorCursorMoves', "Show single editor cursor move commands.") + } + }, + default: { + 'showKeys': true, + 'showCommands': true, + 'showCommandGroups': false, + 'showSingleEditorCursorMoves': true + }, + additionalProperties: false }, 'screencastMode.keyboardOverlayTimeout': { type: 'number', From ccea02b96dbc1351795de5ce66d8b52f10576fde Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 10 Jul 2023 15:16:02 +0200 Subject: [PATCH 087/119] Git - avoid opening a repository multiple times if symbolic links are used (#187435) --- extensions/git/src/model.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts index e8a496822f0..cf22a284bbb 100644 --- a/extensions/git/src/model.ts +++ b/extensions/git/src/model.ts @@ -493,8 +493,9 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu @sequentialize async openRepository(repoPath: string, openIfClosed = false): Promise { this.logger.trace(`Opening repository: ${repoPath}`); - if (this.getRepositoryExact(repoPath)) { - this.logger.trace(`Repository for path ${repoPath} already exists`); + const existingRepository = await this.getRepositoryExact(repoPath); + if (existingRepository) { + this.logger.trace(`Repository for path ${repoPath} already exists: ${existingRepository.root})`); return; } @@ -524,8 +525,9 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu const { repositoryRoot, unsafeRepositoryMatch } = await this.getRepositoryRoot(repoPath); this.logger.trace(`Repository root for path ${repoPath} is: ${repositoryRoot}`); - if (this.getRepositoryExact(repositoryRoot)) { - this.logger.trace(`Repository for path ${repositoryRoot} already exists`); + const existingRepository = await this.getRepositoryExact(repositoryRoot); + if (existingRepository) { + this.logger.trace(`Repository for path ${repositoryRoot} already exists: ${existingRepository.root}`); return; } @@ -763,9 +765,12 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu return liveRepository && liveRepository.repository; } - private getRepositoryExact(repoPath: string): Repository | undefined { - const openRepository = this.openRepositories - .find(r => pathEquals(r.repository.root, repoPath)); + private async getRepositoryExact(repoPath: string): Promise { + const repoPathCanonical = await fs.promises.realpath(repoPath, { encoding: 'utf8' }); + const openRepository = this.openRepositories.find(async r => { + const rootPathCanonical = await fs.promises.realpath(r.repository.root, { encoding: 'utf8' }); + return pathEquals(rootPathCanonical, repoPathCanonical); + }); return openRepository?.repository; } From 6d1066875ea1fb9a1116419c5bb895d51846f4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 10 Jul 2023 16:15:29 +0200 Subject: [PATCH 088/119] isolate artifacts from attempted runs (#187437) * isolate artifacts from attempted runs * set ARTIFACT_PREFIX to empty string first * cleaner --- .../alpine/product-build-alpine.yml | 12 ++++++---- .../darwin/product-build-darwin.yml | 14 +++++++---- .../linux/product-build-linux.yml | 23 ++++++++++--------- build/azure-pipelines/product-build.yml | 2 ++ .../azure-pipelines/web/product-build-web.yml | 6 ++++- .../win32/product-build-win32.yml | 18 +++++++++------ 6 files changed, 47 insertions(+), 28 deletions(-) diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index 704f4814ae9..eed3623addc 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -128,23 +128,27 @@ steps: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server (web) + - script: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" + condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) + displayName: Generate artifact prefix + - publish: $(SERVER_PATH) - artifact: vscode_server_alpine_$(VSCODE_ARCH)_archive-unsigned + artifact: $(ARTIFACT_PREFIX)vscode_server_alpine_$(VSCODE_ARCH)_archive-unsigned displayName: Publish server archive condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], ''), ne(variables['VSCODE_ARCH'], 'x64')) - publish: $(WEB_PATH) - artifact: vscode_web_alpine_$(VSCODE_ARCH)_archive-unsigned + artifact: $(ARTIFACT_PREFIX)vscode_web_alpine_$(VSCODE_ARCH)_archive-unsigned displayName: Publish web server archive condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], ''), ne(variables['VSCODE_ARCH'], 'x64')) # Legacy x64 artifact name - publish: $(SERVER_PATH) - artifact: vscode_server_linux_alpine_archive-unsigned + artifact: $(ARTIFACT_PREFIX)vscode_server_linux_alpine_archive-unsigned displayName: Publish x64 server archive condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], ''), eq(variables['VSCODE_ARCH'], 'x64')) - publish: $(WEB_PATH) - artifact: vscode_web_linux_alpine_archive-unsigned + artifact: $(ARTIFACT_PREFIX)vscode_web_linux_alpine_archive-unsigned displayName: Publish x64 web server archive condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], ''), eq(variables['VSCODE_ARCH'], 'x64')) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 95d81431089..054a3caec37 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -202,6 +202,10 @@ steps: condition: and(succeededOrFailed(), eq(variables['BUILT_CLIENT'], 'true')) displayName: Package client + - script: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" + condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) + displayName: Generate artifact prefix + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 displayName: Generate SBOM (client) inputs: @@ -210,7 +214,7 @@ steps: - publish: $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)/_manifest displayName: Publish SBOM (client) - artifact: vscode_client_darwin_$(VSCODE_ARCH)_sbom + artifact: $(ARTIFACT_PREFIX)sbom_client_darwin_$(VSCODE_ARCH)_sbom - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 displayName: Generate SBOM (server) @@ -220,19 +224,19 @@ steps: - publish: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)/_manifest displayName: Publish SBOM (server) - artifact: vscode_server_darwin_$(VSCODE_ARCH)_sbom + artifact: $(ARTIFACT_PREFIX)sbom_server_darwin_$(VSCODE_ARCH)_sbom - publish: $(CLIENT_PATH) - artifact: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive + artifact: $(ARTIFACT_PREFIX)unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive condition: and(succeededOrFailed(), ne(variables['CLIENT_PATH'], '')) displayName: Publish client archive - publish: $(SERVER_PATH) - artifact: vscode_server_darwin_$(VSCODE_ARCH)_archive-unsigned + artifact: $(ARTIFACT_PREFIX)vscode_server_darwin_$(VSCODE_ARCH)_archive-unsigned condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], '')) displayName: Publish server archive - publish: $(WEB_PATH) - artifact: vscode_web_darwin_$(VSCODE_ARCH)_archive-unsigned + artifact: $(ARTIFACT_PREFIX)vscode_web_darwin_$(VSCODE_ARCH)_archive-unsigned condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], '')) displayName: Publish web server archive diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index fa307a37628..87f4cd800da 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -235,7 +235,7 @@ steps: - ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}: - task: DownloadPipelineArtifact@2 inputs: - artifact: vscode_cli_linux_$(VSCODE_ARCH)_cli + artifact: $(ARTIFACT_PREFIX)vscode_cli_linux_$(VSCODE_ARCH)_cli patterns: "**" path: $(Build.ArtifactStagingDirectory)/cli displayName: Download VS Code CLI @@ -280,8 +280,9 @@ steps: - script: node build/azure-pipelines/common/sign $(Agent.ToolsDirectory)/esrpclient/*/*/net6.0/esrpcli.dll rpm $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) .build/linux/rpm '*.rpm' displayName: Codesign rpm - # - script: ./build/azure-pipelines/linux/prepare-publish.sh - # displayName: Prepare for Publish + - script: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" + condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) + displayName: Generate artifact prefix - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 displayName: Generate SBOM (client) @@ -291,7 +292,7 @@ steps: - publish: $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/_manifest displayName: Publish SBOM (client) - artifact: vscode_client_linux_$(VSCODE_ARCH)_sbom + artifact: $(ARTIFACT_PREFIX)sbom_vscode_client_linux_$(VSCODE_ARCH) - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 displayName: Generate SBOM (server) @@ -301,35 +302,35 @@ steps: - publish: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)/_manifest displayName: Publish SBOM (server) - artifact: vscode_server_linux_$(VSCODE_ARCH)_sbom + artifact: $(ARTIFACT_PREFIX)sbom_vscode_server_linux_$(VSCODE_ARCH) - publish: $(CLIENT_PATH) - artifact: vscode_client_linux_$(VSCODE_ARCH)_archive-unsigned + artifact: $(ARTIFACT_PREFIX)vscode_client_linux_$(VSCODE_ARCH)_archive-unsigned condition: and(succeededOrFailed(), ne(variables['CLIENT_PATH'], '')) displayName: Publish client archive - publish: $(SERVER_PATH) - artifact: vscode_server_linux_$(VSCODE_ARCH)_archive-unsigned + artifact: $(ARTIFACT_PREFIX)vscode_server_linux_$(VSCODE_ARCH)_archive-unsigned condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], '')) displayName: Publish server archive - publish: $(WEB_PATH) - artifact: vscode_web_linux_$(VSCODE_ARCH)_archive-unsigned + artifact: $(ARTIFACT_PREFIX)vscode_web_linux_$(VSCODE_ARCH)_archive-unsigned condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], '')) displayName: Publish web server archive - publish: $(DEB_PATH) - artifact: vscode_client_linux_$(VSCODE_ARCH)_deb-package + artifact: $(ARTIFACT_PREFIX)vscode_client_linux_$(VSCODE_ARCH)_deb-package condition: and(succeededOrFailed(), ne(variables['DEB_PATH'], '')) displayName: Publish deb package - publish: $(RPM_PATH) - artifact: vscode_client_linux_$(VSCODE_ARCH)_rpm-package + artifact: $(ARTIFACT_PREFIX)vscode_client_linux_$(VSCODE_ARCH)_rpm-package condition: and(succeededOrFailed(), ne(variables['RPM_PATH'], '')) displayName: Publish rpm package - publish: $(SNAP_PATH) - artifact: snap-$(VSCODE_ARCH) + artifact: $(ARTIFACT_PREFIX)snap-$(VSCODE_ARCH) condition: and(succeededOrFailed(), ne(variables['SNAP_PATH'], '')) displayName: Publish snap pre-package diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index d0a5f753431..7d809d6d11e 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -136,6 +136,8 @@ variables: value: true - name: Codeql.SkipTaskAutoInjection value: true + - name: ARTIFACT_PREFIX + value: '' name: "$(Date:yyyyMMdd).$(Rev:r) (${{ parameters.VSCODE_QUALITY }})" diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 1b42ebaaaf9..a941ae9adfe 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -139,7 +139,11 @@ steps: node build/azure-pipelines/upload-nlsmetadata displayName: Upload NLS Metadata + - script: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" + condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) + displayName: Generate artifact prefix + - publish: $(WEB_PATH) - artifact: vscode_web_linux_standalone_archive-unsigned + artifact: $(ARTIFACT_PREFIX)vscode_web_linux_standalone_archive-unsigned condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], '')) displayName: Publish web archive diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 7bca3e5ef8a..24957abbaa2 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -299,6 +299,10 @@ steps: echo "##vso[task.setvariable variable=USER_SETUP_PATH]$SetupPath" displayName: Build user setup + - powershell: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" + condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) + displayName: Generate artifact prefix + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 displayName: Generate SBOM (client) inputs: @@ -307,7 +311,7 @@ steps: - publish: $(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/_manifest displayName: Publish SBOM (client) - artifact: vscode_client_win32_$(VSCODE_ARCH)_sbom + artifact: $(ARTIFACT_PREFIX)sbom_client_win32_$(VSCODE_ARCH) - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 displayName: Generate SBOM (server) @@ -318,30 +322,30 @@ steps: - publish: $(agent.builddirectory)/vscode-server-win32-$(VSCODE_ARCH)/_manifest displayName: Publish SBOM (server) - artifact: vscode_server_win32_$(VSCODE_ARCH)_sbom + artifact: $(ARTIFACT_PREFIX)sbom_server_win32_$(VSCODE_ARCH) condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) - publish: $(CLIENT_PATH) - artifact: vscode_client_win32_$(VSCODE_ARCH)_archive + artifact: $(ARTIFACT_PREFIX)vscode_client_win32_$(VSCODE_ARCH)_archive condition: and(succeededOrFailed(), ne(variables['CLIENT_PATH'], '')) displayName: Publish archive - publish: $(SERVER_PATH) - artifact: vscode_server_win32_$(VSCODE_ARCH)_archive + artifact: $(ARTIFACT_PREFIX)vscode_server_win32_$(VSCODE_ARCH)_archive condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], ''), ne(variables['VSCODE_ARCH'], 'arm64')) displayName: Publish server archive - publish: $(WEB_PATH) - artifact: vscode_web_win32_$(VSCODE_ARCH)_archive + artifact: $(ARTIFACT_PREFIX)vscode_web_win32_$(VSCODE_ARCH)_archive condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], ''), ne(variables['VSCODE_ARCH'], 'arm64')) displayName: Publish web server archive - publish: $(SYSTEM_SETUP_PATH) - artifact: vscode_client_win32_$(VSCODE_ARCH)_setup + artifact: $(ARTIFACT_PREFIX)vscode_client_win32_$(VSCODE_ARCH)_setup condition: and(succeededOrFailed(), ne(variables['SYSTEM_SETUP_PATH'], '')) displayName: Publish system setup - publish: $(USER_SETUP_PATH) - artifact: vscode_client_win32_$(VSCODE_ARCH)_user-setup + artifact: $(ARTIFACT_PREFIX)vscode_client_win32_$(VSCODE_ARCH)_user-setup condition: and(succeededOrFailed(), ne(variables['USER_SETUP_PATH'], '')) displayName: Publish user setup From db16e86c983455a13469584702ab19f838565612 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 10 Jul 2023 10:33:01 -0400 Subject: [PATCH 089/119] Restore sinon sandbox (#187476) Restore sinon stubs --- .../telemetry/test/browser/telemetryService.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/platform/telemetry/test/browser/telemetryService.test.ts b/src/vs/platform/telemetry/test/browser/telemetryService.test.ts index 0c6711e8539..cbfd8554437 100644 --- a/src/vs/platform/telemetry/test/browser/telemetryService.test.ts +++ b/src/vs/platform/telemetry/test/browser/telemetryService.test.ts @@ -292,6 +292,7 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + sinon.restore(); })); test('Error Telemetry removes PII from filename with spaces', sinonTestFn(function (this: any) { @@ -314,6 +315,7 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + sinon.restore(); })); test('Uncaught Error Telemetry removes PII from filename', sinonTestFn(function (this: any) { @@ -342,6 +344,7 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + sinon.restore(); })); test('Unexpected Error Telemetry removes PII', sinonTestFn(function (this: any) { @@ -398,6 +401,7 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + sinon.restore(); })); test('Unexpected Error Telemetry removes PII but preserves Code file path', sinonTestFn(function (this: any) { @@ -465,6 +469,7 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + sinon.restore(); })); test('Unexpected Error Telemetry removes PII but preserves Code file path with node modules', sinonTestFn(function (this: any) { @@ -559,6 +564,7 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + sinon.restore(); })); test('Unexpected Error Telemetry removes PII but preserves Missing Model error message', sinonTestFn(function (this: any) { @@ -623,6 +629,7 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + sinon.restore(); })); test('Unexpected Error Telemetry removes PII but preserves No Such File error message', sinonTestFn(function (this: any) { @@ -692,6 +699,7 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + sinon.restore(); } finally { Errors.setUnexpectedErrorHandler(origErrorHandler); } From b0620485c20aea2911cd1ee79e74fb7b35c943e0 Mon Sep 17 00:00:00 2001 From: Zuo Zongyuan Date: Mon, 10 Jul 2023 22:58:32 +0800 Subject: [PATCH 090/119] Fix: Remote tunnel service running on VM with XGETBV disabled exit with SIGILL when being connected (#187345) fix: update cpufeatures from v0.2.5 to v0.2.8 (#187343) --- cli/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/Cargo.lock b/cli/Cargo.lock index bed1af5cdd7..8e6e477991f 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -489,9 +489,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" dependencies = [ "libc", ] From c61a08d4610712cd8c4e719a451cb1e4b6cd6e2a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 10 Jul 2023 17:04:45 +0200 Subject: [PATCH 091/119] adding code in order be able to pass in a position for the inline chat --- src/vs/workbench/api/common/extHostInlineChat.ts | 6 +++++- .../inlineChat/browser/inlineChatActions.ts | 7 +++++-- .../inlineChat/browser/inlineChatController.ts | 15 ++++++++++----- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/api/common/extHostInlineChat.ts b/src/vs/workbench/api/common/extHostInlineChat.ts index 07eb77c0deb..1a5e5e9eba4 100644 --- a/src/vs/workbench/api/common/extHostInlineChat.ts +++ b/src/vs/workbench/api/common/extHostInlineChat.ts @@ -17,6 +17,7 @@ import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; import type * as vscode from 'vscode'; import { ApiCommand, ApiCommandArgument, ApiCommandResult, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { IRange } from 'vs/editor/common/core/range'; +import { IPosition } from 'vs/editor/common/core/position'; class ProviderWrapper { @@ -59,12 +60,14 @@ export class ExtHostInteractiveEditor implements ExtHostInlineChatShape { initialRange?: vscode.Range; message?: string; autoSend?: boolean; + position?: vscode.Position; }; type InteractiveEditorRunOptions = { initialRange?: IRange; message?: string; autoSend?: boolean; + position?: IPosition; }; extHostCommands.registerApiCommand(new ApiCommand( @@ -78,7 +81,8 @@ export class ExtHostInteractiveEditor implements ExtHostInlineChatShape { return { initialRange: v.initialRange ? typeConvert.Range.from(v.initialRange) : undefined, message: v.message, - autoSend: v.autoSend + autoSend: v.autoSend, + position: v.position ? typeConvert.Position.from(v.position) : undefined, }; })], ApiCommandResult.Void diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index 83b481739a1..1f2d61380d8 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -29,6 +29,7 @@ import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/co import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibilityContribution'; import { Disposable } from 'vs/base/common/lifecycle'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { Position } from 'vs/editor/common/core/position'; CommandsRegistry.registerCommandAlias('interactiveEditor.start', 'inlineChat.start'); @@ -50,11 +51,12 @@ export class StartSessionAction extends EditorAction2 { } private _isInteractivEditorOptions(options: any): options is InlineChatRunOptions { - const { initialRange, message, autoSend } = options; + const { initialRange, message, autoSend, position } = options; if ( typeof message !== 'undefined' && typeof message !== 'string' || typeof autoSend !== 'undefined' && typeof autoSend !== 'boolean' - || typeof initialRange !== 'undefined' && !Range.isIRange(initialRange)) { + || typeof initialRange !== 'undefined' && !Range.isIRange(initialRange) + || typeof position !== 'undefined' && typeof !Position.isIPosition(position)) { return false; } return true; @@ -66,6 +68,7 @@ export class StartSessionAction extends EditorAction2 { if (arg && this._isInteractivEditorOptions(arg)) { options = arg; } + console.log('options inside of run editor command : ', options); InlineChatController.get(editor)?.run(options); } } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index ba825ebb44a..c5f48e7963c 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -14,7 +14,7 @@ import { StopWatch } from 'vs/base/common/stopwatch'; import { assertType } from 'vs/base/common/types'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditOperation } from 'vs/editor/common/core/editOperation'; -import { Position } from 'vs/editor/common/core/position'; +import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { IEditorContribution, ScrollType } from 'vs/editor/common/editorCommon'; import { ModelDecorationOptions, createTextBufferFactoryFromSnapshot } from 'vs/editor/common/model/textModel'; @@ -66,6 +66,7 @@ export interface InlineChatRunOptions { autoSend?: boolean; existingSession?: Session; isUnstashed?: boolean; + position?: IPosition; } export class InlineChatController implements IEditorContribution { @@ -184,12 +185,14 @@ export class InlineChatController implements IEditorContribution { // ---- state machine - private _showWidget(initialRender: boolean = false) { + // TODO: maybe should instead use the position inside of the line number? + // Makes the code more difficult but more coherent + private _showWidget(initialRender: boolean = false, position?: IPosition) { assertType(this._editor.hasModel()); let widgetPosition: Position; if (initialRender) { - widgetPosition = this._editor.getSelection().getEndPosition(); + widgetPosition = position ? Position.lift(position) : this._editor.getSelection().getEndPosition(); this._zone.value.setContainerMargins(); this._zone.value.setWidgetMargins(widgetPosition); } else { @@ -219,7 +222,8 @@ export class InlineChatController implements IEditorContribution { let session: Session | undefined = options.existingSession; - this._showWidget(true); + console.log('options : ', options); + this._showWidget(true, options.position); this._zone.value.widget.updateInfo(localize('welcome.1', "AI-generated code may be incorrect")); this._zone.value.widget.placeholder = this._getPlaceholderText(); @@ -307,7 +311,8 @@ export class InlineChatController implements IEditorContribution { } }); - this._showWidget(true); + console.log('options : ', options); + this._showWidget(true, options.position); this._sessionStore.add(this._editor.onDidChangeModel((e) => { const msg = this._activeSession?.lastExchange From ef4206956adc05e328ed48ff30fc326ae109bec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 10 Jul 2023 17:12:32 +0200 Subject: [PATCH 092/119] always roll processed artifacts forward (#187465) --- build/azure-pipelines/product-publish.ps1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/azure-pipelines/product-publish.ps1 b/build/azure-pipelines/product-publish.ps1 index a9170d54f5c..fa4bf1aa31e 100644 --- a/build/azure-pipelines/product-publish.ps1 +++ b/build/azure-pipelines/product-publish.ps1 @@ -60,6 +60,7 @@ do { $artifacts | ForEach-Object { $artifactName = $_.name + if($set.Add($artifactName)) { Write-Host "Processing artifact: '$artifactName. Downloading from: $($_.resource.downloadUrl)" @@ -98,8 +99,11 @@ do { } | Format-Table exec { node build/azure-pipelines/common/createAsset.js $product $os $arch $type $asset.Name $asset.FullName } - $artifactName >> $ARTIFACT_PROCESSED_FILE_PATH } + + # Mark the artifact as processed. Make sure to keep the previously + # processed artifacts in the file as well, not just from this run. + $artifactName >> $ARTIFACT_PROCESSED_FILE_PATH } # Get the timeline and see if it says the other stage completed From ba4564b6335e2a6d02932b266d7ecc22dee7824e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 10 Jul 2023 17:23:02 +0200 Subject: [PATCH 093/119] include error message when save fails (#187479) --- .../services/configuration/common/configurationEditing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/configuration/common/configurationEditing.ts b/src/vs/workbench/services/configuration/common/configurationEditing.ts index 33919697053..699d388f340 100644 --- a/src/vs/workbench/services/configuration/common/configurationEditing.ts +++ b/src/vs/workbench/services/configuration/common/configurationEditing.ts @@ -210,7 +210,7 @@ export class ConfigurationEditing { if ((error).fileOperationResult === FileOperationResult.FILE_MODIFIED_SINCE) { throw this.toConfigurationEditingError(ConfigurationEditingErrorCode.ERROR_CONFIGURATION_FILE_MODIFIED_SINCE, operation.target, operation); } - throw this.toConfigurationEditingError(ConfigurationEditingErrorCode.ERROR_INTERNAL, operation.target, operation); + throw new ConfigurationEditingError(nls.localize('fsError', "Error while writing to {0}. {1}", this.stringifyTarget(operation.target), error.message), ConfigurationEditingErrorCode.ERROR_INTERNAL); } } From 8e1b0952af8c2902d4da0e87949f67e208377037 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 10 Jul 2023 17:25:54 +0200 Subject: [PATCH 094/119] cleaning the code --- .../workbench/contrib/inlineChat/browser/inlineChatActions.ts | 3 +-- .../contrib/inlineChat/browser/inlineChatController.ts | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts index 1f2d61380d8..b5cf33298e6 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts @@ -56,7 +56,7 @@ export class StartSessionAction extends EditorAction2 { typeof message !== 'undefined' && typeof message !== 'string' || typeof autoSend !== 'undefined' && typeof autoSend !== 'boolean' || typeof initialRange !== 'undefined' && !Range.isIRange(initialRange) - || typeof position !== 'undefined' && typeof !Position.isIPosition(position)) { + || typeof position !== 'undefined' && !Position.isIPosition(position)) { return false; } return true; @@ -68,7 +68,6 @@ export class StartSessionAction extends EditorAction2 { if (arg && this._isInteractivEditorOptions(arg)) { options = arg; } - console.log('options inside of run editor command : ', options); InlineChatController.get(editor)?.run(options); } } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index c5f48e7963c..d24cbbe0ab8 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -185,8 +185,6 @@ export class InlineChatController implements IEditorContribution { // ---- state machine - // TODO: maybe should instead use the position inside of the line number? - // Makes the code more difficult but more coherent private _showWidget(initialRender: boolean = false, position?: IPosition) { assertType(this._editor.hasModel()); @@ -222,7 +220,6 @@ export class InlineChatController implements IEditorContribution { let session: Session | undefined = options.existingSession; - console.log('options : ', options); this._showWidget(true, options.position); this._zone.value.widget.updateInfo(localize('welcome.1', "AI-generated code may be incorrect")); this._zone.value.widget.placeholder = this._getPlaceholderText(); @@ -311,7 +308,6 @@ export class InlineChatController implements IEditorContribution { } }); - console.log('options : ', options); this._showWidget(true, options.position); this._sessionStore.add(this._editor.onDidChangeModel((e) => { From 58969b44cd7196f8f596944280691d05300abed3 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 10 Jul 2023 09:28:26 -0700 Subject: [PATCH 095/119] increase time, rename --- .../contrib/tasks/browser/abstractTaskService.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 0bb0287040a..5dc0f99ea57 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -223,7 +223,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer protected _outputChannel: IOutputChannel; protected readonly _onDidStateChange: Emitter; - private _waitForSupportedExecutions: Promise; + private _waitForOneSupportedExecution: Promise; private _waitForAllSupportedExecutions: Promise; private _onDidRegisterSupportedExecutions: Emitter = new Emitter(); private _onDidRegisterAllSupportedExecutions: Emitter = new Emitter(); @@ -335,7 +335,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._setPersistentTask(e.__task); } })); - this._waitForSupportedExecutions = new Promise(resolve => { + this._waitForOneSupportedExecution = new Promise(resolve => { once(this._onDidRegisterSupportedExecutions.event)(() => resolve()); }); this._waitForAllSupportedExecutions = new Promise(resolve => { @@ -2209,10 +2209,10 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!(await this._trust())) { return new Map(); } - await this._waitForSupportedExecutions; + await this._waitForOneSupportedExecution; if (runSource === TaskRunSource.Reconnect) { - await raceTimeout(this._waitForAllSupportedExecutions, 500, () => { - console.warn('Timed out waiting for all supported executions for task reconnection'); + await raceTimeout(this._waitForAllSupportedExecutions, 2000, () => { + this._logService.warn('Timed out waiting for all supported executions for task reconnection'); }); } await this._whenTaskSystemReady; @@ -2891,7 +2891,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer /** * * @param tasks - The tasks which need to be filtered - * @param taskGlobsInList - This tells splitPerGroupType to filter out globbed tasks (into defaults) + * @param tasksInList - This tells splitPerGroupType to filter out globbed tasks (into defaults) * @returns */ private _getDefaultTasks(tasks: Task[], taskGlobsInList: boolean = false): Task[] { From 44d1d6a39c8d88c481ce48c83da198c5c41048d3 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Mon, 10 Jul 2023 10:19:55 -0700 Subject: [PATCH 096/119] build: check for cargo.lock changes in pr too (#187481) * build: check for cargo.lock changes in pr too * keep old name --- .github/workflows/no-yarn-lock-changes.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/no-yarn-lock-changes.yml b/.github/workflows/no-yarn-lock-changes.yml index ac32bc367dc..57082a28b1c 100644 --- a/.github/workflows/no-yarn-lock-changes.yml +++ b/.github/workflows/no-yarn-lock-changes.yml @@ -24,8 +24,8 @@ jobs: - name: Get file changes uses: trilom/file-changes-action@ce38c8ce2459ca3c303415eec8cb0409857b4272 if: ${{ steps.control.outputs.should_run == 'true' }} - - name: Check for yarn.lock changes + - name: Check for lockfile changes if: ${{ steps.control.outputs.should_run == 'true' }} run: | - cat $HOME/files.json | jq -e 'any(test("yarn\\.lock$")) | not' \ - || (echo "Changes to yarn.lock files aren't allowed in PRs." && exit 1) + cat $HOME/files.json | jq -e 'any(test("yarn\\.lock$|Cargo\\.lock$")) | not' \ + || (echo "Changes to yarn.lock/Cargo.lock files aren't allowed in PRs." && exit 1) From c6033eadec1aa29c958ab108ccd4fd62613ae1b7 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Mon, 10 Jul 2023 10:35:24 -0700 Subject: [PATCH 097/119] Restore previous behavior of `onDidChangeSecret` (#187333) ref https://github.com/microsoft/vscode/issues/187247 --- src/vs/platform/secrets/common/secrets.ts | 27 +++++------------------ 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/vs/platform/secrets/common/secrets.ts b/src/vs/platform/secrets/common/secrets.ts index 47ed701bbf8..6c6b822ebc2 100644 --- a/src/vs/platform/secrets/common/secrets.ts +++ b/src/vs/platform/secrets/common/secrets.ts @@ -7,7 +7,7 @@ import { SequencerByKey } from 'vs/base/common/async'; import { IEncryptionService } from 'vs/platform/encryption/common/encryptionService'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, InMemoryStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { Event, PauseableEmitter } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; import { ILogService } from 'vs/platform/log/common/log'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -30,7 +30,7 @@ export abstract class BaseSecretStorageService implements ISecretStorageService private _storagePrefix = 'secret://'; - private readonly _onDidChangeSecret = new PauseableEmitter(); + private readonly _onDidChangeSecret = new Emitter(); onDidChangeSecret: Event = this._onDidChangeSecret.event; protected readonly _sequencer = new SequencerByKey(); @@ -55,11 +55,6 @@ export abstract class BaseSecretStorageService implements ISecretStorageService return; } - if (this._onDidChangeSecret.isPaused) { - this._logService.trace(`[SecretStorageService] Skipping change event for secret: ${key} because it is paused`); - return; - } - const secretKey = key.slice(this._storagePrefix.length); this._logService.trace(`[SecretStorageService] Notifying change in value for secret: ${secretKey}`); @@ -104,13 +99,8 @@ export abstract class BaseSecretStorageService implements ISecretStorageService throw e; } const fullKey = this.getKey(key); - try { - this._onDidChangeSecret.pause(); - this._logService.trace('[secrets] storing encrypted secret for key:', fullKey); - storageService.store(fullKey, encrypted, StorageScope.APPLICATION, StorageTarget.MACHINE); - } finally { - this._onDidChangeSecret.resume(); - } + this._logService.trace('[secrets] storing encrypted secret for key:', fullKey); + storageService.store(fullKey, encrypted, StorageScope.APPLICATION, StorageTarget.MACHINE); this._logService.trace('[secrets] stored encrypted secret for key:', fullKey); }); } @@ -120,13 +110,8 @@ export abstract class BaseSecretStorageService implements ISecretStorageService const storageService = await this.resolvedStorageService; const fullKey = this.getKey(key); - try { - this._onDidChangeSecret.pause(); - this._logService.trace('[secrets] deleting secret for key:', fullKey); - storageService.remove(fullKey, StorageScope.APPLICATION); - } finally { - this._onDidChangeSecret.resume(); - } + this._logService.trace('[secrets] deleting secret for key:', fullKey); + storageService.remove(fullKey, StorageScope.APPLICATION); this._logService.trace('[secrets] deleted secret for key:', fullKey); }); } From de6f24cf773acd9785f7535b8d2a53b8d7c87eb2 Mon Sep 17 00:00:00 2001 From: FateLee Date: Tue, 11 Jul 2023 01:36:14 +0800 Subject: [PATCH 098/119] fix: typos (#179840) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 李京廷 --- src/vs/editor/browser/widget/codeEditorWidget.ts | 2 +- src/vs/editor/common/core/cursorColumns.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index e78be4bd6b7..e90726fe00c 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1308,7 +1308,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE for (const decorationOption of decorationOptions) { let typeKey = decorationTypeKey; if (decorationOption.renderOptions) { - // identify custom reder options by a hash code over all keys and values + // identify custom render options by a hash code over all keys and values // For custom render options register a decoration type if necessary const subType = hash(decorationOption.renderOptions).toString(16); // The fact that `decorationTypeKey` appears in the typeKey has no influence diff --git a/src/vs/editor/common/core/cursorColumns.ts b/src/vs/editor/common/core/cursorColumns.ts index 6f8cd6fbc72..669c38b43f5 100644 --- a/src/vs/editor/common/core/cursorColumns.ts +++ b/src/vs/editor/common/core/cursorColumns.ts @@ -116,7 +116,7 @@ export class CursorColumns { } /** - * ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns) + * ATTENTION: This works with 0-based columns (as opposed to the regular 1-based columns) * @see {@link CursorColumns} */ public static nextRenderTabStop(visibleColumn: number, tabSize: number): number { @@ -124,7 +124,7 @@ export class CursorColumns { } /** - * ATTENTION: This works with 0-based columns (as oposed to the regular 1-based columns) + * ATTENTION: This works with 0-based columns (as opposed to the regular 1-based columns) * @see {@link CursorColumns} */ public static nextIndentTabStop(visibleColumn: number, indentSize: number): number { From 7dbc6ecb931127cd25513edf58bb29ed25fe8155 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 10 Jul 2023 11:11:13 -0700 Subject: [PATCH 099/119] Fix #187447. Avoid npe for reading notebook pane (#187491) --- src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts index a58d4ebd9b0..2959ca1b13a 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts @@ -806,7 +806,7 @@ export function getNotebookEditorFromEditorPane(editorPane?: IEditorPane): INote const input = editorPane.input; if (input && isCompositeNotebookEditorInput(input)) { - return (editorPane.getControl() as { notebookEditor: INotebookEditor | undefined }).notebookEditor; + return (editorPane.getControl() as { notebookEditor: INotebookEditor | undefined } | undefined)?.notebookEditor; } return undefined; From babfe39bb73757136eeaa9c0ef1be5490124ee35 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 10 Jul 2023 11:21:15 -0700 Subject: [PATCH 100/119] Don't call fireSimulatedContinuedEvent if the debug adapter sent a Stopped event before the response of the next/stepIn/etc request (#187215) * Don't call fireSimulatedContinuedEvent if the debug adapter sent a Stopped event before the response of the next/stepIn/etc request Fix #185785 * Fix typo --- .../contrib/debug/browser/rawDebugSession.ts | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts index db8cd73120e..c7201795adf 100644 --- a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts @@ -76,6 +76,7 @@ export class RawDebugSession implements IDisposable { // DA events private readonly _onDidExitAdapter = new Emitter(); private debugAdapter: IDebugAdapter | null; + private stoppedSinceLastStep = false; private toDispose: IDisposable[] = []; @@ -122,6 +123,7 @@ export class RawDebugSession implements IDisposable { break; case 'stopped': this.didReceiveStoppedEvent = true; // telemetry: remember that debugger stopped successfully + this.stoppedSinceLastStep = true; this._onDidStop.fire(event); break; case 'continued': @@ -326,29 +328,41 @@ export class RawDebugSession implements IDisposable { } async next(args: DebugProtocol.NextArguments): Promise { + this.stoppedSinceLastStep = false; const response = await this.send('next', args); - this.fireSimulatedContinuedEvent(args.threadId); + if (!this.stoppedSinceLastStep) { + this.fireSimulatedContinuedEvent(args.threadId); + } return response; } async stepIn(args: DebugProtocol.StepInArguments): Promise { + this.stoppedSinceLastStep = false; const response = await this.send('stepIn', args); - this.fireSimulatedContinuedEvent(args.threadId); + if (!this.stoppedSinceLastStep) { + this.fireSimulatedContinuedEvent(args.threadId); + } return response; } async stepOut(args: DebugProtocol.StepOutArguments): Promise { + this.stoppedSinceLastStep = false; const response = await this.send('stepOut', args); - this.fireSimulatedContinuedEvent(args.threadId); + if (!this.stoppedSinceLastStep) { + this.fireSimulatedContinuedEvent(args.threadId); + } return response; } async continue(args: DebugProtocol.ContinueArguments): Promise { + this.stoppedSinceLastStep = false; const response = await this.send('continue', args); if (response && response.body && response.body.allThreadsContinued !== undefined) { this.allThreadsContinued = response.body.allThreadsContinued; } - this.fireSimulatedContinuedEvent(args.threadId, this.allThreadsContinued); + if (!this.stoppedSinceLastStep) { + this.fireSimulatedContinuedEvent(args.threadId, this.allThreadsContinued); + } return response; } @@ -380,8 +394,11 @@ export class RawDebugSession implements IDisposable { async restartFrame(args: DebugProtocol.RestartFrameArguments, threadId: number): Promise { if (this.capabilities.supportsRestartFrame) { + this.stoppedSinceLastStep = false; const response = await this.send('restartFrame', args); - this.fireSimulatedContinuedEvent(threadId); + if (!this.stoppedSinceLastStep) { + this.fireSimulatedContinuedEvent(threadId); + } return response; } return Promise.reject(new Error('restartFrame not supported')); @@ -484,8 +501,11 @@ export class RawDebugSession implements IDisposable { async stepBack(args: DebugProtocol.StepBackArguments): Promise { if (this.capabilities.supportsStepBack) { + this.stoppedSinceLastStep = false; const response = await this.send('stepBack', args); - this.fireSimulatedContinuedEvent(args.threadId); + if (!this.stoppedSinceLastStep) { + this.fireSimulatedContinuedEvent(args.threadId); + } return response; } return Promise.reject(new Error('stepBack not supported')); @@ -493,8 +513,11 @@ export class RawDebugSession implements IDisposable { async reverseContinue(args: DebugProtocol.ReverseContinueArguments): Promise { if (this.capabilities.supportsStepBack) { + this.stoppedSinceLastStep = false; const response = await this.send('reverseContinue', args); - this.fireSimulatedContinuedEvent(args.threadId); + if (!this.stoppedSinceLastStep) { + this.fireSimulatedContinuedEvent(args.threadId); + } return response; } return Promise.reject(new Error('reverseContinue not supported')); @@ -509,8 +532,11 @@ export class RawDebugSession implements IDisposable { async goto(args: DebugProtocol.GotoArguments): Promise { if (this.capabilities.supportsGotoTargetsRequest) { + this.stoppedSinceLastStep = false; const response = await this.send('goto', args); - this.fireSimulatedContinuedEvent(args.threadId); + if (!this.stoppedSinceLastStep) { + this.fireSimulatedContinuedEvent(args.threadId); + } return response; } From 5822d97cb362ff4d219bbb6231d6b0132fe31732 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 10 Jul 2023 11:37:19 -0700 Subject: [PATCH 101/119] Bump milestones in issue notebooks (#187494) --- .vscode/notebooks/api.github-issues | 2 +- .vscode/notebooks/endgame.github-issues | 2 +- .vscode/notebooks/my-endgame.github-issues | 2 +- .vscode/notebooks/verification.github-issues | 2 +- .vscode/notebooks/vscode-dev.github-issues | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.vscode/notebooks/api.github-issues b/.vscode/notebooks/api.github-issues index 682cd02911b..1d39b63dd9f 100644 --- a/.vscode/notebooks/api.github-issues +++ b/.vscode/notebooks/api.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"June 2023\"" + "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"July 2023\"" }, { "kind": 1, diff --git a/.vscode/notebooks/endgame.github-issues b/.vscode/notebooks/endgame.github-issues index e0a1b766d76..60c8c5a6aec 100644 --- a/.vscode/notebooks/endgame.github-issues +++ b/.vscode/notebooks/endgame.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"June 2023\"" + "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"July 2023\"" }, { "kind": 1, diff --git a/.vscode/notebooks/my-endgame.github-issues b/.vscode/notebooks/my-endgame.github-issues index 74316c9367e..92fddeef220 100644 --- a/.vscode/notebooks/my-endgame.github-issues +++ b/.vscode/notebooks/my-endgame.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"June 2023\"\n\n$MINE=assignee:@me" + "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n\n$MILESTONE=milestone:\"July 2023\"\n\n$MINE=assignee:@me" }, { "kind": 1, diff --git a/.vscode/notebooks/verification.github-issues b/.vscode/notebooks/verification.github-issues index f3c54eab361..43ff3912c72 100644 --- a/.vscode/notebooks/verification.github-issues +++ b/.vscode/notebooks/verification.github-issues @@ -12,7 +12,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n$milestone=milestone:\"June 2023\"" + "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n repo:microsoft/vscode-remote-tunnels\n$milestone=milestone:\"July 2023\"" }, { "kind": 1, diff --git a/.vscode/notebooks/vscode-dev.github-issues b/.vscode/notebooks/vscode-dev.github-issues index ffcd620be52..65cfed180a5 100644 --- a/.vscode/notebooks/vscode-dev.github-issues +++ b/.vscode/notebooks/vscode-dev.github-issues @@ -2,7 +2,7 @@ { "kind": 2, "language": "github-issues", - "value": "$milestone=milestone:\"June 2023\"" + "value": "$milestone=milestone:\"July 2023\"" }, { "kind": 1, From 84fc1ff4b3894aa9304b11632136c486a667dadd Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Mon, 10 Jul 2023 11:40:55 -0700 Subject: [PATCH 102/119] testing: fix memory leak during unit tests (#187488) For #187471 --- src/vs/workbench/api/test/browser/extHostTesting.test.ts | 1 + src/vs/workbench/contrib/debug/test/browser/callStack.test.ts | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/vs/workbench/api/test/browser/extHostTesting.test.ts b/src/vs/workbench/api/test/browser/extHostTesting.test.ts index f4e445ae444..92970a9a9cd 100644 --- a/src/vs/workbench/api/test/browser/extHostTesting.test.ts +++ b/src/vs/workbench/api/test/browser/extHostTesting.test.ts @@ -93,6 +93,7 @@ suite('ExtHost Testing', () => { teardown(() => { single.dispose(); + sinon.restore(); }); suite('OwnedTestCollection', () => { diff --git a/src/vs/workbench/contrib/debug/test/browser/callStack.test.ts b/src/vs/workbench/contrib/debug/test/browser/callStack.test.ts index 0cb9462b00c..c6158426173 100644 --- a/src/vs/workbench/contrib/debug/test/browser/callStack.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/callStack.test.ts @@ -76,6 +76,10 @@ suite('Debug - CallStack', () => { mockRawSession = new MockRawSession(); }); + teardown(() => { + sinon.restore(); + }); + // Threads test('threads simple', () => { From e5782fe70ae548fc9d589ea83bb7189b03263cf3 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 10 Jul 2023 12:31:39 -0700 Subject: [PATCH 103/119] fix #185960 --- .../tasks/browser/abstractTaskService.ts | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 12fc22bd477..e8ec458751d 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -2936,22 +2936,33 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); }); }; - + let globTasksDetected = false; // First check for globs before checking for the default tasks of the task group const absoluteURI = EditorResourceAccessor.getOriginalUri(this._editorService.activeEditor); if (absoluteURI) { const workspaceFolder = this._contextService.getWorkspaceFolder(absoluteURI); - // fallback to absolute path of the file if it is not in a workspace or relative path cannot be found - const relativePath = workspaceFolder?.uri ? (resources.relativePath(workspaceFolder.uri, absoluteURI) ?? absoluteURI.path) : absoluteURI.path; + if (workspaceFolder) { + const config = this._getConfiguration(workspaceFolder); + globTasksDetected = ((config?.config?.tasks) || []).filter(task => task.group && typeof task.group !== 'string' && typeof task.group.isDefault === 'string').length > 0; + + if (globTasksDetected) { + // fallback to absolute path of the file if it is not in a workspace or relative path cannot be found + const relativePath = workspaceFolder?.uri ? (resources.relativePath(workspaceFolder.uri, absoluteURI) ?? absoluteURI.path) : absoluteURI.path; + + taskGroupTasks = await this._findWorkspaceTasks((task) => { + const currentTaskGroup = task.configurationProperties.group; + if (currentTaskGroup && typeof currentTaskGroup !== 'string' && typeof currentTaskGroup.isDefault === 'string') { + return (currentTaskGroup._id === taskGroup._id && glob.match(currentTaskGroup.isDefault, relativePath)); + } - taskGroupTasks = await this._findWorkspaceTasks((task) => { - const currentTaskGroup = task.configurationProperties.group; - if (currentTaskGroup && typeof currentTaskGroup !== 'string' && typeof currentTaskGroup.isDefault === 'string') { - return (currentTaskGroup._id === taskGroup._id && glob.match(currentTaskGroup.isDefault, relativePath)); + return false; + }); } + } + } - return false; - }); + if (!globTasksDetected && taskGroupTasks.length === 0) { + taskGroupTasks = await this._findWorkspaceTasksInGroup(TaskGroup.Build, true); } const handleMultipleTasks = (areGlobTasks: boolean) => { @@ -2991,7 +3002,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer // If there's multiple globs that match we want to show the quick picker for those tasks // We will need to call splitPerGroupType putting globs in defaults and the remaining tasks in none. // We don't need to carry on after here - if (taskGroupTasks.length > 1) { + if (globTasksDetected && taskGroupTasks.length > 1) { return handleMultipleTasks(true); } From 199fd02fc1605ff46a0184d814caa827159e7633 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Mon, 10 Jul 2023 12:55:02 -0700 Subject: [PATCH 104/119] add roaming changes to search history (#187330) --- src/vs/base/browser/ui/inputbox/inputBox.ts | 13 ++++++ .../search/browser/patternInputWidget.ts | 4 ++ .../contrib/search/browser/searchView.ts | 40 ++++++++++++++++--- .../contrib/search/browser/searchWidget.ts | 8 ++++ .../search/common/searchHistoryService.ts | 4 +- 5 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 1dcc1751ff8..af621b9047e 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -685,6 +685,19 @@ export class HistoryInputBox extends InputBox implements IHistoryNavigationWidge } } + public prependHistory(restoredHistory: string[]): void { + const newHistory = this.getHistory(); + this.clearHistory(); + + restoredHistory.forEach((item) => { + this.history.add(item); + }); + + newHistory.forEach(item => { + this.history.add(item); + }); + } + public getHistory(): string[] { return this.history.getHistory(); } diff --git a/src/vs/workbench/contrib/search/browser/patternInputWidget.ts b/src/vs/workbench/contrib/search/browser/patternInputWidget.ts index 92de68be38d..6d167046d37 100644 --- a/src/vs/workbench/contrib/search/browser/patternInputWidget.ts +++ b/src/vs/workbench/contrib/search/browser/patternInputWidget.ts @@ -116,6 +116,10 @@ export class PatternInputWidget extends Widget { this.inputBox.clearHistory(); } + prependHistory(history: string[]): void { + this.inputBox.prependHistory(history); + } + clear(): void { this.setValue(''); } diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index eeaed2cc943..44d8993bf19 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -70,7 +70,7 @@ import { SearchWidget } from 'vs/workbench/contrib/search/browser/searchWidget'; import * as Constants from 'vs/workbench/contrib/search/common/constants'; import { IReplaceService } from 'vs/workbench/contrib/search/browser/replace'; import { getOutOfWorkspaceEditorResources, SearchStateKey, SearchUIState } from 'vs/workbench/contrib/search/common/search'; -import { ISearchHistoryService, ISearchHistoryValues } from 'vs/workbench/contrib/search/common/searchHistoryService'; +import { ISearchHistoryService, ISearchHistoryValues, SearchHistoryService } from 'vs/workbench/contrib/search/common/searchHistoryService'; import { FileMatch, FileMatchOrMatch, FolderMatch, FolderMatchWithResource, IChangeEvent, ISearchWorkbenchService, Match, MatchInNotebook, RenderableMatch, searchMatchComparer, SearchModel, SearchResult } from 'vs/workbench/contrib/search/browser/searchModel'; import { createEditorFromSearchResult } from 'vs/workbench/contrib/searchEditor/browser/searchEditorActions'; import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; @@ -185,7 +185,7 @@ export class SearchView extends ViewPane { @IContextMenuService contextMenuService: IContextMenuService, @IAccessibilityService private readonly accessibilityService: IAccessibilityService, @IKeybindingService keybindingService: IKeybindingService, - @IStorageService storageService: IStorageService, + @IStorageService private readonly storageService: IStorageService, @IOpenerService openerService: IOpenerService, @ITelemetryService telemetryService: ITelemetryService, @INotebookService private readonly notebookService: INotebookService, @@ -257,6 +257,30 @@ export class SearchView extends ViewPane { this.isTreeLayoutViewVisible = this.viewletState['view.treeLayout'] ?? (this.searchConfig.defaultViewMode === ViewMode.Tree); this._refreshResultsScheduler = this._register(new RunOnceScheduler(this._updateResults.bind(this), 80)); + + // storage service listener for for roaming changes + this._register(this.storageService.onWillSaveState(() => { + this._saveSearchHistoryService(); + })); + + this._register(this.storageService.onDidChangeValue((v) => { + if (v.key === SearchHistoryService.SEARCH_HISTORY_KEY) { + const restoredHistory = this.searchHistoryService.load(); + + if (restoredHistory.include) { + this.inputPatternIncludes.prependHistory(restoredHistory.include); + } + if (restoredHistory.exclude) { + this.inputPatternExcludes.prependHistory(restoredHistory.exclude); + } + if (restoredHistory.search) { + this.searchWidget.prependSearchHistory(restoredHistory.search); + } + if (restoredHistory.replace) { + this.searchWidget.prependReplaceHistory(restoredHistory.replace); + } + } + })); } get isTreeLayoutViewVisible(): boolean { @@ -2038,6 +2062,14 @@ export class SearchView extends ViewPane { this.viewletState['view.treeLayout'] = this.isTreeLayoutViewVisible; this.viewletState['query.replaceText'] = isReplaceShown && this.searchWidget.getReplaceValue(); + this._saveSearchHistoryService(); + + this.memento.saveMemento(); + + super.saveState(); + } + + private _saveSearchHistoryService() { const history: ISearchHistoryValues = Object.create(null); const searchHistory = this.searchWidget.getSearchHistory(); @@ -2061,10 +2093,6 @@ export class SearchView extends ViewPane { } this.searchHistoryService.save(history); - - this.memento.saveMemento(); - - super.saveState(); } private async retrieveFileStats(): Promise { diff --git a/src/vs/workbench/contrib/search/browser/searchWidget.ts b/src/vs/workbench/contrib/search/browser/searchWidget.ts index ea705b2a2f8..6062d87937d 100644 --- a/src/vs/workbench/contrib/search/browser/searchWidget.ts +++ b/src/vs/workbench/contrib/search/browser/searchWidget.ts @@ -300,6 +300,14 @@ export class SearchWidget extends Widget { return this.replaceInput?.inputBox.getHistory() ?? []; } + prependSearchHistory(history: string[]): void { + this.searchInput?.inputBox.prependHistory(history); + } + + prependReplaceHistory(history: string[]): void { + this.replaceInput?.inputBox.prependHistory(history); + } + clearHistory(): void { this.searchInput?.inputBox.clearHistory(); this.replaceInput?.inputBox.clearHistory(); diff --git a/src/vs/workbench/contrib/search/common/searchHistoryService.ts b/src/vs/workbench/contrib/search/common/searchHistoryService.ts index 4e864e7c171..1c6640363af 100644 --- a/src/vs/workbench/contrib/search/common/searchHistoryService.ts +++ b/src/vs/workbench/contrib/search/common/searchHistoryService.ts @@ -28,7 +28,7 @@ export interface ISearchHistoryValues { export class SearchHistoryService implements ISearchHistoryService { declare readonly _serviceBrand: undefined; - private static readonly SEARCH_HISTORY_KEY = 'workbench.search.history'; + public static readonly SEARCH_HISTORY_KEY = 'workbench.search.history'; private readonly _onDidClearHistory = new Emitter(); readonly onDidClearHistory: Event = this._onDidClearHistory.event; @@ -61,7 +61,7 @@ export class SearchHistoryService implements ISearchHistoryService { if (isEmptyObject(history)) { this.storageService.remove(SearchHistoryService.SEARCH_HISTORY_KEY, StorageScope.WORKSPACE); } else { - this.storageService.store(SearchHistoryService.SEARCH_HISTORY_KEY, JSON.stringify(history), StorageScope.WORKSPACE, StorageTarget.MACHINE); + this.storageService.store(SearchHistoryService.SEARCH_HISTORY_KEY, JSON.stringify(history), StorageScope.WORKSPACE, StorageTarget.USER); } } } From a0208c89dfe806278dc116d2855018bea6e4de44 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 10 Jul 2023 12:56:28 -0700 Subject: [PATCH 105/119] Pick up latest TS nightly for building VS Code (#187500) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7f011f15bbd..4f04e9ddb1d 100644 --- a/package.json +++ b/package.json @@ -210,7 +210,7 @@ "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "tsec": "0.2.7", - "typescript": "^5.2.0-dev.20230621", + "typescript": "^5.2.0-dev.20230710", "typescript-formatter": "7.1.0", "underscore": "^1.12.1", "util": "^0.12.4", diff --git a/yarn.lock b/yarn.lock index 13650bd8310..e8975eef7f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10041,10 +10041,10 @@ typescript@^4.7.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== -typescript@^5.2.0-dev.20230621: - version "5.2.0-dev.20230621" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.0-dev.20230621.tgz#fc61be8c6448dce096aa5df1abda7966d730999d" - integrity sha512-8iIehsqwx8TrzBcPWAuXZ0Z4wF/+0CmwdbibftaivqXJlD3V4qWr26hn67r/UT/VNm67iO86XN45F8Viivvobw== +typescript@^5.2.0-dev.20230710: + version "5.2.0-dev.20230710" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.0-dev.20230710.tgz#6e42862d126c2c7b4ce14ce6124396561dd808c0" + integrity sha512-D4u4/pfdrIi94+F+iVzxzuzCk8bE/cbe4jng6Sce2Y1szj/QiBqN43X5lMrIbMR9Kb1G2AdWzYPrcNv/ButJGA== typical@^4.0.0: version "4.0.0" From 011ac2c103a032c754d33e5b75b29aa1613d5569 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 10 Jul 2023 13:03:41 -0700 Subject: [PATCH 106/119] Pick up TS 5.1.6 (#187495) For #187493 --- extensions/package.json | 2 +- extensions/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/package.json b/extensions/package.json index 8ab93875293..f5f0b7e6197 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -4,7 +4,7 @@ "license": "MIT", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "5.1.3" + "typescript": "5.1.6" }, "scripts": { "postinstall": "node ./postinstall.mjs" diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 50070eb668f..18507f58b59 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -228,10 +228,10 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -typescript@5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" - integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== +typescript@5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== vscode-grammar-updater@^1.1.0: version "1.1.0" From 6aca75d9d09f7d9d32c18e58c836067f2d420495 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 10 Jul 2023 13:04:03 -0700 Subject: [PATCH 107/119] Fix markdown preview classes (#187501) For #187234 Got introduced through a bad PR change. Makes more sense to move this styling to the css file instead --- extensions/markdown-language-features/media/markdown.css | 1 + .../markdown-language-features/src/preview/documentRenderer.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/markdown-language-features/media/markdown.css b/extensions/markdown-language-features/media/markdown.css index 896531fdcc8..809a8bf0600 100644 --- a/extensions/markdown-language-features/media/markdown.css +++ b/extensions/markdown-language-features/media/markdown.css @@ -9,6 +9,7 @@ html, body { padding: 0 26px; line-height: var(--markdown-line-height, 22px); word-wrap: break-word; + overscroll-behavior-x: none; } body { diff --git a/extensions/markdown-language-features/src/preview/documentRenderer.ts b/extensions/markdown-language-features/src/preview/documentRenderer.ts index 57ec4ee0051..331fb5566a0 100644 --- a/extensions/markdown-language-features/src/preview/documentRenderer.ts +++ b/extensions/markdown-language-features/src/preview/documentRenderer.ts @@ -103,7 +103,7 @@ export class MdDocumentRenderer { ${this._getStyles(resourceProvider, sourceUri, config, imageInfo)} - + ${body.html} ${this._getScripts(resourceProvider, nonce)} From 13991f66032b18133c42e824dc2a4062ae781c32 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 10 Jul 2023 13:30:58 -0700 Subject: [PATCH 108/119] clean up and add comment --- .../tasks/browser/abstractTaskService.ts | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index e8ec458751d..75bf1a9952d 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -2908,7 +2908,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer title: strings.fetching }; const promise = (async () => { - let taskGroupTasks: (Task | ConfiguringTask)[] = []; + let groupTasks: (Task | ConfiguringTask)[] = []; async function runSingleTask(task: Task | undefined, problemMatcherOptions: IProblemMatcherRunOptions | undefined, that: AbstractTaskService) { that.run(task, problemMatcherOptions, TaskRunSource.User).then(undefined, reason => { @@ -2942,27 +2942,29 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (absoluteURI) { const workspaceFolder = this._contextService.getWorkspaceFolder(absoluteURI); if (workspaceFolder) { - const config = this._getConfiguration(workspaceFolder); - globTasksDetected = ((config?.config?.tasks) || []).filter(task => task.group && typeof task.group !== 'string' && typeof task.group.isDefault === 'string').length > 0; - - if (globTasksDetected) { - // fallback to absolute path of the file if it is not in a workspace or relative path cannot be found - const relativePath = workspaceFolder?.uri ? (resources.relativePath(workspaceFolder.uri, absoluteURI) ?? absoluteURI.path) : absoluteURI.path; - - taskGroupTasks = await this._findWorkspaceTasks((task) => { - const currentTaskGroup = task.configurationProperties.group; - if (currentTaskGroup && typeof currentTaskGroup !== 'string' && typeof currentTaskGroup.isDefault === 'string') { - return (currentTaskGroup._id === taskGroup._id && glob.match(currentTaskGroup.isDefault, relativePath)); - } + const configuredTasks = this._getConfiguration(workspaceFolder)?.config?.tasks; + if (configuredTasks) { + globTasksDetected = configuredTasks.filter(task => task.group && typeof task.group !== 'string' && typeof task.group.isDefault === 'string').length > 0; + // This will activate extensions, so only do so if necessary #185960 + if (globTasksDetected) { + // Fallback to absolute path of the file if it is not in a workspace or relative path cannot be found + const relativePath = workspaceFolder?.uri ? (resources.relativePath(workspaceFolder.uri, absoluteURI) ?? absoluteURI.path) : absoluteURI.path; + + groupTasks = await this._findWorkspaceTasks((task) => { + const currentTaskGroup = task.configurationProperties.group; + if (currentTaskGroup && typeof currentTaskGroup !== 'string' && typeof currentTaskGroup.isDefault === 'string') { + return (currentTaskGroup._id === taskGroup._id && glob.match(currentTaskGroup.isDefault, relativePath)); + } - return false; - }); + return false; + }); + } } } } - if (!globTasksDetected && taskGroupTasks.length === 0) { - taskGroupTasks = await this._findWorkspaceTasksInGroup(TaskGroup.Build, true); + if (!globTasksDetected && groupTasks.length === 0) { + groupTasks = await this._findWorkspaceTasksInGroup(TaskGroup.Build, true); } const handleMultipleTasks = (areGlobTasks: boolean) => { @@ -2995,25 +2997,25 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }; // A single default glob task was returned, just run it directly - if (taskGroupTasks.length === 1) { - return resolveTaskAndRun(taskGroupTasks[0]); + if (groupTasks.length === 1) { + return resolveTaskAndRun(groupTasks[0]); } // If there's multiple globs that match we want to show the quick picker for those tasks // We will need to call splitPerGroupType putting globs in defaults and the remaining tasks in none. // We don't need to carry on after here - if (globTasksDetected && taskGroupTasks.length > 1) { + if (globTasksDetected && groupTasks.length > 1) { return handleMultipleTasks(true); } // If no globs are found or matched fallback to checking for default tasks of the task group - if (!taskGroupTasks.length) { - taskGroupTasks = await this._findWorkspaceTasksInGroup(taskGroup, false); + if (!groupTasks.length) { + groupTasks = await this._findWorkspaceTasksInGroup(taskGroup, false); } // A single default task was returned, just run it directly - if (taskGroupTasks.length === 1) { - return resolveTaskAndRun(taskGroupTasks[0]); + if (groupTasks.length === 1) { + return resolveTaskAndRun(groupTasks[0]); } // Multiple default tasks returned, show the quickPicker From 261a75e3a4800d25ef6c2a03f52fb9a60c4ea65d Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Mon, 10 Jul 2023 13:41:50 -0700 Subject: [PATCH 109/119] add missing sinon restore calls in search (#187489) * add missing sinon restore calls * use `teardown(() => sinon.restore())` in search tests to restore stubs --- .../search/test/browser/searchModel.test.ts | 27 +++++-------------- .../search/test/browser/searchResult.test.ts | 5 ++-- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts b/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts index e7254f5fb73..c6cfdd8c5ff 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchModel.test.ts @@ -60,7 +60,6 @@ const lineOneRange = new OneLineRange(1, 0, 1); suite('SearchModel', () => { let instantiationService: TestInstantiationService; - let restoreStubs: sinon.SinonStub[]; const testSearchStats: IFileSearchStats = { fromCache: false, @@ -80,7 +79,6 @@ suite('SearchModel', () => { ]; setup(() => { - restoreStubs = []; instantiationService = new TestInstantiationService(); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(ILabelService, { getUriBasenameLabel: (uri: URI) => '' }); @@ -92,11 +90,7 @@ suite('SearchModel', () => { instantiationService.stub(ILogService, new NullLogService()); }); - teardown(() => { - restoreStubs.forEach(element => { - element.restore(); - }); - }); + teardown(() => sinon.restore()); function searchServiceWithResults(results: IFileMatch[], complete: ISearchComplete | null = null): ISearchService { return { @@ -174,8 +168,7 @@ suite('SearchModel', () => { new TextSearchMatch('this is a test', new OneLineRange(1, 11, 15))), aRawMatch('/3', new TextSearchMatch('test', lineOneRange))]; const searchService = instantiationService.stub(ISearchService, searchServiceWithResults(results)); - const addContext = sinon.stub(CellMatch.prototype, 'addContext'); - restoreStubs.push(addContext); + sinon.stub(CellMatch.prototype, 'addContext'); const textSearch = sinon.spy(searchService, 'textSearch'); const mdInputCell = { @@ -264,8 +257,6 @@ suite('SearchModel', () => { scannedFiles: new ResourceSet([...localResults.keys()]), }); }); - restoreStubs.push(notebookSearch); - await model.search({ contentPattern: { pattern: 'test' }, type: QueryType.Text, folderQueries }); const actual = model.searchResult.matches(); @@ -329,7 +320,7 @@ suite('SearchModel', () => { test('Search Model: Search reports timed telemetry on search when progress is not called', () => { const target2 = sinon.spy(); - stub(nullEvent, 'stop', target2); + sinon.stub(nullEvent, 'stop').callsFake(target2); const target1 = sinon.stub().returns(nullEvent); instantiationService.stub(ITelemetryService, 'publicLog', target1); @@ -348,7 +339,7 @@ suite('SearchModel', () => { test('Search Model: Search reports timed telemetry on search when progress is called', () => { const target2 = sinon.spy(); - stub(nullEvent, 'stop', target2); + sinon.stub(nullEvent, 'stop').callsFake(target2); const target1 = sinon.stub().returns(nullEvent); instantiationService.stub(ITelemetryService, 'publicLog', target1); @@ -372,7 +363,7 @@ suite('SearchModel', () => { test('Search Model: Search reports timed telemetry on search when error is called', () => { const target2 = sinon.spy(); - stub(nullEvent, 'stop', target2); + sinon.stub(nullEvent, 'stop').callsFake(target2); const target1 = sinon.stub().returns(nullEvent); instantiationService.stub(ITelemetryService, 'publicLog', target1); @@ -392,7 +383,7 @@ suite('SearchModel', () => { test('Search Model: Search reports timed telemetry on search when error is cancelled error', () => { const target2 = sinon.spy(); - stub(nullEvent, 'stop', target2); + sinon.stub(nullEvent, 'stop').callsFake(target2); const target1 = sinon.stub().returns(nullEvent); instantiationService.stub(ITelemetryService, 'publicLog', target1); @@ -491,12 +482,6 @@ suite('SearchModel', () => { return { resource: createFileUriFromPathFromRoot(resource), cellResults: cells }; } - function stub(arg1: any, arg2: any, arg3: any): sinon.SinonStub { - const stub = sinon.stub(arg1, arg2).callsFake(arg3); - restoreStubs.push(stub); - return stub; - } - function stubModelService(instantiationService: TestInstantiationService): IModelService { instantiationService.stub(IThemeService, new TestThemeService()); const config = new TestConfigurationService(); diff --git a/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts b/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts index a65a4f7c43c..30e273f7096 100644 --- a/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts +++ b/src/vs/workbench/contrib/search/test/browser/searchResult.test.ts @@ -51,6 +51,8 @@ suite('SearchResult', () => { instantiationService.stub(ILogService, new NullLogService()); }); + teardown(() => sinon.restore()); + test('Line Match', function () { const fileMatch = aFileMatch('folder/file.txt', null!); const lineMatch = new Match(fileMatch, ['0 foo bar'], new OneLineRange(0, 2, 5), new OneLineRange(1, 0, 5)); @@ -228,7 +230,7 @@ suite('SearchResult', () => { const cell1 = { cellKind: CellKind.Code } as ICellViewModel; const cell2 = { cellKind: CellKind.Code } as ICellViewModel; - const addContext = sinon.stub(CellMatch.prototype, 'addContext'); + sinon.stub(CellMatch.prototype, 'addContext'); const addFileMatch = sinon.spy(FolderMatch.prototype, "addFileMatch"); const fileMatch1 = aRawFileMatchWithCells('/1', @@ -263,7 +265,6 @@ suite('SearchResult', () => { assert.deepStrictEqual(fileMatch1.cellResults[0].webviewResults, (addFileMatch.getCall(0).args[0][0] as IFileMatchWithCells).cellResults[0].webviewResults); assert.deepStrictEqual(fileMatch2.cellResults[0].contentResults, (addFileMatch.getCall(0).args[0][1] as IFileMatchWithCells).cellResults[0].contentResults); assert.deepStrictEqual(fileMatch2.cellResults[0].webviewResults, (addFileMatch.getCall(0).args[0][1] as IFileMatchWithCells).cellResults[0].webviewResults); - addContext.restore(); }); test('Dispose disposes matches', function () { From f07abd224bf29609d00cb3b56cbbbf5ce0a409e4 Mon Sep 17 00:00:00 2001 From: Meghan Kulkarni Date: Mon, 10 Jul 2023 14:11:49 -0700 Subject: [PATCH 110/119] Make markdown link pasting feature smarter (#187170) * making markdown link pasting feature smarter * Update settings description Co-authored-by: Joyce Er * made checkPaste more concise * won't paste md link in fenced code or math --------- Co-authored-by: Joyce Er --- .../markdown-language-features/package.json | 14 ++++- .../package.nls.json | 5 +- .../src/commands/insertResource.ts | 4 +- .../copyFiles/copyPasteLinks.ts | 5 +- .../src/languageFeatures/copyFiles/shared.ts | 51 +++++++++++++++---- 5 files changed, 62 insertions(+), 17 deletions(-) diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 1f4fcbc6034..1afabaf9dff 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -499,10 +499,20 @@ ] }, "markdown.editor.pasteUrlAsFormattedLink.enabled": { - "type": "boolean", + "type": "string", "scope": "resource", "markdownDescription": "%configuration.markdown.editor.pasteUrlAsFormattedLink.enabled%", - "default": true + "default":"smart", + "enum": [ + "always", + "smart", + "never" + ], + "markdownEnumDescriptions": [ + "%configuration.pasteUrlAsFormattedLink.always%", + "%configuration.pasteUrlAsFormattedLink.smart%", + "%configuration.pasteUrlAsFormattedLink.never%" + ] }, "markdown.validate.enabled": { "type": "boolean", diff --git a/extensions/markdown-language-features/package.nls.json b/extensions/markdown-language-features/package.nls.json index e39e597b02f..0468fbf1d79 100644 --- a/extensions/markdown-language-features/package.nls.json +++ b/extensions/markdown-language-features/package.nls.json @@ -41,9 +41,12 @@ "configuration.markdown.editor.drop.copyIntoWorkspace": "Controls if files outside of the workspace that are dropped into a Markdown editor should be copied into the workspace.\n\nUse `#markdown.copyFiles.destination#` to configure where copied dropped files should be created", "configuration.markdown.editor.filePaste.enabled": "Enable pasting files into a Markdown editor to create Markdown links. Requires enabling `#editor.pasteAs.enabled#`.", "configuration.markdown.editor.filePaste.copyIntoWorkspace": "Controls if files outside of the workspace that are pasted into a Markdown editor should be copied into the workspace.\n\nUse `#markdown.copyFiles.destination#` to configure where copied files should be created.", - "configuration.markdown.editor.pasteUrlAsFormattedLink.enabled": "Controls if a Markdown link is created when a URL is pasted into the Markdown editor. Requires enabling `#editor.pasteAs.enabled#`.", "configuration.copyIntoWorkspace.mediaFiles": "Try to copy external image and video files into the workspace.", "configuration.copyIntoWorkspace.never": "Do not copy external files into the workspace.", + "configuration.markdown.editor.pasteUrlAsFormattedLink.enabled": "Controls how a Markdown link is created when a URL is pasted into the Markdown editor. Requires enabling `#editor.pasteAs.enabled#`.", + "configuration.pasteUrlAsFormattedLink.always": "Always create a Markdown link when a URL is pasted into the Markdown editor.", + "configuration.pasteUrlAsFormattedLink.smart": "Does not create a Markdown link within a link snippet or code bracket.", + "configuration.pasteUrlAsFormattedLink.never": "Never create a Markdown link when a URL is pasted into the Markdown editor.", "configuration.markdown.validate.enabled.description": "Enable all error reporting in Markdown files.", "configuration.markdown.validate.referenceLinks.enabled.description": "Validate reference links in Markdown files, for example: `[link][ref]`. Requires enabling `#markdown.validate.enabled#`.", "configuration.markdown.validate.fragmentLinks.enabled.description": "Validate fragment links to headers in the current Markdown file, for example: `[link](#header)`. Requires enabling `#markdown.validate.enabled#`.", diff --git a/extensions/markdown-language-features/src/commands/insertResource.ts b/extensions/markdown-language-features/src/commands/insertResource.ts index 2e7b97c3048..da50c83c991 100644 --- a/extensions/markdown-language-features/src/commands/insertResource.ts +++ b/extensions/markdown-language-features/src/commands/insertResource.ts @@ -76,10 +76,10 @@ async function insertLink(activeEditor: vscode.TextEditor, selectedFiles: vscode await vscode.workspace.applyEdit(edit); } -function createInsertLinkEdit(activeEditor: vscode.TextEditor, selectedFiles: vscode.Uri[], insertAsMedia: boolean, title = '', placeholderValue = 0) { +function createInsertLinkEdit(activeEditor: vscode.TextEditor, selectedFiles: vscode.Uri[], insertAsMedia: boolean, title = '', placeholderValue = 0, smartPaste = false) { const snippetEdits = coalesce(activeEditor.selections.map((selection, i): vscode.SnippetTextEdit | undefined => { const selectionText = activeEditor.document.getText(selection); - const snippet = createUriListSnippet(activeEditor.document, selectedFiles, title, placeholderValue, { + const snippet = createUriListSnippet(activeEditor.document, selectedFiles, title, placeholderValue, smartPaste, { insertAsMedia, placeholderText: selectionText, placeholderStartIndex: (i + 1) * selectedFiles.length, diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyPasteLinks.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyPasteLinks.ts index 313a3916688..90755d990fc 100644 --- a/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyPasteLinks.ts +++ b/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyPasteLinks.ts @@ -5,7 +5,6 @@ import * as vscode from 'vscode'; import { getMarkdownLink } from './shared'; - class PasteLinkEditProvider implements vscode.DocumentPasteEditProvider { readonly id = 'insertMarkdownLink'; @@ -15,8 +14,8 @@ class PasteLinkEditProvider implements vscode.DocumentPasteEditProvider { dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken, ): Promise { - const enabled = vscode.workspace.getConfiguration('markdown', document).get('editor.pasteUrlAsFormattedLink.enabled', true); - if (!enabled) { + const enabled = vscode.workspace.getConfiguration('markdown', document).get<'always' | 'smart' | 'never'>('editor.pasteUrlAsFormattedLink.enabled', 'smart'); + if (enabled === 'never') { return; } diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts index 28a86a22d70..f40fea3556f 100644 --- a/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts +++ b/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts @@ -65,15 +65,26 @@ export async function getMarkdownLink(document: vscode.TextDocument, ranges: rea if (ranges.length === 0) { return; } + const enabled = vscode.workspace.getConfiguration('markdown', document).get<'always' | 'smart' | 'never'>('editor.pasteUrlAsFormattedLink.enabled', 'always'); const edits: vscode.SnippetTextEdit[] = []; let placeHolderValue: number = ranges.length; let label: string = ''; + let smartPaste: boolean = false; for (let i = 0; i < ranges.length; i++) { - const snippet = await tryGetUriListSnippet(document, urlList, token, document.getText(ranges[i]), placeHolderValue); + if (enabled === 'smart') { + const inMarkdownLink = checkPaste(document, ranges, /\[([^\]]*)\]\(([^)]*)\)/g, i); + const inFencedCode = checkPaste(document, ranges, /^```[\s\S]*?```$/gm, i); + const inFencedMath = checkPaste(document, ranges, /^\$\$[\s\S]*?\$\$$/gm, i); + smartPaste = (inMarkdownLink || inFencedCode || inFencedMath); + } + + const snippet = await tryGetUriListSnippet(document, urlList, token, document.getText(ranges[i]), placeHolderValue, smartPaste); if (!snippet) { return; } + + smartPaste = false; placeHolderValue--; edits.push(new vscode.SnippetTextEdit(ranges[i], snippet.snippet)); label = snippet.label; @@ -85,7 +96,20 @@ export async function getMarkdownLink(document: vscode.TextDocument, ranges: rea return { additionalEdits, label }; } -export async function tryGetUriListSnippet(document: vscode.TextDocument, urlList: String, token: vscode.CancellationToken, title = '', placeHolderValue = 0): Promise<{ snippet: vscode.SnippetString; label: string } | undefined> { +function checkPaste(document: vscode.TextDocument, ranges: readonly vscode.Range[], regex: RegExp, index: number): boolean { + const rangeStartOffset = document.offsetAt(ranges[index].start); + const rangeEndOffset = document.offsetAt(ranges[index].end); + const matches = [...document.getText().matchAll(regex)]; + for (const match of matches) { + if (match.index !== undefined && rangeStartOffset > match.index && rangeEndOffset < match.index + match[0].length) { + return true; + } + } + + return false; +} + +export async function tryGetUriListSnippet(document: vscode.TextDocument, urlList: String, token: vscode.CancellationToken, title = '', placeHolderValue = 0, smartPaste = false): Promise<{ snippet: vscode.SnippetString; label: string } | undefined> { if (token.isCancellationRequested) { return undefined; } @@ -99,7 +123,7 @@ export async function tryGetUriListSnippet(document: vscode.TextDocument, urlLis } } - return createUriListSnippet(document, uris, title, placeHolderValue); + return createUriListSnippet(document, uris, title, placeHolderValue, smartPaste); } interface UriListSnippetOptions { @@ -122,6 +146,7 @@ export function createUriListSnippet( uris: readonly vscode.Uri[], title = '', placeholderValue = 0, + smartPaste = false, options?: UriListSnippetOptions, ): { snippet: vscode.SnippetString; label: string } | undefined { if (!uris.length) { @@ -164,13 +189,21 @@ export function createUriListSnippet( snippet.appendText(`](${escapeMarkdownLinkPath(mdPath)})`); } else { insertedLinkCount++; - snippet.appendText('['); - snippet.appendPlaceholder(escapeBrackets(title) || 'Title', placeholderValue); - if (externalUriSchemes.includes(uri.scheme)) { - const uriString = uri.toString(true); - snippet.appendText(`](${uriString})`); + if (smartPaste) { + if (externalUriSchemes.includes(uri.scheme)) { + snippet.appendText(uri.toString(true)); + } else { + snippet.appendText(escapeMarkdownLinkPath(mdPath)); + } } else { - snippet.appendText(`](${escapeMarkdownLinkPath(mdPath)})`); + snippet.appendText('['); + snippet.appendPlaceholder(escapeBrackets(title) || 'Title', placeholderValue); + if (externalUriSchemes.includes(uri.scheme)) { + const uriString = uri.toString(true); + snippet.appendText(`](${uriString})`); + } else { + snippet.appendText(`](${escapeMarkdownLinkPath(mdPath)})`); + } } } } From 1beeb2e113ddf014478124e1aae1c341cc55ee2e Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Mon, 10 Jul 2023 15:01:54 -0700 Subject: [PATCH 111/119] Repopulate slash command in chat input editor (#187207) * Repopulate slash command in chat input editor --- .../browser/contrib/chatInputEditorContrib.ts | 32 ++++++++++++++++++- .../contrib/chat/common/chatService.ts | 3 ++ .../contrib/chat/common/chatServiceImpl.ts | 9 ++++++ .../vscode.proposed.interactive.d.ts | 1 + 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts index 4dff6bbd72a..d869e5bed4f 100644 --- a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts +++ b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts @@ -21,6 +21,7 @@ import { IChatWidget, IChatWidgetService } from 'vs/workbench/contrib/chat/brows import { ChatWidget } from 'vs/workbench/contrib/chat/browser/chatWidget'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { ChatInputPart } from 'vs/workbench/contrib/chat/browser/chatInputPart'; +import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; const decorationDescription = 'chat'; const slashCommandPlaceholderDecorationType = 'chat-session-detail'; @@ -131,7 +132,36 @@ class InputEditorDecorations extends Disposable { } } -ChatWidget.CONTRIBS.push(InputEditorDecorations); +class InputEditorSlashCommandFollowups extends Disposable { + constructor( + private readonly widget: IChatWidget, + @IChatService private readonly chatService: IChatService + ) { + super(); + this._register(this.chatService.onDidCompleteSlashCommand(({ slashCommand, sessionId }) => this.repopulateSlashCommand(slashCommand, sessionId))); + } + + private async repopulateSlashCommand(slashCommand: string, sessionId: string) { + if (this.widget.viewModel?.sessionId !== sessionId) { + return; + } + + const slashCommands = await this.widget.getSlashCommands(); + + if (this.widget.inputEditor.getValue().trim().length !== 0) { + return; + } + + if (slashCommands?.find(c => c.command === slashCommand)?.shouldRepopulate) { + const value = `/${slashCommand} `; + this.widget.inputEditor.setValue(value); + this.widget.inputEditor.setPosition({ lineNumber: 1, column: value.length + 1 }); + + } + } +} + +ChatWidget.CONTRIBS.push(InputEditorDecorations, InputEditorSlashCommandFollowups); class SlashCommandCompletions extends Disposable { constructor( diff --git a/src/vs/workbench/contrib/chat/common/chatService.ts b/src/vs/workbench/contrib/chat/common/chatService.ts index 477f7118062..8acfa91959c 100644 --- a/src/vs/workbench/contrib/chat/common/chatService.ts +++ b/src/vs/workbench/contrib/chat/common/chatService.ts @@ -67,6 +67,7 @@ export interface ISlashCommandProvider { export interface ISlashCommand { command: string; + shouldRepopulate?: boolean; provider?: ISlashCommandProvider; sortText?: string; detail?: string; @@ -176,6 +177,8 @@ export const IChatService = createDecorator('IChatService'); export interface IChatService { _serviceBrand: undefined; transferredSessionId: string | undefined; + + onDidCompleteSlashCommand: Event<{ slashCommand: string; sessionId: string }>; registerProvider(provider: IChatProvider): IDisposable; registerSlashCommandProvider(provider: ISlashCommandProvider): IDisposable; getProviderInfos(): IChatProviderInfo[]; diff --git a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts index c15379f06c6..3c20b21d168 100644 --- a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts +++ b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts @@ -135,6 +135,9 @@ export class ChatService extends Disposable implements IChatService { private readonly _onDidPerformUserAction = this._register(new Emitter()); public readonly onDidPerformUserAction: Event = this._onDidPerformUserAction.event; + private readonly _onDidCompleteSlashCommand = this._register(new Emitter<{ slashCommand: string; sessionId: string }>()); + public readonly onDidCompleteSlashCommand = this._onDidCompleteSlashCommand.event; + constructor( @IStorageService private readonly storageService: IStorageService, @ILogService private readonly logService: ILogService, @@ -472,9 +475,15 @@ export class ChatService extends Disposable implements IChatService { Promise.resolve(provider.provideFollowups(model.session!, CancellationToken.None)).then(followups => { model.setFollowups(request, withNullAsUndefined(followups)); model.completeResponse(request); + if (usedSlashCommand?.command) { + this._onDidCompleteSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId }); + } }); } else { model.completeResponse(request); + if (usedSlashCommand?.command) { + this._onDidCompleteSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId }); + } } } }); diff --git a/src/vscode-dts/vscode.proposed.interactive.d.ts b/src/vscode-dts/vscode.proposed.interactive.d.ts index 916e425189c..79d6db91573 100644 --- a/src/vscode-dts/vscode.proposed.interactive.d.ts +++ b/src/vscode-dts/vscode.proposed.interactive.d.ts @@ -128,6 +128,7 @@ declare module 'vscode' { export interface InteractiveSessionSlashCommand { command: string; + shouldRepopulate?: boolean; kind: CompletionItemKind; detail?: string; } From 35be9af88eb6757f7db17b1fc3de2648ebf8c43d Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 10 Jul 2023 15:03:31 -0700 Subject: [PATCH 112/119] clean up accessible view --- .../accessibility/browser/accessibleView.ts | 14 +++++--------- .../browser/accessibility/accessibility.css | 4 ++-- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index a9b03c3ed6f..534d08414ea 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -24,8 +24,7 @@ import { SelectionClipboardContributionID } from 'vs/workbench/contrib/codeEdito import { getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions'; const enum DIMENSION_DEFAULT { - WIDTH = .6, - HEIGHT = 200 + WIDTH = 800 } export interface IAccessibleContentProvider { @@ -88,14 +87,15 @@ class AccessibleView extends Disposable { quickSuggestions: false, renderWhitespace: 'none', dropIntoEditor: { enabled: true }, - readOnly: true + readOnly: true, + fontFamily: 'var(--monaco-monospace-font)' }; this._editorWidget = this._register(this._instantiationService.createInstance(CodeEditorWidget, this._editorContainer, editorOptions, codeEditorWidgetOptions)); } show(provider: IAccessibleContentProvider): void { const delegate: IContextViewDelegate = { - getAnchor: () => this._editorContainer, + getAnchor: () => { return { x: (window.innerWidth / 2) - (DIMENSION_DEFAULT.WIDTH / 2), y: (window.innerHeight / 2) - (this.editorWidget.getContentHeight() / 2) }; }, render: (container) => { return this._render(provider, container); }, @@ -161,11 +161,7 @@ class AccessibleView extends Disposable { } private _layout(): void { - const windowWidth = window.innerWidth; - const width = windowWidth * DIMENSION_DEFAULT.WIDTH; - this._editorWidget.layout({ width, height: this._editorWidget.getContentHeight() }); - const left = Math.round((windowWidth - width) / 2); - this._editorContainer.style.left = `${left}px`; + this._editorWidget.layout({ width: DIMENSION_DEFAULT.WIDTH, height: this._editorWidget.getContentHeight() }); } private async _getTextModel(resource: URI): Promise { diff --git a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css index d56086e674c..0a03582ca60 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css +++ b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ .accessible-view { - position: relative; + position: absolute; background-color: var(--vscode-editorWidget-background); color: var(--vscode-editorWidget-foreground); box-shadow: 0 2px 8px var(--vscode-widget-shadow); - border: 2px solid var(--vscode-contrastActiveBorder); + border: 2px solid var(--vscode-focusBorder); } From 54b7f4272e82fb691ebd5ae014c3f6f64318a1c3 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Mon, 10 Jul 2023 15:49:50 -0700 Subject: [PATCH 113/119] Repopulate slash command when user submits query (#187514) --- .../chat/browser/contrib/chatInputEditorContrib.ts | 2 +- src/vs/workbench/contrib/chat/common/chatService.ts | 2 +- .../contrib/chat/common/chatServiceImpl.ts | 13 +++++-------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts index d869e5bed4f..1bf461d1ae3 100644 --- a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts +++ b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts @@ -138,7 +138,7 @@ class InputEditorSlashCommandFollowups extends Disposable { @IChatService private readonly chatService: IChatService ) { super(); - this._register(this.chatService.onDidCompleteSlashCommand(({ slashCommand, sessionId }) => this.repopulateSlashCommand(slashCommand, sessionId))); + this._register(this.chatService.onDidSubmitSlashCommand(({ slashCommand, sessionId }) => this.repopulateSlashCommand(slashCommand, sessionId))); } private async repopulateSlashCommand(slashCommand: string, sessionId: string) { diff --git a/src/vs/workbench/contrib/chat/common/chatService.ts b/src/vs/workbench/contrib/chat/common/chatService.ts index 8acfa91959c..95ebca45502 100644 --- a/src/vs/workbench/contrib/chat/common/chatService.ts +++ b/src/vs/workbench/contrib/chat/common/chatService.ts @@ -178,7 +178,7 @@ export interface IChatService { _serviceBrand: undefined; transferredSessionId: string | undefined; - onDidCompleteSlashCommand: Event<{ slashCommand: string; sessionId: string }>; + onDidSubmitSlashCommand: Event<{ slashCommand: string; sessionId: string }>; registerProvider(provider: IChatProvider): IDisposable; registerSlashCommandProvider(provider: ISlashCommandProvider): IDisposable; getProviderInfos(): IChatProviderInfo[]; diff --git a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts index 3c20b21d168..68a14aaf8b7 100644 --- a/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts +++ b/src/vs/workbench/contrib/chat/common/chatServiceImpl.ts @@ -135,8 +135,8 @@ export class ChatService extends Disposable implements IChatService { private readonly _onDidPerformUserAction = this._register(new Emitter()); public readonly onDidPerformUserAction: Event = this._onDidPerformUserAction.event; - private readonly _onDidCompleteSlashCommand = this._register(new Emitter<{ slashCommand: string; sessionId: string }>()); - public readonly onDidCompleteSlashCommand = this._onDidCompleteSlashCommand.event; + private readonly _onDidSubmitSlashCommand = this._register(new Emitter<{ slashCommand: string; sessionId: string }>()); + public readonly onDidSubmitSlashCommand = this._onDidSubmitSlashCommand.event; constructor( @IStorageService private readonly storageService: IStorageService, @@ -446,6 +446,9 @@ export class ChatService extends Disposable implements IChatService { model.cancelRequest(request); }); + if (usedSlashCommand?.command) { + this._onDidSubmitSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId }); + } let rawResponse = await provider.provideReply({ session: model.session!, message: resolvedCommand }, progressCallback, token); if (token.isCancellationRequested) { return; @@ -475,15 +478,9 @@ export class ChatService extends Disposable implements IChatService { Promise.resolve(provider.provideFollowups(model.session!, CancellationToken.None)).then(followups => { model.setFollowups(request, withNullAsUndefined(followups)); model.completeResponse(request); - if (usedSlashCommand?.command) { - this._onDidCompleteSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId }); - } }); } else { model.completeResponse(request); - if (usedSlashCommand?.command) { - this._onDidCompleteSlashCommand.fire({ slashCommand: usedSlashCommand.command, sessionId: model.sessionId }); - } } } }); From ff81f6cb82c29590844e8d5fd07f498bbea7692e Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 10 Jul 2023 16:41:31 -0700 Subject: [PATCH 114/119] Remove un-needed use of native privates (#187518) For #186737 --- .../codeAction/browser/codeActionController.ts | 6 +++--- .../codeAction/browser/codeActionModel.ts | 10 +++++----- .../browser/webviewWorkbenchService.ts | 18 +++++++++--------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionController.ts b/src/vs/editor/contrib/codeAction/browser/codeActionController.ts index 384902ff004..5b8d6576b14 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionController.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionController.ts @@ -56,7 +56,7 @@ export class CodeActionController extends Disposable implements IEditorContribut private readonly _resolver: CodeActionKeybindingResolver; - #disposed = false; + private _disposed = false; constructor( editor: ICodeEditor, @@ -91,7 +91,7 @@ export class CodeActionController extends Disposable implements IEditorContribut } override dispose() { - this.#disposed = true; + this._disposed = true; super.dispose(); } @@ -150,7 +150,7 @@ export class CodeActionController extends Disposable implements IEditorContribut return; } - if (this.#disposed) { + if (this._disposed) { return; } diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts index e36f94c275f..19963bfe57f 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts @@ -147,7 +147,7 @@ export class CodeActionModel extends Disposable { private readonly _onDidChangeState = this._register(new Emitter()); public readonly onDidChangeState = this._onDidChangeState.event; - #isDisposed = false; + private _disposed = false; constructor( private readonly _editor: ICodeEditor, @@ -167,17 +167,17 @@ export class CodeActionModel extends Disposable { } override dispose(): void { - if (this.#isDisposed) { + if (this._disposed) { return; } - this.#isDisposed = true; + this._disposed = true; super.dispose(); this.setState(CodeActionsState.Empty, true); } private _update(): void { - if (this.#isDisposed) { + if (this._disposed) { return; } @@ -228,7 +228,7 @@ export class CodeActionModel extends Disposable { this._state = newState; - if (!skipNotify && !this.#isDisposed) { + if (!skipNotify && !this._disposed) { this._onDidChangeState.fire(newState); } } diff --git a/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts b/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts index 263649a8b74..39750b798b2 100644 --- a/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts +++ b/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts @@ -120,8 +120,8 @@ function canRevive(reviver: WebviewResolver, webview: WebviewInput): boolean { export class LazilyResolvedWebviewEditorInput extends WebviewInput { - #resolved = false; - #resolvePromise?: CancelablePromise; + private _resolved = false; + private _resolvePromise?: CancelablePromise; constructor( init: WebviewInputInitInfo, @@ -133,17 +133,17 @@ export class LazilyResolvedWebviewEditorInput extends WebviewInput { override dispose() { super.dispose(); - this.#resolvePromise?.cancel(); - this.#resolvePromise = undefined; + this._resolvePromise?.cancel(); + this._resolvePromise = undefined; } @memoize public override async resolve() { - if (!this.#resolved) { - this.#resolved = true; - this.#resolvePromise = createCancelablePromise(token => this._webviewWorkbenchService.resolveWebview(this, token)); + if (!this._resolved) { + this._resolved = true; + this._resolvePromise = createCancelablePromise(token => this._webviewWorkbenchService.resolveWebview(this, token)); try { - await this.#resolvePromise; + await this._resolvePromise; } catch (e) { if (!isCancellationError(e)) { throw e; @@ -158,7 +158,7 @@ export class LazilyResolvedWebviewEditorInput extends WebviewInput { return; } - other.#resolved = this.#resolved; + other._resolved = this._resolved; return other; } } From b14044d28520339c787ad823fe0459fe35dcfac4 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 10 Jul 2023 17:07:10 -0700 Subject: [PATCH 115/119] part of #179684 --- .../contrib/tasks/browser/abstractTaskService.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 0a5012a9c9a..9bb6a0deee6 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -1957,6 +1957,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private async _getGroupedTasks(filter?: ITaskFilter): Promise { + await this._waitForAllSupportedExecutions; const type = filter?.type; const needsRecentTasksMigration = this._needsRecentTasksMigration(); await this._activateTaskProviders(filter?.type); @@ -2210,11 +2211,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return new Map(); } await this._waitForOneSupportedExecution; - if (runSource === TaskRunSource.Reconnect) { - await raceTimeout(this._waitForAllSupportedExecutions, 2000, () => { - this._logService.warn('Timed out waiting for all supported executions for task reconnection'); - }); - } + await raceTimeout(this._waitForAllSupportedExecutions, 2000, () => { + this._logService.warn('Timed out waiting for all supported executions'); + }); await this._whenTaskSystemReady; if (this._workspaceTasksPromise) { return this._workspaceTasksPromise; From b041b4edc4f1f7c191be7762703cff64be503d91 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 10 Jul 2023 17:07:51 -0700 Subject: [PATCH 116/119] tweak --- src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 9bb6a0deee6..82abd3c3c0f 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -2210,7 +2210,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!(await this._trust())) { return new Map(); } - await this._waitForOneSupportedExecution; await raceTimeout(this._waitForAllSupportedExecutions, 2000, () => { this._logService.warn('Timed out waiting for all supported executions'); }); From 492217cfd3d419f087d2a33fc40c8df66db5023c Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 10 Jul 2023 20:27:12 -0700 Subject: [PATCH 117/119] fix compile error --- src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 82abd3c3c0f..04b21c59814 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -223,7 +223,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer protected _outputChannel: IOutputChannel; protected readonly _onDidStateChange: Emitter; - private _waitForOneSupportedExecution: Promise; private _waitForAllSupportedExecutions: Promise; private _onDidRegisterSupportedExecutions: Emitter = new Emitter(); private _onDidRegisterAllSupportedExecutions: Emitter = new Emitter(); @@ -335,9 +334,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._setPersistentTask(e.__task); } })); - this._waitForOneSupportedExecution = new Promise(resolve => { - once(this._onDidRegisterSupportedExecutions.event)(() => resolve()); - }); this._waitForAllSupportedExecutions = new Promise(resolve => { once(this._onDidRegisterAllSupportedExecutions.event)(() => resolve()); }); From 6243562032a9a168df33c1b4dc84d5b2abbcb22d Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Mon, 10 Jul 2023 21:48:30 -0700 Subject: [PATCH 118/119] Avoid restoring stale input value after clear (#187513) --- src/vs/workbench/contrib/chat/browser/chatViewPane.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/chat/browser/chatViewPane.ts b/src/vs/workbench/contrib/chat/browser/chatViewPane.ts index e3863e507b7..5f7a05375d9 100644 --- a/src/vs/workbench/contrib/chat/browser/chatViewPane.ts +++ b/src/vs/workbench/contrib/chat/browser/chatViewPane.ts @@ -119,6 +119,7 @@ export class ChatViewPane extends ViewPane implements IChatViewPane { if (this.widget.viewModel) { this.chatService.clearSession(this.widget.viewModel.sessionId); } + this.viewState.inputValue = ''; this.updateModel(); } From 618d67ebcc713599e934898128adb9a4936207da Mon Sep 17 00:00:00 2001 From: Artem Zatsarynnyi Date: Tue, 11 Jul 2023 12:26:39 +0200 Subject: [PATCH 119/119] Align to upstream Signed-off-by: Artem Zatsarynnyi --- code/src/vs/code/browser/workbench/workbench.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/src/vs/code/browser/workbench/workbench.ts b/code/src/vs/code/browser/workbench/workbench.ts index bb44677a3ff..f15fa499fa3 100644 --- a/code/src/vs/code/browser/workbench/workbench.ts +++ b/code/src/vs/code/browser/workbench/workbench.ts @@ -410,7 +410,7 @@ class WorkspaceProvider implements IWorkspaceProvider { } : undefined, workspaceProvider: WorkspaceProvider.create(config), urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute), - credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider() // with a remote, we don't use a local credentials provider + credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageSecretStorageProvider() // with a remote, we don't use a local secret storage provider }, undefined, 2)); // Create workbench