From 73f3a69d81e3fae50b56718b5e97c19b193bacb9 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 3 Jun 2021 08:20:21 +0200 Subject: [PATCH 01/91] debt - remove unncesseary lifecycle phase awaits --- src/vs/base/common/filters.ts | 2 +- src/vs/workbench/electron-sandbox/window.ts | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/vs/base/common/filters.ts b/src/vs/base/common/filters.ts index 5677cbebebb..f939880a97e 100644 --- a/src/vs/base/common/filters.ts +++ b/src/vs/base/common/filters.ts @@ -526,7 +526,7 @@ const enum Arrow { Diag = 1, Left = 2, LeftLeft = 3 } * 3. `` * 4. `` etc */ -export type FuzzyScore = [score: number, wordStart: number, ...matches: number[]];// [number, number, number]; +export type FuzzyScore = [score: number, wordStart: number, ...matches: number[]]; export namespace FuzzyScore { /** diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts index de32fcf338d..f81b2dc9382 100644 --- a/src/vs/workbench/electron-sandbox/window.ts +++ b/src/vs/workbench/electron-sandbox/window.ts @@ -187,15 +187,8 @@ export class NativeWindow extends Disposable { ipcRenderer.on('vscode:showInfoMessage', (event: unknown, message: string) => this.notificationService.info(message)); // Fullscreen Events - ipcRenderer.on('vscode:enterFullScreen', async () => { - await this.lifecycleService.when(LifecyclePhase.Ready); - setFullscreen(true); - }); - - ipcRenderer.on('vscode:leaveFullScreen', async () => { - await this.lifecycleService.when(LifecyclePhase.Ready); - setFullscreen(false); - }); + ipcRenderer.on('vscode:enterFullScreen', async () => setFullscreen(true)); + ipcRenderer.on('vscode:leaveFullScreen', async () => setFullscreen(false)); // Proxy Login Dialog ipcRenderer.on('vscode:openProxyAuthenticationDialog', async (event: unknown, payload: { authInfo: AuthInfo, username?: string, password?: string, replyChannel: string }) => { @@ -669,8 +662,6 @@ export class NativeWindow extends Disposable { } private async openResources(resources: Array, diffMode: boolean): Promise { - await this.lifecycleService.when(LifecyclePhase.Ready); - const editors: IBaseResourceEditorInput[] = []; // In diffMode we open 2 resources as diff From dc4b317192d606fd244e6d7723b18249054ed13a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 3 Jun 2021 08:49:30 +0200 Subject: [PATCH 02/91] dialogs - do not require `buttons` property --- src/vs/base/browser/ui/dialog/dialog.ts | 4 ++-- src/vs/platform/dialogs/common/dialogs.ts | 9 +++++---- .../dialogs/test/common/testDialogService.ts | 2 +- .../quickinput/browser/commandsQuickAccess.ts | 2 +- .../api/browser/mainThreadAuthentication.ts | 2 +- src/vs/workbench/browser/actions/layoutActions.ts | 6 +++--- src/vs/workbench/browser/actions/workspaceActions.ts | 2 +- .../workbench/browser/parts/dialogs/dialogHandler.ts | 4 ++-- .../browser/parts/editor/editorDropTarget.ts | 2 +- .../contrib/bulkEdit/browser/preview/bulkEditPane.ts | 2 +- .../extensions/browser/extensions.contribution.ts | 2 +- .../contrib/extensions/browser/extensionsActions.ts | 2 +- .../electron-sandbox/extensionsSlowActions.ts | 4 ++-- .../workbench/contrib/files/browser/fileActions.ts | 2 +- .../contrib/files/browser/views/explorerViewer.ts | 2 +- src/vs/workbench/contrib/update/browser/update.ts | 3 +-- .../userDataSync/browser/userDataSyncMergesView.ts | 2 +- .../electron-sandbox/actions/installActions.ts | 8 ++++---- .../electron-sandbox/parts/dialogs/dialogHandler.ts | 2 +- src/vs/workbench/electron-sandbox/window.ts | 2 +- .../services/dialogs/common/dialogService.ts | 12 ++++++++---- .../extensionManagement/browser/extensionBisect.ts | 2 +- .../services/remote/common/remoteExplorerService.ts | 2 +- .../electron-sandbox/workingCopyBackupTracker.ts | 2 +- .../electron-sandbox/workspaceEditingService.ts | 2 +- 25 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/vs/base/browser/ui/dialog/dialog.ts b/src/vs/base/browser/ui/dialog/dialog.ts index 6df00351bfc..84757ba8cc8 100644 --- a/src/vs/base/browser/ui/dialog/dialog.ts +++ b/src/vs/base/browser/ui/dialog/dialog.ts @@ -87,7 +87,7 @@ export class Dialog extends Disposable { private readonly inputs: InputBox[]; private readonly buttons: string[]; - constructor(private container: HTMLElement, private message: string, buttons: string[], private options: IDialogOptions) { + constructor(private container: HTMLElement, private message: string, buttons: string[] | undefined, private options: IDialogOptions) { super(); this.modalElement = this.container.appendChild($(`.monaco-dialog-modal-block.dimmed`)); @@ -96,7 +96,7 @@ export class Dialog extends Disposable { this.element.setAttribute('role', 'dialog'); hide(this.element); - this.buttons = buttons.length ? buttons : [nls.localize('ok', "OK")]; // If no button is provided, default to OK + this.buttons = Array.isArray(buttons) && buttons.length ? buttons : [nls.localize('ok', "OK")]; // If no button is provided, default to OK const buttonsRowElement = this.element.appendChild($('.dialog-buttons-row')); this.buttonsContainer = buttonsRowElement.appendChild($('.dialog-buttons')); diff --git a/src/vs/platform/dialogs/common/dialogs.ts b/src/vs/platform/dialogs/common/dialogs.ts index 9e3738404d0..ca48f7a7253 100644 --- a/src/vs/platform/dialogs/common/dialogs.ts +++ b/src/vs/platform/dialogs/common/dialogs.ts @@ -31,12 +31,13 @@ export interface IConfirmDialogArgs { export interface IShowDialogArgs { severity: Severity; message: string; - buttons: string[]; + buttons?: string[]; options?: IDialogOptions; } export interface IInputDialogArgs extends IShowDialogArgs { - inputs: IInput[], + buttons: string[]; + inputs: IInput[]; } export interface IDialog { @@ -222,7 +223,7 @@ export interface IDialogHandler { * then a promise with index of `cancelId` option is returned. If there is no such * option then promise with index `0` is returned. */ - show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise; + show(severity: Severity, message: string, buttons?: string[], options?: IDialogOptions): Promise; /** * Present a modal dialog to the user asking for input. @@ -262,7 +263,7 @@ export interface IDialogService { * then a promise with index of `cancelId` option is returned. If there is no such * option then promise with index `0` is returned. */ - show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise; + show(severity: Severity, message: string, buttons?: string[], options?: IDialogOptions): Promise; /** * Present a modal dialog to the user asking for input. diff --git a/src/vs/platform/dialogs/test/common/testDialogService.ts b/src/vs/platform/dialogs/test/common/testDialogService.ts index 1d2b2f08f71..bf965945ad8 100644 --- a/src/vs/platform/dialogs/test/common/testDialogService.ts +++ b/src/vs/platform/dialogs/test/common/testDialogService.ts @@ -26,7 +26,7 @@ export class TestDialogService implements IDialogService { return { confirmed: false }; } - async show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise { return { choice: 0 }; } + async show(severity: Severity, message: string, buttons?: string[], options?: IDialogOptions): Promise { return { choice: 0 }; } async input(): Promise { { return { choice: 0, values: [] }; } } async about(): Promise { } } diff --git a/src/vs/platform/quickinput/browser/commandsQuickAccess.ts b/src/vs/platform/quickinput/browser/commandsQuickAccess.ts index e84a282762a..d2cac3a6407 100644 --- a/src/vs/platform/quickinput/browser/commandsQuickAccess.ts +++ b/src/vs/platform/quickinput/browser/commandsQuickAccess.ts @@ -163,7 +163,7 @@ export abstract class AbstractCommandsQuickAccessProvider extends PickerQuickAcc await this.commandService.executeCommand(commandPick.commandId); } catch (error) { if (!isPromiseCanceledError(error)) { - this.dialogService.show(Severity.Error, localize('canNotRun', "Command '{0}' resulted in an error ({1})", commandPick.label, toErrorMessage(error)), [localize('ok', 'OK')]); + this.dialogService.show(Severity.Error, localize('canNotRun', "Command '{0}' resulted in an error ({1})", commandPick.label, toErrorMessage(error))); } } } diff --git a/src/vs/workbench/api/browser/mainThreadAuthentication.ts b/src/vs/workbench/api/browser/mainThreadAuthentication.ts index 19e704dff86..797e8c2ba2f 100644 --- a/src/vs/workbench/api/browser/mainThreadAuthentication.ts +++ b/src/vs/workbench/api/browser/mainThreadAuthentication.ts @@ -34,7 +34,7 @@ export class MainThreadAuthenticationProvider extends Disposable { const allowedExtensions = readAllowedExtensions(this.storageService, this.id, accountName); if (!allowedExtensions.length) { - this.dialogService.show(Severity.Info, nls.localize('noTrustedExtensions', "This account has not been used by any extensions."), []); + this.dialogService.show(Severity.Info, nls.localize('noTrustedExtensions', "This account has not been used by any extensions.")); return; } diff --git a/src/vs/workbench/browser/actions/layoutActions.ts b/src/vs/workbench/browser/actions/layoutActions.ts index 3d94cd32bc6..391919a1129 100644 --- a/src/vs/workbench/browser/actions/layoutActions.ts +++ b/src/vs/workbench/browser/actions/layoutActions.ts @@ -625,13 +625,13 @@ class MoveFocusedViewAction extends Action2 { const focusedViewId = viewId || FocusedViewContext.getValue(contextKeyService); if (focusedViewId === undefined || focusedViewId.trim() === '') { - dialogService.show(Severity.Error, localize('moveFocusedView.error.noFocusedView', "There is no view currently focused."), [localize('ok', 'OK')]); + dialogService.show(Severity.Error, localize('moveFocusedView.error.noFocusedView', "There is no view currently focused.")); return; } const viewDescriptor = viewDescriptorService.getViewDescriptorById(focusedViewId); if (!viewDescriptor || !viewDescriptor.canMoveView) { - dialogService.show(Severity.Error, localize('moveFocusedView.error.nonMovableView', "The currently focused view is not movable."), [localize('ok', 'OK')]); + dialogService.show(Severity.Error, localize('moveFocusedView.error.nonMovableView', "The currently focused view is not movable.")); return; } @@ -756,7 +756,7 @@ registerAction2(class extends Action2 { } if (!viewDescriptor) { - dialogService.show(Severity.Error, localize('resetFocusedView.error.noFocusedView', "There is no view currently focused."), [localize('ok', 'OK')]); + dialogService.show(Severity.Error, localize('resetFocusedView.error.noFocusedView', "There is no view currently focused.")); return; } diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts index 7cd58d9a66c..c96cc285aca 100644 --- a/src/vs/workbench/browser/actions/workspaceActions.ts +++ b/src/vs/workbench/browser/actions/workspaceActions.ts @@ -124,7 +124,7 @@ export class CloseWorkspaceAction extends Action2 { const environmentService = accessor.get(IWorkbenchEnvironmentService); if (contextService.getWorkbenchState() === WorkbenchState.EMPTY) { - dialogService.show(Severity.Error, localize('noWorkspaceOrFolderOpened', "There is currently no workspace or folder opened in this instance to close."), [localize('ok', 'OK')]); + dialogService.show(Severity.Error, localize('noWorkspaceOrFolderOpened', "There is currently no workspace or folder opened in this instance to close.")); return; } diff --git a/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts b/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts index 84c51a948ad..530ce5e5c28 100644 --- a/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts +++ b/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts @@ -71,7 +71,7 @@ export class BrowserDialogHandler implements IDialogHandler { return (severity === Severity.Info) ? 'question' : (severity === Severity.Error) ? 'error' : (severity === Severity.Warning) ? 'warning' : 'none'; } - async show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise { + async show(severity: Severity, message: string, buttons?: string[], options?: IDialogOptions): Promise { this.logService.trace('DialogService#show', message); const result = await this.doShow(this.getDialogType(severity), message, buttons, options?.detail, options?.cancelId, options?.checkbox, undefined, typeof options?.custom === 'object' ? options.custom : undefined); @@ -82,7 +82,7 @@ export class BrowserDialogHandler implements IDialogHandler { }; } - private async doShow(type: 'none' | 'info' | 'error' | 'question' | 'warning' | 'pending' | undefined, message: string, buttons: string[], detail?: string, cancelId?: number, checkbox?: ICheckbox, inputs?: IInput[], customOptions?: ICustomDialogOptions): Promise { + private async doShow(type: 'none' | 'info' | 'error' | 'question' | 'warning' | 'pending' | undefined, message: string, buttons?: string[], detail?: string, cancelId?: number, checkbox?: ICheckbox, inputs?: IInput[], customOptions?: ICustomDialogOptions): Promise { const dialogDisposables = new DisposableStore(); const renderBody = customOptions ? (parent: HTMLElement) => { diff --git a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts index 10cecdf94a4..ed8c6be050b 100644 --- a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts +++ b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts @@ -313,7 +313,7 @@ class DropOverlay extends Themable { // Skip for very large files because this operation is unbuffered if (file.size > DropOverlay.MAX_FILE_UPLOAD_SIZE) { - this.dialogService.show(Severity.Warning, localize('fileTooLarge', "File is too large to open as untitled editor. Please upload it first into the file explorer and then try again."), [localize('ok', 'OK')]); + this.dialogService.show(Severity.Warning, localize('fileTooLarge', "File is too large to open as untitled editor. Please upload it first into the file explorer and then try again.")); continue; } diff --git a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPane.ts b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPane.ts index 5964f380e31..ec73360517e 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPane.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPane.ts @@ -245,7 +245,7 @@ export class BulkEditPane extends ViewPane { message = localize('conflict.N', "Cannot apply refactoring because {0} other files have changed in the meantime.", conflicts.length); } - this._dialogService.show(Severity.Warning, message, []).finally(() => this._done(false)); + this._dialogService.show(Severity.Warning, message).finally(() => this._done(false)); } discard() { diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 4232ee5f9e3..956164ef0a8 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -546,7 +546,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi if (outdated.length) { return runAction(this.instantiationService.createInstance(SearchExtensionsAction, '@outdated ')); } else { - return this.dialogService.show(Severity.Info, localize('noUpdatesAvailable', "All extensions are up to date."), []); + return this.dialogService.show(Severity.Info, localize('noUpdatesAvailable', "All extensions are up to date.")); } } }); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 6e4fea0a6a8..b24d28d16f9 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -133,7 +133,7 @@ export class PromptExtensionInstallFailureAction extends Action { } if ([INSTALL_ERROR_INCOMPATIBLE, INSTALL_ERROR_MALICIOUS].includes(this.error.name)) { - await this.dialogService.show(Severity.Info, getErrorMessage(this.error), []); + await this.dialogService.show(Severity.Info, getErrorMessage(this.error)); return; } diff --git a/src/vs/workbench/contrib/extensions/electron-sandbox/extensionsSlowActions.ts b/src/vs/workbench/contrib/extensions/electron-sandbox/extensionsSlowActions.ts index 82b6883f9e5..0c5855b4e3b 100644 --- a/src/vs/workbench/contrib/extensions/electron-sandbox/extensionsSlowActions.ts +++ b/src/vs/workbench/contrib/extensions/electron-sandbox/extensionsSlowActions.ts @@ -152,7 +152,7 @@ class ReportExtensionSlowAction extends Action { this._dialogService.show( Severity.Info, localize('attach.title', "Did you attach the CPU-Profile?"), - [localize('ok', 'OK')], + undefined, { detail: localize('attach.msg', "This is a reminder to make sure that you have not forgotten to attach '{0}' to the issue you have just created.", path) } ); } @@ -186,7 +186,7 @@ class ShowExtensionSlowAction extends Action { this._dialogService.show( Severity.Info, localize('attach.title', "Did you attach the CPU-Profile?"), - [localize('ok', 'OK')], + undefined, { detail: localize('attach.msg2', "This is a reminder to make sure that you have not forgotten to attach '{0}' to an existing performance issue.", path) } ); } diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 258000894b2..cf5fd76a1bc 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -614,7 +614,7 @@ export class ShowOpenedFileInNewWindow extends Action { if (this.fileService.canHandleResource(fileResource)) { this.hostService.openWindow([{ fileUri: fileResource }], { forceNewWindow: true }); } else { - this.dialogService.show(Severity.Error, nls.localize('openFileToShowInNewWindow.unsupportedschema', "The active editor must contain an openable resource."), [nls.localize('ok', 'OK')]); + this.dialogService.show(Severity.Error, nls.localize('openFileToShowInNewWindow.unsupportedschema', "The active editor must contain an openable resource.")); } } } diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 49095f56fca..9cb2193c8f3 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -984,7 +984,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { await this.handleExplorerDrop(data as ElementsDragAndDropData, resolvedTarget, originalEvent); } } catch (error) { - this.dialogService.show(Severity.Error, toErrorMessage(error), [localize('ok', 'OK')]); + this.dialogService.show(Severity.Error, toErrorMessage(error)); } } diff --git a/src/vs/workbench/contrib/update/browser/update.ts b/src/vs/workbench/contrib/update/browser/update.ts index f648957e6b6..2138c3827ba 100644 --- a/src/vs/workbench/contrib/update/browser/update.ts +++ b/src/vs/workbench/contrib/update/browser/update.ts @@ -306,8 +306,7 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu private onUpdateNotAvailable(): void { this.dialogService.show( severity.Info, - nls.localize('noUpdatesAvailable', "There are currently no updates available."), - [nls.localize('ok', "OK")] + nls.localize('noUpdatesAvailable', "There are currently no updates available.") ); } diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncMergesView.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncMergesView.ts index b86deb022dd..e7f00b997c6 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncMergesView.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncMergesView.ts @@ -267,7 +267,7 @@ export class UserDataSyncMergesViewPane extends TreeViewPane { previewResource = this.userDataSyncPreview.resources.find(({ local }) => isEqual(local, previewResource.local))!; await this.reopen(previewResource); if (previewResource.mergeState === MergeState.Conflict) { - await this.dialogService.show(Severity.Warning, localize('conflicts detected', "Conflicts Detected"), [], { + await this.dialogService.show(Severity.Warning, localize('conflicts detected', "Conflicts Detected"), undefined, { detail: localize('resolve', "Unable to merge due to conflicts. Please resolve them to continue.") }); } diff --git a/src/vs/workbench/electron-sandbox/actions/installActions.ts b/src/vs/workbench/electron-sandbox/actions/installActions.ts index 37b8f4130e0..4bcee746dbe 100644 --- a/src/vs/workbench/electron-sandbox/actions/installActions.ts +++ b/src/vs/workbench/electron-sandbox/actions/installActions.ts @@ -37,9 +37,9 @@ export class InstallShellScriptAction extends Action2 { try { await nativeHostService.installShellCommand(); - dialogService.show(Severity.Info, localize('successIn', "Shell command '{0}' successfully installed in PATH.", productService.applicationName), []); + dialogService.show(Severity.Info, localize('successIn', "Shell command '{0}' successfully installed in PATH.", productService.applicationName)); } catch (error) { - dialogService.show(Severity.Error, toErrorMessage(error), [localize('ok', "OK"),]); + dialogService.show(Severity.Error, toErrorMessage(error)); } } } @@ -66,9 +66,9 @@ export class UninstallShellScriptAction extends Action2 { try { await nativeHostService.uninstallShellCommand(); - dialogService.show(Severity.Info, localize('successFrom', "Shell command '{0}' successfully uninstalled from PATH.", productService.applicationName), []); + dialogService.show(Severity.Info, localize('successFrom', "Shell command '{0}' successfully uninstalled from PATH.", productService.applicationName)); } catch (error) { - dialogService.show(Severity.Error, toErrorMessage(error), [localize('ok', "OK"),]); + dialogService.show(Severity.Error, toErrorMessage(error)); } } } diff --git a/src/vs/workbench/electron-sandbox/parts/dialogs/dialogHandler.ts b/src/vs/workbench/electron-sandbox/parts/dialogs/dialogHandler.ts index 3805a175897..40094f38189 100644 --- a/src/vs/workbench/electron-sandbox/parts/dialogs/dialogHandler.ts +++ b/src/vs/workbench/electron-sandbox/parts/dialogs/dialogHandler.ts @@ -90,7 +90,7 @@ export class NativeDialogHandler implements IDialogHandler { return opts; } - async show(severity: Severity, message: string, buttons: string[], dialogOptions?: IDialogOptions): Promise { + async show(severity: Severity, message: string, buttons?: string[], dialogOptions?: IDialogOptions): Promise { this.logService.trace('DialogService#show', message); const { options, buttonIndexMap } = this.massageMessageBoxOptions({ diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts index f81b2dc9382..a5fe0e7040d 100644 --- a/src/vs/workbench/electron-sandbox/window.ts +++ b/src/vs/workbench/electron-sandbox/window.ts @@ -466,7 +466,7 @@ export class NativeWindow extends Disposable { this.logService.error('Error: There is a dependency cycle in the AMD modules that needs to be resolved!'); this.nativeHostService.exit(37); // running on a build machine, just exit without showing a dialog } else { - this.dialogService.show(Severity.Error, localize('loaderCycle', "There is a dependency cycle in the AMD modules that needs to be resolved!"), [localize('ok', "OK")]); + this.dialogService.show(Severity.Error, localize('loaderCycle', "There is a dependency cycle in the AMD modules that needs to be resolved!")); this.nativeHostService.openDevTools(); } } diff --git a/src/vs/workbench/services/dialogs/common/dialogService.ts b/src/vs/workbench/services/dialogs/common/dialogService.ts index df940085921..b66b8678475 100644 --- a/src/vs/workbench/services/dialogs/common/dialogService.ts +++ b/src/vs/workbench/services/dialogs/common/dialogService.ts @@ -6,26 +6,30 @@ import Severity from 'vs/base/common/severity'; import { Disposable } from 'vs/base/common/lifecycle'; import { IConfirmation, IConfirmationResult, IDialogOptions, IDialogService, IInput, IInputResult, IShowResult } from 'vs/platform/dialogs/common/dialogs'; -import { DialogsModel, IDialogsModel } from 'vs/workbench/common/dialogs'; +import { DialogsModel } from 'vs/workbench/common/dialogs'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class DialogService extends Disposable implements IDialogService { - _serviceBrand: undefined; - readonly model: IDialogsModel = this._register(new DialogsModel()); + declare readonly _serviceBrand: undefined; + + readonly model = this._register(new DialogsModel()); async confirm(confirmation: IConfirmation): Promise { const handle = this.model.show({ confirmArgs: { confirmation } }); + return await handle.result as IConfirmationResult; } - async show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise { + async show(severity: Severity, message: string, buttons?: string[], options?: IDialogOptions): Promise { const handle = this.model.show({ showArgs: { severity, message, buttons, options } }); + return await handle.result as IShowResult; } async input(severity: Severity, message: string, buttons: string[], inputs: IInput[], options?: IDialogOptions): Promise { const handle = this.model.show({ inputArgs: { severity, message, buttons, inputs, options } }); + return await handle.result as IInputResult; } diff --git a/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts b/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts index 0684def2708..548f15ad4f8 100644 --- a/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts +++ b/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts @@ -291,7 +291,7 @@ registerAction2(class extends Action2 { if (done.bad) { // DONE but nothing found - await dialogService.show(Severity.Info, localize('done.msg', "Extension Bisect"), [], { + await dialogService.show(Severity.Info, localize('done.msg', "Extension Bisect"), undefined, { detail: localize('done.detail2', "Extension Bisect is done but no extension has been identified. This might be a problem with {0}.", productService.nameShort) }); diff --git a/src/vs/workbench/services/remote/common/remoteExplorerService.ts b/src/vs/workbench/services/remote/common/remoteExplorerService.ts index 162f505dc32..bbbf8f7448b 100644 --- a/src/vs/workbench/services/remote/common/remoteExplorerService.ts +++ b/src/vs/workbench/services/remote/common/remoteExplorerService.ts @@ -546,7 +546,7 @@ export class TunnelModel extends Disposable { this.mismatchCooldown = newCooldown; const mismatchString = nls.localize('remote.localPortMismatch.single', "Local port {0} could not be used for forwarding to remote port {1}.\n\nThis usually happens when there is already another process using local port {0}.\n\nPort number {2} has been used instead.", expectedLocal, tunnel.tunnelRemotePort, tunnel.tunnelLocalPort); - return this.dialogService.show(Severity.Info, mismatchString, [nls.localize('remote.localPortMismatch.Ok', "Ok")]); + return this.dialogService.show(Severity.Info, mismatchString); } async forward(remote: { host: string, port: number }, local?: number, name?: string, source?: string, elevateIfNeeded?: boolean, diff --git a/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupTracker.ts b/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupTracker.ts index c158e96b18f..737fac3ad17 100644 --- a/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupTracker.ts +++ b/src/vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupTracker.ts @@ -143,7 +143,7 @@ export class NativeWorkingCopyBackupTracker extends WorkingCopyBackupTracker imp ? getFileNamesMessage(dirtyWorkingCopies.map(x => x.name)) + '\n' + advice : advice; - this.dialogService.show(Severity.Error, msg, [localize('ok', 'OK')], { detail }); + this.dialogService.show(Severity.Error, msg, undefined, { detail }); this.logService.error(error ? `[backup tracker] ${msg}: ${error}` : `[backup tracker] ${msg}`); } diff --git a/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts b/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts index 32ce1d95e9b..952ba35f3a5 100644 --- a/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts @@ -147,7 +147,7 @@ export class NativeWorkspaceEditingService extends AbstractWorkspaceEditingServi await this.dialogService.show( Severity.Info, localize('workspaceOpenedMessage', "Unable to save workspace '{0}'", basename(path)), - [localize('ok', "OK")], + undefined, { detail: localize('workspaceOpenedDetail', "The workspace is already opened in another window. Please close that window first and then try again.") } From e47d24f0a773999a51597def6b4cc7d00f7a6ebf Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 3 Jun 2021 09:49:19 +0200 Subject: [PATCH 03/91] file editor - path service for default URI scheme --- .../files/browser/editors/fileEditorInput.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts index 488441ba5e3..bc013fb733b 100644 --- a/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts +++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts @@ -21,6 +21,7 @@ import { isEqual } from 'vs/base/common/resources'; import { Event } from 'vs/base/common/event'; import { Schemas } from 'vs/base/common/network'; import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; +import { IPathService } from 'vs/workbench/services/path/common/pathService'; const enum ForceOpenAs { None, @@ -84,7 +85,8 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements @ILabelService labelService: ILabelService, @IFileService fileService: IFileService, @IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService, - @IEditorService editorService: IEditorService + @IEditorService editorService: IEditorService, + @IPathService private readonly pathService: IPathService ) { super(resource, preferredResource, editorService, textFileService, labelService, fileService); @@ -158,7 +160,7 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements setPreferredName(name: string): void { if (!this.allowLabelOverride()) { - return; // block for specific schemes we own + return; // block for specific schemes we consider to be owning } if (this.preferredName !== name) { @@ -169,7 +171,10 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements } private allowLabelOverride(): boolean { - return this.resource.scheme !== Schemas.file && this.resource.scheme !== Schemas.vscodeRemote && this.resource.scheme !== Schemas.userData; + return this.resource.scheme !== this.pathService.defaultUriScheme && + this.resource.scheme !== Schemas.userData && + this.resource.scheme !== Schemas.file && + this.resource.scheme !== Schemas.vscodeRemote; } getPreferredName(): string | undefined { @@ -182,7 +187,7 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements setPreferredDescription(description: string): void { if (!this.allowLabelOverride()) { - return; // block for specific schemes we own + return; // block for specific schemes we consider to be owning } if (this.preferredDescription !== description) { From b0509196f61378f636ee8bc4d84fcdb89b29f569 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Thu, 3 Jun 2021 10:21:19 +0200 Subject: [PATCH 04/91] Disable workspace trust during tests --- scripts/test-integration.bat | 2 +- scripts/test-integration.sh | 2 +- .../services/workspaces/common/workspaceTrust.ts | 4 ---- test/automation/src/application.ts | 15 --------------- test/automation/src/code.ts | 1 + 5 files changed, 3 insertions(+), 21 deletions(-) diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat index 0ce9c1ba30b..a28bb307fbd 100644 --- a/scripts/test-integration.bat +++ b/scripts/test-integration.bat @@ -46,7 +46,7 @@ if %errorlevel% neq 0 exit /b %errorlevel% :: Tests in the extension host -set ALL_PLATFORMS_API_TESTS_EXTRA_ARGS=--disable-telemetry --crash-reporter-directory=%VSCODECRASHDIR% --no-cached-data --disable-updates --disable-keytar --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% +set ALL_PLATFORMS_API_TESTS_EXTRA_ARGS=--disable-telemetry --crash-reporter-directory=%VSCODECRASHDIR% --no-cached-data --disable-updates --disable-keytar --disable-extensions --disable-workspace-trust --user-data-dir=%VSCODEUSERDATADIR% call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-api-tests\testWorkspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests %ALL_PLATFORMS_API_TESTS_EXTRA_ARGS% if %errorlevel% neq 0 exit /b %errorlevel% diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index 0b2fe97b17d..e147156da33 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -62,7 +62,7 @@ after_suite # Tests in the extension host -ALL_PLATFORMS_API_TESTS_EXTRA_ARGS="--disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-keytar --disable-extensions --user-data-dir=$VSCODEUSERDATADIR" +ALL_PLATFORMS_API_TESTS_EXTRA_ARGS="--disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-keytar --disable-extensions --disable-workspace-trust --user-data-dir=$VSCODEUSERDATADIR" "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/vscode-api-tests/testWorkspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests $ALL_PLATFORMS_API_TESTS_EXTRA_ARGS after_suite diff --git a/src/vs/workbench/services/workspaces/common/workspaceTrust.ts b/src/vs/workbench/services/workspaces/common/workspaceTrust.ts index 7bfb5124c64..c070ebbb7e1 100644 --- a/src/vs/workbench/services/workspaces/common/workspaceTrust.ts +++ b/src/vs/workbench/services/workspaces/common/workspaceTrust.ts @@ -233,10 +233,6 @@ export class WorkspaceTrustManagementService extends Disposable implements IWork return this._remoteAuthority.options.isTrusted; } - if (this.environmentService.extensionTestsLocationURI) { - return true; // trust running tests with vscode-test - } - if (this.workspaceService.getWorkbenchState() === WorkbenchState.EMPTY) { // Use memento if present, otherwise default to restricted mode // Workspace may transition to trusted based on the opened editors diff --git a/test/automation/src/application.ts b/test/automation/src/application.ts index aec773a75b0..d620cb05a45 100644 --- a/test/automation/src/application.ts +++ b/test/automation/src/application.ts @@ -71,7 +71,6 @@ export class Application { async start(expectWalkthroughPart = true): Promise { await this._start(); await this.code.waitForElement('.explorer-folders-view'); - await this.dismissTrustDialog(); // https://github.com/microsoft/vscode/issues/118748 // if (expectWalkthroughPart) { @@ -84,20 +83,6 @@ export class Application { await new Promise(c => setTimeout(c, 1000)); await this._start(options.workspaceOrFolder, options.extraArgs); await this.code.waitForElement('.explorer-folders-view'); - await this.dismissTrustDialog(); - } - - private async dismissTrustDialog(): Promise { - if (this.options.web) { - return; - } - - try { - // Dismiss workspace trust dialog, if found - await this.code.waitAndClick(`.monaco-workbench .dialog-buttons-row a:nth-child(1)`, 10, 10, 50); - } catch { - // there musn't be any trust dialog, maybe workspace is trusted? - } } private async _start(workspaceOrFolder = this.workspacePathOrFolder, extraArgs: string[] = []): Promise { diff --git a/test/automation/src/code.ts b/test/automation/src/code.ts index aab14d1f0d5..8333471680a 100644 --- a/test/automation/src/code.ts +++ b/test/automation/src/code.ts @@ -140,6 +140,7 @@ export async function spawn(options: SpawnOptions): Promise { '--disable-updates', '--disable-keytar', '--disable-crash-reporter', + '--disable-workspace-trust', `--extensions-dir=${options.extensionsPath}`, `--user-data-dir=${options.userDataDir}`, '--driver', handle From e1b5d625b08f80e753e53423f402695c936f796d Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 3 Jun 2021 22:32:15 +0200 Subject: [PATCH 05/91] Improve `CharacterMapping` API --- .../browser/viewParts/lines/viewLine.ts | 17 ++++--------- .../common/viewLayout/viewLineRenderer.ts | 24 ++++++++++++++++--- .../viewLayout/viewLineRenderer.test.ts | 13 ++++------ 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/vs/editor/browser/viewParts/lines/viewLine.ts b/src/vs/editor/browser/viewParts/lines/viewLine.ts index edec7f7a041..fdbb6f89389 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLine.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLine.ts @@ -606,11 +606,9 @@ class RenderedViewLine implements IRenderedViewLine { return this.getWidth(); } - const partData = this._characterMapping.charOffsetToPartData(column - 1); - const partIndex = CharacterMapping.getPartIndex(partData); - const charOffsetInPart = CharacterMapping.getCharIndex(partData); + const domPosition = this._characterMapping.getDomPosition(column); - const r = RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), partIndex, charOffsetInPart, partIndex, charOffsetInPart, context.clientRectDeltaLeft, context.endNode); + const r = RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), domPosition.partIndex, domPosition.offset, domPosition.partIndex, domPosition.offset, context.clientRectDeltaLeft, context.endNode); if (!r || r.length === 0) { return -1; } @@ -633,15 +631,10 @@ class RenderedViewLine implements IRenderedViewLine { return [new HorizontalRange(0, this.getWidth())]; } - const startPartData = this._characterMapping.charOffsetToPartData(startColumn - 1); - const startPartIndex = CharacterMapping.getPartIndex(startPartData); - const startCharOffsetInPart = CharacterMapping.getCharIndex(startPartData); + const startDomPosition = this._characterMapping.getDomPosition(startColumn); + const endDomPosition = this._characterMapping.getDomPosition(endColumn); - const endPartData = this._characterMapping.charOffsetToPartData(endColumn - 1); - const endPartIndex = CharacterMapping.getPartIndex(endPartData); - const endCharOffsetInPart = CharacterMapping.getCharIndex(endPartData); - - return RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), startPartIndex, startCharOffsetInPart, endPartIndex, endCharOffsetInPart, context.clientRectDeltaLeft, context.endNode); + return RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), startDomPosition.partIndex, startDomPosition.offset, endDomPosition.partIndex, endDomPosition.offset, context.clientRectDeltaLeft, context.endNode); } /** diff --git a/src/vs/editor/common/viewLayout/viewLineRenderer.ts b/src/vs/editor/common/viewLayout/viewLineRenderer.ts index 76f0fc65430..4b24bf373ac 100644 --- a/src/vs/editor/common/viewLayout/viewLineRenderer.ts +++ b/src/vs/editor/common/viewLayout/viewLineRenderer.ts @@ -217,16 +217,23 @@ export const enum CharacterMappingConstants { PART_INDEX_OFFSET = 16 } +export class DomPosition { + constructor( + public readonly partIndex: number, + public readonly offset: number + ) { } +} + /** * Provides a both direction mapping between a line's character and its rendered position. */ export class CharacterMapping { - public static getPartIndex(partData: number): number { + private static getPartIndex(partData: number): number { return (partData & CharacterMappingConstants.PART_INDEX_MASK) >>> CharacterMappingConstants.PART_INDEX_OFFSET; } - public static getCharIndex(partData: number): number { + private static getCharIndex(partData: number): number { return (partData & CharacterMappingConstants.CHAR_INDEX_MASK) >>> CharacterMappingConstants.CHAR_INDEX_OFFSET; } @@ -253,7 +260,7 @@ export class CharacterMapping { return this._absoluteOffsets; } - public charOffsetToPartData(charOffset: number): number { + private charOffsetToPartData(charOffset: number): number { if (this.length === 0) { return 0; } @@ -266,6 +273,17 @@ export class CharacterMapping { return this._data[charOffset]; } + private charOffsetToDOMPosition(charOffset: number): DomPosition { + const partData = this.charOffsetToPartData(charOffset); + const partIndex = CharacterMapping.getPartIndex(partData); + const offset = CharacterMapping.getCharIndex(partData); + return new DomPosition(partIndex, offset); + } + + public getDomPosition(column: number): DomPosition { + return this.charOffsetToDOMPosition(column - 1); + } + public partDataToCharOffset(partIndex: number, partLength: number, charIndex: number): number { if (this.length === 0) { return 0; diff --git a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts index ed5e03b5bd8..0ed70267e16 100644 --- a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts +++ b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts @@ -792,10 +792,8 @@ suite('viewLineRenderer.renderLine', () => { function decodeCharacterMapping(source: CharacterMapping) { const mapping: ICharMappingData[] = []; for (let charOffset = 0; charOffset < source.length; charOffset++) { - const partData = source.charOffsetToPartData(charOffset); - const partIndex = CharacterMapping.getPartIndex(partData); - const charIndex = CharacterMapping.getCharIndex(partData); - mapping.push({ charOffset, partIndex, charIndex }); + const domPosition = source.getDomPosition(charOffset + 1); + mapping.push({ charOffset, partIndex: domPosition.partIndex, charIndex: domPosition.offset }); } const absoluteOffsets: number[] = []; for (const absoluteOffset of source.getAbsoluteOffsets()) { @@ -840,13 +838,10 @@ function assertCharPartOffsets(actual: CharacterMapping, expected: number[][]): for (let partIndex = 0; partIndex < expected.length; partIndex++) { let part = expected[partIndex]; for (const charIndex of part) { - // here - let _actualPartData = actual.charOffsetToPartData(charOffset); - let actualPartIndex = CharacterMapping.getPartIndex(_actualPartData); - let actualCharIndex = CharacterMapping.getCharIndex(_actualPartData); + const actualDOMPosition = actual.getDomPosition(charOffset + 1); assert.deepStrictEqual( - { partIndex: actualPartIndex, charIndex: actualCharIndex }, + { partIndex: actualDOMPosition.partIndex, charIndex: actualDOMPosition.offset }, { partIndex: partIndex, charIndex: charIndex }, `character mapping for offset ${charOffset}` ); From 4dcb02fea1fbf064c494e6207618662ec294251d Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 3 Jun 2021 22:47:09 +0200 Subject: [PATCH 06/91] Pass in column to `CharacterMapping.getAbsoluteOffset` --- src/vs/editor/browser/viewParts/lines/viewLine.ts | 12 ++++-------- src/vs/editor/browser/widget/diffEditorWidget.ts | 3 +-- src/vs/editor/common/viewLayout/viewLineRenderer.ts | 8 ++++++-- .../test/common/viewLayout/viewLineRenderer.test.ts | 9 ++++----- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/vs/editor/browser/viewParts/lines/viewLine.ts b/src/vs/editor/browser/viewParts/lines/viewLine.ts index fdbb6f89389..780f761fc5b 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLine.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLine.ts @@ -430,12 +430,8 @@ class FastRenderedViewLine implements IRenderedViewLine { } private _getCharPosition(column: number): number { - const charOffset = this._characterMapping.getAbsoluteOffsets(); - if (charOffset.length === 0) { - // No characters on this line - return 0; - } - return Math.round(this._charWidth * charOffset[column - 1]); + const charOffset = this._characterMapping.getAbsoluteOffset(column); + return Math.round(this._charWidth * charOffset); } public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number { @@ -614,8 +610,8 @@ class RenderedViewLine implements IRenderedViewLine { } const result = r[0].left; if (this.input.isBasicASCII) { - const charOffset = this._characterMapping.getAbsoluteOffsets(); - const expectedResult = Math.round(this.input.spaceWidth * charOffset[column - 1]); + const charOffset = this._characterMapping.getAbsoluteOffset(column); + const expectedResult = Math.round(this.input.spaceWidth * charOffset); if (Math.abs(expectedResult - result) <= 1) { return expectedResult; } diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index ec7c270000f..c4a791e9ab3 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -2513,8 +2513,7 @@ class InlineViewZonesComputer extends ViewZonesComputer { marginDomNode.appendChild(marginElement); } - const absoluteOffsets = output.characterMapping.getAbsoluteOffsets(); - return absoluteOffsets.length > 0 ? absoluteOffsets[absoluteOffsets.length - 1] : 0; + return output.characterMapping.getAbsoluteOffset(output.characterMapping.length); } } diff --git a/src/vs/editor/common/viewLayout/viewLineRenderer.ts b/src/vs/editor/common/viewLayout/viewLineRenderer.ts index 4b24bf373ac..38a6f4b4899 100644 --- a/src/vs/editor/common/viewLayout/viewLineRenderer.ts +++ b/src/vs/editor/common/viewLayout/viewLineRenderer.ts @@ -256,8 +256,12 @@ export class CharacterMapping { this._absoluteOffsets[charOffset] = partAbsoluteOffset + charIndex; } - public getAbsoluteOffsets(): Uint32Array { - return this._absoluteOffsets; + public getAbsoluteOffset(column: number): number { + if (this._absoluteOffsets.length === 0) { + // No characters on this line + return 0; + } + return this._absoluteOffsets[column - 1]; } private charOffsetToPartData(charOffset: number): number { diff --git a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts index 0ed70267e16..04cc3dfa478 100644 --- a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts +++ b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts @@ -796,8 +796,8 @@ suite('viewLineRenderer.renderLine', () => { mapping.push({ charOffset, partIndex: domPosition.partIndex, charIndex: domPosition.offset }); } const absoluteOffsets: number[] = []; - for (const absoluteOffset of source.getAbsoluteOffsets()) { - absoluteOffsets.push(absoluteOffset); + for (let i = 0; i < source.length; i++) { + absoluteOffsets[i] = source.getAbsoluteOffset(i + 1); } return { mapping, absoluteOffsets }; } @@ -825,9 +825,8 @@ function assertCharacterMapping(actual: CharacterMapping, expectedCharPartOffset } let actualCharOffset: number[] = []; - let tmp = actual.getAbsoluteOffsets(); - for (let i = 0; i < tmp.length; i++) { - actualCharOffset[i] = tmp[i]; + for (let i = 0; i < actual.length; i++) { + actualCharOffset[i] = actual.getAbsoluteOffset(i + 1); } assert.deepStrictEqual(actualCharOffset, expectedCharAbsoluteOffset); } From f715b7de9742ecb181eaa955746051e3a9ed596d Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 3 Jun 2021 23:04:32 +0200 Subject: [PATCH 07/91] Minor renames --- src/vs/editor/browser/viewParts/lines/viewLine.ts | 4 ++-- .../editor/common/viewLayout/viewLineRenderer.ts | 14 +++++--------- .../common/viewLayout/viewLineRenderer.test.ts | 4 ++-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/vs/editor/browser/viewParts/lines/viewLine.ts b/src/vs/editor/browser/viewParts/lines/viewLine.ts index 780f761fc5b..4e00c4c5aa1 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLine.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLine.ts @@ -604,7 +604,7 @@ class RenderedViewLine implements IRenderedViewLine { const domPosition = this._characterMapping.getDomPosition(column); - const r = RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), domPosition.partIndex, domPosition.offset, domPosition.partIndex, domPosition.offset, context.clientRectDeltaLeft, context.endNode); + const r = RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), domPosition.partIndex, domPosition.charIndex, domPosition.partIndex, domPosition.charIndex, context.clientRectDeltaLeft, context.endNode); if (!r || r.length === 0) { return -1; } @@ -630,7 +630,7 @@ class RenderedViewLine implements IRenderedViewLine { const startDomPosition = this._characterMapping.getDomPosition(startColumn); const endDomPosition = this._characterMapping.getDomPosition(endColumn); - return RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), startDomPosition.partIndex, startDomPosition.offset, endDomPosition.partIndex, endDomPosition.offset, context.clientRectDeltaLeft, context.endNode); + return RangeUtil.readHorizontalRanges(this._getReadingTarget(domNode), startDomPosition.partIndex, startDomPosition.charIndex, endDomPosition.partIndex, endDomPosition.charIndex, context.clientRectDeltaLeft, context.endNode); } /** diff --git a/src/vs/editor/common/viewLayout/viewLineRenderer.ts b/src/vs/editor/common/viewLayout/viewLineRenderer.ts index 38a6f4b4899..b94ff290965 100644 --- a/src/vs/editor/common/viewLayout/viewLineRenderer.ts +++ b/src/vs/editor/common/viewLayout/viewLineRenderer.ts @@ -220,7 +220,7 @@ export const enum CharacterMappingConstants { export class DomPosition { constructor( public readonly partIndex: number, - public readonly offset: number + public readonly charIndex: number ) { } } @@ -277,15 +277,11 @@ export class CharacterMapping { return this._data[charOffset]; } - private charOffsetToDOMPosition(charOffset: number): DomPosition { - const partData = this.charOffsetToPartData(charOffset); - const partIndex = CharacterMapping.getPartIndex(partData); - const offset = CharacterMapping.getCharIndex(partData); - return new DomPosition(partIndex, offset); - } - public getDomPosition(column: number): DomPosition { - return this.charOffsetToDOMPosition(column - 1); + const partData = this.charOffsetToPartData(column - 1); + const partIndex = CharacterMapping.getPartIndex(partData); + const charIndex = CharacterMapping.getCharIndex(partData); + return new DomPosition(partIndex, charIndex); } public partDataToCharOffset(partIndex: number, partLength: number, charIndex: number): number { diff --git a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts index 04cc3dfa478..6d45c0ade3e 100644 --- a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts +++ b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts @@ -793,7 +793,7 @@ suite('viewLineRenderer.renderLine', () => { const mapping: ICharMappingData[] = []; for (let charOffset = 0; charOffset < source.length; charOffset++) { const domPosition = source.getDomPosition(charOffset + 1); - mapping.push({ charOffset, partIndex: domPosition.partIndex, charIndex: domPosition.offset }); + mapping.push({ charOffset, partIndex: domPosition.partIndex, charIndex: domPosition.charIndex }); } const absoluteOffsets: number[] = []; for (let i = 0; i < source.length; i++) { @@ -840,7 +840,7 @@ function assertCharPartOffsets(actual: CharacterMapping, expected: number[][]): const actualDOMPosition = actual.getDomPosition(charOffset + 1); assert.deepStrictEqual( - { partIndex: actualDOMPosition.partIndex, charIndex: actualDOMPosition.offset }, + { partIndex: actualDOMPosition.partIndex, charIndex: actualDOMPosition.charIndex }, { partIndex: partIndex, charIndex: charIndex }, `character mapping for offset ${charOffset}` ); From c4b1317d2efc466b5f790918abf35847fb0b1919 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 4 Jun 2021 00:53:04 +0200 Subject: [PATCH 08/91] Simplify tests --- .../viewLayout/viewLineRenderer.test.ts | 243 ++++++++---------- 1 file changed, 113 insertions(+), 130 deletions(-) diff --git a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts index 6d45c0ade3e..f36dc8b2c6a 100644 --- a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts +++ b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts @@ -9,7 +9,7 @@ import * as strings from 'vs/base/common/strings'; import { IViewLineTokens } from 'vs/editor/common/core/lineTokens'; import { MetadataConsts } from 'vs/editor/common/modes'; import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations'; -import { CharacterMapping, RenderLineInput, renderViewLine2 as renderViewLine, LineRange } from 'vs/editor/common/viewLayout/viewLineRenderer'; +import { CharacterMapping, RenderLineInput, renderViewLine2 as renderViewLine, LineRange, DomPosition } from 'vs/editor/common/viewLayout/viewLineRenderer'; import { InlineDecorationType } from 'vs/editor/common/viewModel/viewModel'; import { ViewLineToken, ViewLineTokens } from 'vs/editor/test/common/core/viewLineToken'; @@ -25,8 +25,8 @@ function createPart(endIndex: number, foreground: number): ViewLineToken { suite('viewLineRenderer.renderLine', () => { - function assertCharacterReplacement(lineContent: string, tabSize: number, expected: string, expectedCharOffsetInPart: number[][], expectedPartLengts: number[]): void { - let _actual = renderViewLine(new RenderLineInput( + function assertCharacterReplacement(lineContent: string, tabSize: number, expected: string, expectedCharOffsetInPart: number[]): void { + const _actual = renderViewLine(new RenderLineInput( false, true, lineContent, @@ -49,36 +49,37 @@ suite('viewLineRenderer.renderLine', () => { )); assert.strictEqual(_actual.html, '' + expected + ''); - assertCharacterMapping(_actual.characterMapping, expectedCharOffsetInPart, expectedPartLengts); + const info = expectedCharOffsetInPart.map((absoluteOffset) => [absoluteOffset, [0, absoluteOffset]]); + assertCharacterMapping3(_actual.characterMapping, info); } test('replaces spaces', () => { - assertCharacterReplacement(' ', 4, '\u00a0', [[0, 1]], [1]); - assertCharacterReplacement(' ', 4, '\u00a0\u00a0', [[0, 1, 2]], [2]); - assertCharacterReplacement('a b', 4, 'a\u00a0\u00a0b', [[0, 1, 2, 3, 4]], [4]); + assertCharacterReplacement(' ', 4, '\u00a0', [0, 1]); + assertCharacterReplacement(' ', 4, '\u00a0\u00a0', [0, 1, 2]); + assertCharacterReplacement('a b', 4, 'a\u00a0\u00a0b', [0, 1, 2, 3, 4]); }); test('escapes HTML markup', () => { - assertCharacterReplacement('ab', 4, 'a>b', [[0, 1, 2, 3]], [3]); - assertCharacterReplacement('a&b', 4, 'a&b', [[0, 1, 2, 3]], [3]); + assertCharacterReplacement('ab', 4, 'a>b', [0, 1, 2, 3]); + assertCharacterReplacement('a&b', 4, 'a&b', [0, 1, 2, 3]); }); test('replaces some bad characters', () => { - assertCharacterReplacement('a\0b', 4, 'a�b', [[0, 1, 2, 3]], [3]); - assertCharacterReplacement('a' + String.fromCharCode(CharCode.UTF8_BOM) + 'b', 4, 'a\ufffdb', [[0, 1, 2, 3]], [3]); - assertCharacterReplacement('a\u2028b', 4, 'a\ufffdb', [[0, 1, 2, 3]], [3]); + assertCharacterReplacement('a\0b', 4, 'a�b', [0, 1, 2, 3]); + assertCharacterReplacement('a' + String.fromCharCode(CharCode.UTF8_BOM) + 'b', 4, 'a\ufffdb', [0, 1, 2, 3]); + assertCharacterReplacement('a\u2028b', 4, 'a\ufffdb', [0, 1, 2, 3]); }); test('handles tabs', () => { - assertCharacterReplacement('\t', 4, '\u00a0\u00a0\u00a0\u00a0', [[0, 4]], [4]); - assertCharacterReplacement('x\t', 4, 'x\u00a0\u00a0\u00a0', [[0, 1, 4]], [4]); - assertCharacterReplacement('xx\t', 4, 'xx\u00a0\u00a0', [[0, 1, 2, 4]], [4]); - assertCharacterReplacement('xxx\t', 4, 'xxx\u00a0', [[0, 1, 2, 3, 4]], [4]); - assertCharacterReplacement('xxxx\t', 4, 'xxxx\u00a0\u00a0\u00a0\u00a0', [[0, 1, 2, 3, 4, 8]], [8]); + assertCharacterReplacement('\t', 4, '\u00a0\u00a0\u00a0\u00a0', [0, 4]); + assertCharacterReplacement('x\t', 4, 'x\u00a0\u00a0\u00a0', [0, 1, 4]); + assertCharacterReplacement('xx\t', 4, 'xx\u00a0\u00a0', [0, 1, 2, 4]); + assertCharacterReplacement('xxx\t', 4, 'xxx\u00a0', [0, 1, 2, 3, 4]); + assertCharacterReplacement('xxxx\t', 4, 'xxxx\u00a0\u00a0\u00a0\u00a0', [0, 1, 2, 3, 4, 8]); }); - function assertParts(lineContent: string, tabSize: number, parts: ViewLineToken[], expected: string, expectedCharOffsetInPart: number[][], expectedPartLengts: number[]): void { + function assertParts(lineContent: string, tabSize: number, parts: ViewLineToken[], expected: string, info: CharacterMappingInfo[]): void { let _actual = renderViewLine(new RenderLineInput( false, true, @@ -102,23 +103,23 @@ suite('viewLineRenderer.renderLine', () => { )); assert.strictEqual(_actual.html, '' + expected + ''); - assertCharacterMapping(_actual.characterMapping, expectedCharOffsetInPart, expectedPartLengts); + assertCharacterMapping3(_actual.characterMapping, info); } test('empty line', () => { - assertParts('', 4, [], '', [], []); + assertParts('', 4, [], '', []); }); test('uses part type', () => { - assertParts('x', 4, [createPart(1, 10)], 'x', [[0, 1]], [1]); - assertParts('x', 4, [createPart(1, 20)], 'x', [[0, 1]], [1]); - assertParts('x', 4, [createPart(1, 30)], 'x', [[0, 1]], [1]); + assertParts('x', 4, [createPart(1, 10)], 'x', [[0, [0, 0]], [1, [0, 1]]]); + assertParts('x', 4, [createPart(1, 20)], 'x', [[0, [0, 0]], [1, [0, 1]]]); + assertParts('x', 4, [createPart(1, 30)], 'x', [[0, [0, 0]], [1, [0, 1]]]); }); test('two parts', () => { - assertParts('xy', 4, [createPart(1, 1), createPart(2, 2)], 'xy', [[0], [0, 1]], [1, 1]); - assertParts('xyz', 4, [createPart(1, 1), createPart(3, 2)], 'xyz', [[0], [0, 1, 2]], [1, 2]); - assertParts('xyz', 4, [createPart(2, 1), createPart(3, 2)], 'xyz', [[0, 1], [0, 1]], [2, 1]); + assertParts('xy', 4, [createPart(1, 1), createPart(2, 2)], 'xy', [[0, [0, 0]], [1, [1, 0]], [2, [1, 1]]]); + assertParts('xyz', 4, [createPart(1, 1), createPart(3, 2)], 'xyz', [[0, [0, 0]], [1, [1, 0]], [2, [1, 1]], [3, [1, 2]]]); + assertParts('xyz', 4, [createPart(2, 1), createPart(3, 2)], 'xyz', [[0, [0, 0]], [1, [0, 1]], [2, [1, 0]], [3, [1, 1]]]); }); test('overflow', () => { @@ -168,16 +169,17 @@ suite('viewLineRenderer.renderLine', () => { ].join(''); assert.strictEqual(_actual.html, '' + expectedOutput + ''); - assertCharacterMapping(_actual.characterMapping, + assertCharacterMapping3( + _actual.characterMapping, [ - [0], - [0], - [0], - [0], - [0], - [0, 1], - ], - [1, 1, 1, 1, 1, 1] + [0, [0, 0]], + [1, [1, 0]], + [2, [2, 0]], + [3, [3, 0]], + [4, [4, 0]], + [5, [5, 0]], + [6, [5, 1]], + ] ); }); @@ -213,24 +215,25 @@ suite('viewLineRenderer.renderLine', () => { '\u00b7\u00b7', '\u00b7\u00b7\u00b7' ].join(''); - let expectedOffsetsArr = [ - [0], - [0, 1, 2, 3], - [0, 1, 2, 3, 4, 5], - [0], - [0, 1, 2, 3, 4], - [0], - [0, 1, 2, 3], - [0], - [0], - [0], - [0, 1, 2], - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], - [0, 1], - [0, 1, 2, 3], + + const info: CharacterMappingInfo[] = [ + [0, [0, 0]], + [4, [1, 0]], [5, [1, 1]], [6, [1, 2]], [7, [1, 3]], + [8, [2, 0]], [9, [2, 1]], [10, [2, 2]], [11, [2, 3]], [12, [2, 4]], [13, [2, 5]], + [14, [3, 0]], + [15, [4, 0]], [16, [4, 1]], [17, [4, 2]], [18, [4, 3]], [19, [4, 4]], + [20, [5, 0]], + [21, [6, 0]], [22, [6, 1]], [23, [6, 2]], [24, [6, 3]], + [25, [7, 0]], + [26, [8, 0]], + [27, [9, 0]], + [28, [10, 0]], [29, [10, 1]], [30, [10, 2]], + [31, [11, 0]], [32, [11, 1]], [33, [11, 2]], [34, [11, 3]], [35, [11, 4]], [36, [11, 5]], [37, [11, 6]], [38, [11, 7]], [39, [11, 8]], [40, [11, 9]], [41, [11, 10]], [42, [11, 11]], [43, [11, 12]], [44, [11, 13]], [45, [11, 14]], + [46, [12, 0]], [47, [12, 1]], + [48, [13, 0]], [49, [13, 1]], [50, [13, 2]], [51, [13, 3]], ]; - let _actual = renderViewLine(new RenderLineInput( + const _actual = renderViewLine(new RenderLineInput( false, true, lineText, @@ -253,7 +256,7 @@ suite('viewLineRenderer.renderLine', () => { )); assert.strictEqual(_actual.html, '' + expectedOutput + ''); - assertCharacterMapping(_actual.characterMapping, expectedOffsetsArr, [4, 4, 6, 1, 5, 1, 4, 1, 1, 1, 3, 15, 2, 3]); + assertCharacterMapping3(_actual.characterMapping, info); }); test('issue #2255: Weird line rendering part 1', () => { @@ -283,20 +286,21 @@ suite('viewLineRenderer.renderLine', () => { ')', ',', ].join(''); - let expectedOffsetsArr = [ - [0, 4, 8], // 3 chars - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], // 12 chars - [0, 4, 8, 12, 16, 20], // 6 chars - [0], // 1 char - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], // 21 chars - [0, 1], // 2 chars - [0], // 1 char - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], // 20 chars - [0], // 1 char - [0, 1] // 2 chars + + const info: CharacterMappingInfo[] = [ + [0, [0, 0]], [4, [0, 4]], [8, [0, 8]], + [12, [1, 0]], [13, [1, 1]], [14, [1, 2]], [15, [1, 3]], [16, [1, 4]], [17, [1, 5]], [18, [1, 6]], [19, [1, 7]], [20, [1, 8]], [21, [1, 9]], [22, [1, 10]], [23, [1, 11]], + [24, [2, 0]], [28, [2, 4]], [32, [2, 8]], [36, [2, 12]], [40, [2, 16]], [44, [2, 20]], + [48, [3, 0]], + [49, [4, 0]], [50, [4, 1]], [51, [4, 2]], [52, [4, 3]], [53, [4, 4]], [54, [4, 5]], [55, [4, 6]], [56, [4, 7]], [57, [4, 8]], [58, [4, 9]], [59, [4, 10]], [60, [4, 11]], [61, [4, 12]], [62, [4, 13]], [63, [4, 14]], [64, [4, 15]], [65, [4, 16]], [66, [4, 17]], [67, [4, 18]], [68, [4, 19]], [69, [4, 20]], + [70, [5, 0]], [71, [5, 1]], + [72, [6, 0]], + [73, [7, 0]], [74, [7, 1]], [75, [7, 2]], [76, [7, 3]], [77, [7, 4]], [78, [7, 5]], [79, [7, 6]], [80, [7, 7]], [81, [7, 8]], [82, [7, 9]], [83, [7, 10]], [84, [7, 11]], [85, [7, 12]], [86, [7, 13]], [87, [7, 14]], [88, [7, 15]], [89, [7, 16]], [90, [7, 17]], [91, [7, 18]], [92, [7, 19]], + [93, [8, 0]], + [94, [9, 0]], [95, [9, 1]], ]; - let _actual = renderViewLine(new RenderLineInput( + const _actual = renderViewLine(new RenderLineInput( false, true, lineText, @@ -319,7 +323,7 @@ suite('viewLineRenderer.renderLine', () => { )); assert.strictEqual(_actual.html, '' + expectedOutput + ''); - assertCharacterMapping(_actual.characterMapping, expectedOffsetsArr, [12, 12, 24, 1, 21, 2, 1, 20, 1, 1]); + assertCharacterMapping3(_actual.characterMapping, info); }); test('issue #2255: Weird line rendering part 2', () => { @@ -349,20 +353,21 @@ suite('viewLineRenderer.renderLine', () => { ')', ',', ].join(''); - let expectedOffsetsArr = [ - [0, 1, 4, 8], // 4 chars - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], // 12 chars - [0, 4, 8, 12, 16, 20], // 6 chars - [0], // 1 char - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], // 21 chars - [0, 1], // 2 chars - [0], // 1 char - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], // 20 chars - [0], // 1 char - [0, 1] // 2 chars + + const info: CharacterMappingInfo[] = [ + [0, [0, 0]], [1, [0, 1]], [4, [0, 4]], [8, [0, 8]], + [12, [1, 0]], [13, [1, 1]], [14, [1, 2]], [15, [1, 3]], [16, [1, 4]], [17, [1, 5]], [18, [1, 6]], [19, [1, 7]], [20, [1, 8]], [21, [1, 9]], [22, [1, 10]], [23, [1, 11]], + [24, [2, 0]], [28, [2, 4]], [32, [2, 8]], [36, [2, 12]], [40, [2, 16]], [44, [2, 20]], + [48, [3, 0]], + [49, [4, 0]], [50, [4, 1]], [51, [4, 2]], [52, [4, 3]], [53, [4, 4]], [54, [4, 5]], [55, [4, 6]], [56, [4, 7]], [57, [4, 8]], [58, [4, 9]], [59, [4, 10]], [60, [4, 11]], [61, [4, 12]], [62, [4, 13]], [63, [4, 14]], [64, [4, 15]], [65, [4, 16]], [66, [4, 17]], [67, [4, 18]], [68, [4, 19]], [69, [4, 20]], + [70, [5, 0]], [71, [5, 1]], + [72, [6, 0]], + [73, [7, 0]], [74, [7, 1]], [75, [7, 2]], [76, [7, 3]], [77, [7, 4]], [78, [7, 5]], [79, [7, 6]], [80, [7, 7]], [81, [7, 8]], [82, [7, 9]], [83, [7, 10]], [84, [7, 11]], [85, [7, 12]], [86, [7, 13]], [87, [7, 14]], [88, [7, 15]], [89, [7, 16]], [90, [7, 17]], [91, [7, 18]], [92, [7, 19]], + [93, [8, 0]], + [94, [9, 0]], [95, [9, 1]], ]; - let _actual = renderViewLine(new RenderLineInput( + const _actual = renderViewLine(new RenderLineInput( false, true, lineText, @@ -385,7 +390,7 @@ suite('viewLineRenderer.renderLine', () => { )); assert.strictEqual(_actual.html, '' + expectedOutput + ''); - assertCharacterMapping(_actual.characterMapping, expectedOffsetsArr, [12, 12, 24, 1, 21, 2, 1, 20, 1, 1]); + assertCharacterMapping3(_actual.characterMapping, info); }); test('issue #91178: after decoration type shown before cursor', () => { @@ -809,56 +814,33 @@ suite('viewLineRenderer.renderLine', () => { } }); -function assertCharacterMapping(actual: CharacterMapping, expectedCharPartOffsets: number[][], expectedPartLengths: number[]): void { +type CharacterMappingInfo = [number, [number, number]]; - assertCharPartOffsets(actual, expectedCharPartOffsets); +function assertCharacterMapping3(actual: CharacterMapping, expectedInfo: CharacterMappingInfo[]): void { + for (let i = 0; i < expectedInfo.length; i++) { + const [absoluteOffset, [partIndex, charIndex]] = expectedInfo[i]; - let expectedCharAbsoluteOffset: number[] = [], currentPartAbsoluteOffset = 0; - for (let partIndex = 0; partIndex < expectedCharPartOffsets.length; partIndex++) { - const part = expectedCharPartOffsets[partIndex]; + const actualDomPosition = actual.getDomPosition(i + 1); + assert.deepStrictEqual(actualDomPosition, new DomPosition(partIndex, charIndex), `getDomPosition(${i + 1})`); - for (const charIndex of part) { - expectedCharAbsoluteOffset.push(currentPartAbsoluteOffset + charIndex); + let partLength = charIndex + 1; + for (let j = i + 1; j < expectedInfo.length; j++) { + const [, [nextPartIndex, nextCharIndex]] = expectedInfo[j]; + if (nextPartIndex === partIndex) { + partLength = nextCharIndex + 1; + } else { + break; + } } - currentPartAbsoluteOffset += expectedPartLengths[partIndex]; + const actualOffset = actual.partDataToCharOffset(partIndex, partLength, charIndex); + assert.strictEqual(actualOffset, i, `actual.partDataToCharOffset(${partIndex}, ${charIndex})`); + + const actualAbsoluteOffset = actual.getAbsoluteOffset(i + 1); + assert.strictEqual(actualAbsoluteOffset, absoluteOffset, `actual.getAbsoluteOffset(${i + 1})`); } - let actualCharOffset: number[] = []; - for (let i = 0; i < actual.length; i++) { - actualCharOffset[i] = actual.getAbsoluteOffset(i + 1); - } - assert.deepStrictEqual(actualCharOffset, expectedCharAbsoluteOffset); -} - -function assertCharPartOffsets(actual: CharacterMapping, expected: number[][]): void { - - let charOffset = 0; - for (let partIndex = 0; partIndex < expected.length; partIndex++) { - let part = expected[partIndex]; - for (const charIndex of part) { - const actualDOMPosition = actual.getDomPosition(charOffset + 1); - - assert.deepStrictEqual( - { partIndex: actualDOMPosition.partIndex, charIndex: actualDOMPosition.charIndex }, - { partIndex: partIndex, charIndex: charIndex }, - `character mapping for offset ${charOffset}` - ); - - // here - let actualOffset = actual.partDataToCharOffset(partIndex, part[part.length - 1] + 1, charIndex); - - assert.strictEqual( - actualOffset, - charOffset, - `character mapping for part ${partIndex}, ${charIndex}` - ); - - charOffset++; - } - } - - assert.strictEqual(actual.length, charOffset); + assert.strictEqual(actual.length, expectedInfo.length, `length mismatch`); } suite('viewLineRenderer.renderLine 2', () => { @@ -2166,15 +2148,16 @@ suite('viewLineRenderer.renderLine 2', () => { ].join(''); assert.deepStrictEqual(actual.html, expected); - assertCharacterMapping(actual.characterMapping, + assertCharacterMapping3(actual.characterMapping, [ - [0, 1, 2, 3], - [0, 1], - [], - [0], - [], - ], - [4, 2, 0, 0] + [0, [0, 0]], + [1, [0, 1]], + [2, [0, 2]], + [3, [0, 3]], + [4, [1, 0]], + [5, [1, 1]], + [6, [3, 0]], + ] ); }); From a2ef11ff55376920abda9c7dcc9b07f17affad29 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 3 Jun 2021 19:08:23 -0700 Subject: [PATCH 09/91] fixes context keys with menubar --- .../browser/parts/titlebar/menubarControl.ts | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 71a85d0fd79..7d5201ed058 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -14,7 +14,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { isMacintosh, isWeb, isIOS, isNative } from 'vs/base/common/platform'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; import { Event, Emitter } from 'vs/base/common/event'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IRecentlyOpened, isRecentFolder, IRecent, isRecentWorkspace, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces'; import { RunOnceScheduler } from 'vs/base/common/async'; import { MENUBAR_SELECTION_FOREGROUND, MENUBAR_SELECTION_BACKGROUND, MENUBAR_SELECTION_BORDER, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_INACTIVE_FOREGROUND } from 'vs/workbench/common/theme'; @@ -173,16 +173,29 @@ export abstract class MenubarControl extends Disposable { super(); - const mainMenu = this.menuService.createMenu(MenuId.MenubarMainMenu, this.contextKeyService); - const [, mainMenuActions] = mainMenu.getActions()[0]; - for (const mainMenuAction of mainMenuActions) { - if (mainMenuAction instanceof SubmenuItemAction && typeof mainMenuAction.item.title !== 'string') { - this.menus[mainMenuAction.item.title.original] = this._register(this.menuService.createMenu(mainMenuAction.item.submenu, this.contextKeyService)); - this.topLevelTitles[mainMenuAction.item.title.original] = mainMenuAction.item.title.mnemonicTitle ?? mainMenuAction.item.title.value; - } - } + const mainMenu = this._register(this.menuService.createMenu(MenuId.MenubarMainMenu, this.contextKeyService)); + const mainMenuDisposables = this._register(new DisposableStore()); - mainMenu.dispose(); + const setupMenu = () => { + mainMenuDisposables.clear(); + this.menus = {}; + this.topLevelTitles = {}; + + const [, mainMenuActions] = mainMenu.getActions()[0]; + for (const mainMenuAction of mainMenuActions) { + if (mainMenuAction instanceof SubmenuItemAction && typeof mainMenuAction.item.title !== 'string') { + this.menus[mainMenuAction.item.title.original] = mainMenuDisposables.add(this.menuService.createMenu(mainMenuAction.item.submenu, this.contextKeyService)); + this.topLevelTitles[mainMenuAction.item.title.original] = mainMenuAction.item.title.mnemonicTitle ?? mainMenuAction.item.title.value; + } + } + }; + + setupMenu(); + + mainMenu.onDidChange(() => { + setupMenu(); + this.doUpdateMenubar(true); + }); this.menuUpdater = this._register(new RunOnceScheduler(() => this.doUpdateMenubar(false), 200)); @@ -624,6 +637,7 @@ export class CustomMenubarControl extends MenubarControl { this._onVisibilityChange.fire(visible); } + private reinstallDisposables = this._register(new DisposableStore()); private setupCustomMenubar(firstTime: boolean): void { // If there is no container, we cannot setup the menubar if (!this.container) { @@ -631,14 +645,19 @@ export class CustomMenubarControl extends MenubarControl { } if (firstTime) { - this.menubar = this._register(new MenuBar(this.container, this.getMenuBarOptions())); + // Reset and create new menubar + if (this.menubar) { + this.reinstallDisposables.clear(); + } + + this.menubar = this.reinstallDisposables.add(new MenuBar(this.container, this.getMenuBarOptions())); this.accessibilityService.alwaysUnderlineAccessKeys().then(val => { this.alwaysOnMnemonics = val; this.menubar?.update(this.getMenuBarOptions()); }); - this._register(this.menubar.onFocusStateChange(focused => { + this.reinstallDisposables.add(this.menubar.onFocusStateChange(focused => { this._onFocusStateChange.fire(focused); // When the menubar loses focus, update it to clear any pending updates @@ -648,18 +667,18 @@ export class CustomMenubarControl extends MenubarControl { } })); - this._register(this.menubar.onVisibilityChange(e => this.onDidVisibilityChange(e))); + this.reinstallDisposables.add(this.menubar.onVisibilityChange(e => this.onDidVisibilityChange(e))); // Before we focus the menubar, stop updates to it so that focus-related context keys will work - this._register(addDisposableListener(this.container, EventType.FOCUS_IN, () => { + this.reinstallDisposables.add(addDisposableListener(this.container, EventType.FOCUS_IN, () => { this.focusInsideMenubar = true; })); - this._register(addDisposableListener(this.container, EventType.FOCUS_OUT, () => { + this.reinstallDisposables.add(addDisposableListener(this.container, EventType.FOCUS_OUT, () => { this.focusInsideMenubar = false; })); - this._register(attachMenuStyler(this.menubar, this.themeService)); + this.reinstallDisposables.add(attachMenuStyler(this.menubar, this.themeService)); } else { this.menubar?.update(this.getMenuBarOptions()); } @@ -727,7 +746,7 @@ export class CustomMenubarControl extends MenubarControl { for (const title of Object.keys(this.topLevelTitles)) { const menu = this.menus[title]; if (firstTime && menu) { - this._register(menu.onDidChange(() => { + this.reinstallDisposables.add(menu.onDidChange(() => { if (!this.focusInsideMenubar) { const actions: IAction[] = []; updateActions(menu, actions, title); @@ -739,7 +758,7 @@ export class CustomMenubarControl extends MenubarControl { // For the file menu, we need to update if the web nav menu updates as well if (menu === this.menus.File) { - this._register(this.webNavigationMenu.onDidChange(() => { + this.reinstallDisposables.add(this.webNavigationMenu.onDidChange(() => { if (!this.focusInsideMenubar) { const actions: IAction[] = []; updateActions(menu, actions, title); From 4202b755befc3d33ad6f1373d358d7cdae14543d Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 4 Jun 2021 07:51:31 +0200 Subject: [PATCH 10/91] Add `CharacterMapping.getColumn` --- src/vs/editor/browser/viewParts/lines/viewLine.ts | 8 +++----- src/vs/editor/common/viewLayout/viewLineRenderer.ts | 7 ++++++- .../test/common/viewLayout/viewLineRenderer.test.ts | 9 ++++----- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/browser/viewParts/lines/viewLine.ts b/src/vs/editor/browser/viewParts/lines/viewLine.ts index 4e00c4c5aa1..3745a64d68d 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLine.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLine.ts @@ -12,7 +12,7 @@ import { IStringBuilder } from 'vs/editor/common/core/stringBuilder'; import { IConfiguration } from 'vs/editor/common/editorCommon'; import { HorizontalRange, VisibleRanges } from 'vs/editor/common/view/renderingContext'; import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations'; -import { CharacterMapping, ForeignElementType, RenderLineInput, renderViewLine, LineRange } from 'vs/editor/common/viewLayout/viewLineRenderer'; +import { CharacterMapping, ForeignElementType, RenderLineInput, renderViewLine, LineRange, DomPosition } from 'vs/editor/common/viewLayout/viewLineRenderer'; import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; import { InlineDecorationType } from 'vs/editor/common/viewModel/viewModel'; import { ColorScheme } from 'vs/platform/theme/common/theme'; @@ -443,8 +443,7 @@ class FastRenderedViewLine implements IRenderedViewLine { spanIndex++; } - const charOffset = this._characterMapping.partDataToCharOffset(spanIndex, spanNodeTextContentLength, offset); - return charOffset + 1; + return this._characterMapping.getColumn(new DomPosition(spanIndex, offset), spanNodeTextContentLength); } } @@ -645,8 +644,7 @@ class RenderedViewLine implements IRenderedViewLine { spanIndex++; } - const charOffset = this._characterMapping.partDataToCharOffset(spanIndex, spanNodeTextContentLength, offset); - return charOffset + 1; + return this._characterMapping.getColumn(new DomPosition(spanIndex, offset), spanNodeTextContentLength); } } diff --git a/src/vs/editor/common/viewLayout/viewLineRenderer.ts b/src/vs/editor/common/viewLayout/viewLineRenderer.ts index b94ff290965..5e3bedacb48 100644 --- a/src/vs/editor/common/viewLayout/viewLineRenderer.ts +++ b/src/vs/editor/common/viewLayout/viewLineRenderer.ts @@ -284,7 +284,12 @@ export class CharacterMapping { return new DomPosition(partIndex, charIndex); } - public partDataToCharOffset(partIndex: number, partLength: number, charIndex: number): number { + public getColumn(domPosition: DomPosition, partLength: number): number { + const charOffset = this.partDataToCharOffset(domPosition.partIndex, partLength, domPosition.charIndex); + return charOffset + 1; + } + + private partDataToCharOffset(partIndex: number, partLength: number, charIndex: number): number { if (this.length === 0) { return 0; } diff --git a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts index f36dc8b2c6a..978eb8f06e0 100644 --- a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts +++ b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts @@ -833,8 +833,8 @@ function assertCharacterMapping3(actual: CharacterMapping, expectedInfo: Charact } } - const actualOffset = actual.partDataToCharOffset(partIndex, partLength, charIndex); - assert.strictEqual(actualOffset, i, `actual.partDataToCharOffset(${partIndex}, ${charIndex})`); + const actualColumn = actual.getColumn(new DomPosition(partIndex, charIndex), partLength); + assert.strictEqual(actualColumn, i + 1, `actual.getColumn(${partIndex}, ${charIndex})`); const actualAbsoluteOffset = actual.getAbsoluteOffset(i + 1); assert.strictEqual(actualAbsoluteOffset, absoluteOffset, `actual.getAbsoluteOffset(${i + 1})`); @@ -2186,9 +2186,8 @@ suite('viewLineRenderer.renderLine 2', () => { )); return (partIndex: number, partLength: number, offset: number, expected: number) => { - let charOffset = renderLineOutput.characterMapping.partDataToCharOffset(partIndex, partLength, offset); - let actual = charOffset + 1; - assert.strictEqual(actual, expected, 'getColumnOfLinePartOffset for ' + partIndex + ' @ ' + offset); + const actualColumn = renderLineOutput.characterMapping.getColumn(new DomPosition(partIndex, offset), partLength); + assert.strictEqual(actualColumn, expected, 'getColumn for ' + partIndex + ', ' + offset); }; } From d6db1362ea41df87a744fc75872c4ab2bfd8c3d8 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 4 Jun 2021 07:58:03 +0200 Subject: [PATCH 11/91] Add `CharacterMapping.setColumnInfo` --- .../common/viewLayout/viewLineRenderer.ts | 18 +++++----- .../viewLayout/viewLineRenderer.test.ts | 34 +++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/vs/editor/common/viewLayout/viewLineRenderer.ts b/src/vs/editor/common/viewLayout/viewLineRenderer.ts index 5e3bedacb48..a0bea771332 100644 --- a/src/vs/editor/common/viewLayout/viewLineRenderer.ts +++ b/src/vs/editor/common/viewLayout/viewLineRenderer.ts @@ -247,13 +247,13 @@ export class CharacterMapping { this._absoluteOffsets = new Uint32Array(this.length); } - public setPartData(charOffset: number, partIndex: number, charIndex: number, partAbsoluteOffset: number): void { - let partData = ( + public setColumnInfo(column: number, partIndex: number, charIndex: number, partAbsoluteOffset: number): void { + const partData = ( (partIndex << CharacterMappingConstants.PART_INDEX_OFFSET) | (charIndex << CharacterMappingConstants.CHAR_INDEX_OFFSET) ) >>> 0; - this._data[charOffset] = partData; - this._absoluteOffsets[charOffset] = partAbsoluteOffset + charIndex; + this._data[column - 1] = partData; + this._absoluteOffsets[column - 1] = partAbsoluteOffset + charIndex; } public getAbsoluteOffset(column: number): number { @@ -400,7 +400,7 @@ export function renderViewLine(input: RenderLineInput, sb: IStringBuilder): Rend sb.appendASCIIString(``); const characterMapping = new CharacterMapping(1, beforeCount + afterCount); - characterMapping.setPartData(0, beforeCount, 0, 0); + characterMapping.setColumnInfo(1, beforeCount, 0, 0); return new RenderLineOutput( characterMapping, @@ -907,7 +907,7 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render sb.appendASCII(CharCode.GreaterThan); for (; charIndex < partEndIndex; charIndex++) { - characterMapping.setPartData(charIndex, partIndex - partDisplacement, charOffsetInPart, partAbsoluteOffset); + characterMapping.setColumnInfo(charIndex + 1, partIndex - partDisplacement, charOffsetInPart, partAbsoluteOffset); partDisplacement = 0; const charCode = lineContent.charCodeAt(charIndex); let charWidth: number; @@ -945,7 +945,7 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render sb.appendASCII(CharCode.GreaterThan); for (; charIndex < partEndIndex; charIndex++) { - characterMapping.setPartData(charIndex, partIndex - partDisplacement, charOffsetInPart, partAbsoluteOffset); + characterMapping.setColumnInfo(charIndex + 1, partIndex - partDisplacement, charOffsetInPart, partAbsoluteOffset); partDisplacement = 0; const charCode = lineContent.charCodeAt(charIndex); @@ -1026,7 +1026,7 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render if (charIndex >= len && !lastCharacterMappingDefined && part.isPseudoAfter()) { lastCharacterMappingDefined = true; - characterMapping.setPartData(charIndex, partIndex, charOffsetInPart, partAbsoluteOffset); + characterMapping.setColumnInfo(charIndex + 1, partIndex, charOffsetInPart, partAbsoluteOffset); } sb.appendASCIIString(''); @@ -1036,7 +1036,7 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render if (!lastCharacterMappingDefined) { // When getting client rects for the last character, we will position the // text range at the end of the span, insteaf of at the beginning of next span - characterMapping.setPartData(len, parts.length - 1, charOffsetInPart, partAbsoluteOffset); + characterMapping.setColumnInfo(len + 1, parts.length - 1, charOffsetInPart, partAbsoluteOffset); } if (isOverflowing) { diff --git a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts index 978eb8f06e0..27657cf1cc8 100644 --- a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts +++ b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts @@ -406,23 +406,23 @@ suite('viewLineRenderer.renderLine', () => { ].join(''); const expectedCharacterMapping = new CharacterMapping(17, 4); - expectedCharacterMapping.setPartData(0, 0, 0, 0); - expectedCharacterMapping.setPartData(1, 0, 1, 0); - expectedCharacterMapping.setPartData(2, 0, 2, 0); - expectedCharacterMapping.setPartData(3, 0, 3, 0); - expectedCharacterMapping.setPartData(4, 0, 4, 0); - expectedCharacterMapping.setPartData(5, 0, 5, 0); - expectedCharacterMapping.setPartData(6, 0, 6, 0); - expectedCharacterMapping.setPartData(7, 0, 7, 0); - expectedCharacterMapping.setPartData(8, 0, 8, 0); - expectedCharacterMapping.setPartData(9, 0, 9, 0); - expectedCharacterMapping.setPartData(10, 0, 10, 0); - expectedCharacterMapping.setPartData(11, 0, 11, 0); - expectedCharacterMapping.setPartData(12, 2, 0, 12); - expectedCharacterMapping.setPartData(13, 3, 1, 12); - expectedCharacterMapping.setPartData(14, 3, 2, 12); - expectedCharacterMapping.setPartData(15, 3, 3, 12); - expectedCharacterMapping.setPartData(16, 3, 4, 12); + expectedCharacterMapping.setColumnInfo(1, 0, 0, 0); + expectedCharacterMapping.setColumnInfo(2, 0, 1, 0); + expectedCharacterMapping.setColumnInfo(3, 0, 2, 0); + expectedCharacterMapping.setColumnInfo(4, 0, 3, 0); + expectedCharacterMapping.setColumnInfo(5, 0, 4, 0); + expectedCharacterMapping.setColumnInfo(6, 0, 5, 0); + expectedCharacterMapping.setColumnInfo(7, 0, 6, 0); + expectedCharacterMapping.setColumnInfo(8, 0, 7, 0); + expectedCharacterMapping.setColumnInfo(9, 0, 8, 0); + expectedCharacterMapping.setColumnInfo(10, 0, 9, 0); + expectedCharacterMapping.setColumnInfo(11, 0, 10, 0); + expectedCharacterMapping.setColumnInfo(12, 0, 11, 0); + expectedCharacterMapping.setColumnInfo(13, 2, 0, 12); + expectedCharacterMapping.setColumnInfo(14, 3, 1, 12); + expectedCharacterMapping.setColumnInfo(15, 3, 2, 12); + expectedCharacterMapping.setColumnInfo(16, 3, 3, 12); + expectedCharacterMapping.setColumnInfo(17, 3, 4, 12); const actual = renderViewLine(new RenderLineInput( true, From 802648f2a133559ffe1f861fba823026cdaac60f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 4 Jun 2021 09:22:38 +0200 Subject: [PATCH 12/91] electron - adopt some newer APIs and :lipstick: main code --- src/vs/code/electron-main/app.ts | 66 ++++--------------- src/vs/code/node/cli.ts | 2 +- .../backup/electron-main/backupMainService.ts | 13 ++-- .../issue/electron-main/issueMainService.ts | 1 - src/vs/platform/product/common/product.ts | 2 +- .../electron-main/sharedProcess.ts | 1 - .../platform/windows/electron-main/window.ts | 1 - test/unit/electron/index.js | 1 - 8 files changed, 23 insertions(+), 64 deletions(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 630c577a640..c3e48687980 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -71,7 +71,7 @@ import { withNullAsUndefined } from 'vs/base/common/types'; import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels'; import { WebviewMainService } from 'vs/platform/webview/electron-main/webviewMainService'; import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService'; -import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files'; +import { IFileService } from 'vs/platform/files/common/files'; import { stripComments } from 'vs/base/common/json'; import { generateUuid } from 'vs/base/common/uuid'; import { VSBuffer } from 'vs/base/common/buffer'; @@ -148,37 +148,6 @@ export class CodeApplication extends Disposable { // // !!! DO NOT CHANGE without consulting the documentation !!! // - app.on('remote-require', (event, sender, module) => { - this.logService.trace('app#on(remote-require): prevented'); - - event.preventDefault(); - }); - app.on('remote-get-global', (event, sender, module) => { - this.logService.trace(`app#on(remote-get-global): prevented on ${module}`); - - event.preventDefault(); - }); - app.on('remote-get-builtin', (event, sender, module) => { - this.logService.trace(`app#on(remote-get-builtin): prevented on ${module}`); - - if (module !== 'clipboard') { - event.preventDefault(); - } - }); - app.on('remote-get-current-window', event => { - this.logService.trace(`app#on(remote-get-current-window): prevented`); - - event.preventDefault(); - }); - app.on('remote-get-current-web-contents', event => { - if (this.environmentMainService.args.driver) { - return; // the driver needs access to web contents - } - - this.logService.trace(`app#on(remote-get-current-web-contents): prevented`); - - event.preventDefault(); - }); app.on('web-contents-created', (event, contents) => { contents.on('will-attach-webview', (event, webPreferences, params) => { @@ -222,19 +191,19 @@ export class CodeApplication extends Disposable { event.preventDefault(); }); - contents.on('new-window', (event, url) => { - event.preventDefault(); // prevent code that wants to open links - + contents.setWindowOpenHandler(({ url }) => { this.nativeHostMainService?.openExternal(undefined, url); + + return { action: 'deny' }; }); - const isUrlFromWebview = (requestingUrl: string) => - requestingUrl.startsWith(`${Schemas.vscodeWebview}://`); + const isUrlFromWebview = (requestingUrl: string) => requestingUrl.startsWith(`${Schemas.vscodeWebview}://`); session.defaultSession.setPermissionRequestHandler((_webContents, permission /* 'media' | 'geolocation' | 'notifications' | 'midiSysex' | 'pointerLock' | 'fullscreen' | 'openExternal' */, callback, details) => { if (isUrlFromWebview(details.requestingUrl)) { return callback(permission === 'clipboard-read'); } + return callback(false); }); @@ -242,6 +211,7 @@ export class CodeApplication extends Disposable { if (isUrlFromWebview(details.requestingUrl)) { return permission === 'clipboard-read'; } + return false; }); }); @@ -379,18 +349,6 @@ export class CodeApplication extends Disposable { this.logService.debug(`from: ${this.environmentMainService.appRoot}`); this.logService.debug('args:', this.environmentMainService.args); - // TODO@bpasero TODO@deepak1556 workaround for #120655 - try { - const cachedDataPath = URI.file(this.environmentMainService.chromeCachedDataDir); - this.logService.trace(`Deleting Chrome cached data path: ${cachedDataPath.fsPath}`); - - await this.fileService.del(cachedDataPath, { recursive: true }); - } catch (error) { - if ((error).fileOperationResult !== FileOperationResult.FILE_NOT_FOUND) { - this.logService.error(error); - } - } - // Make sure we associate the program with the app user model id // This will help Windows to associate the running program with // any shortcut that is pinned to the taskbar and prevent showing @@ -678,16 +636,18 @@ export class CodeApplication extends Disposable { // Check for initial URLs to handle from protocol link invocations const pendingWindowOpenablesFromProtocolLinks: IWindowOpenable[] = []; const pendingProtocolLinksToHandle = [ + // Windows/Linux: protocol handler invokes CLI with --open-url ...this.environmentMainService.args['open-url'] ? this.environmentMainService.args._urls || [] : [], // macOS: open-url events ...((global).getOpenUrls() || []) as string[] + ].map(url => { try { return { uri: URI.parse(url), url }; } catch { - return null; + return undefined; } }).filter((obj): obj is { uri: URI, url: string } => { if (!obj) { @@ -741,7 +701,7 @@ export class CodeApplication extends Disposable { cli: { ...environmentService.args }, urisToOpen: [windowOpenableFromProtocolLink], gotoLineMode: true - /* remoteAuthority will be determined based on windowOpenableFromProtocolLink */ + // remoteAuthority: will be determined based on windowOpenableFromProtocolLink }); window.focus(); // this should help ensuring that the right window gets focus when multiple are opened @@ -804,7 +764,7 @@ export class CodeApplication extends Disposable { urisToOpen: pendingWindowOpenablesFromProtocolLinks, gotoLineMode: true, initialStartup: true - /* remoteAuthority will be determined based on pendingWindowOpenablesFromProtocolLinks */ + // remoteAuthority: will be determined based on pendingWindowOpenablesFromProtocolLinks }); } @@ -831,7 +791,7 @@ export class CodeApplication extends Disposable { noRecentEntry, waitMarkerFileURI, initialStartup: true, - /* remoteAuthority will be determined based on macOpenFiles */ + // remoteAuthority: will be determined based on macOpenFiles }); } diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 2e7b324ed1d..9c7ad6268b6 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -56,7 +56,7 @@ export async function main(argv: string[]): Promise { // Extensions Management else if (shouldSpawnCliProcess(args)) { - const cli = await new Promise((c, e) => require(['vs/code/node/cliProcessMain'], c, e)); + const cli = await new Promise((resolve, reject) => require(['vs/code/node/cliProcessMain'], resolve, reject)); await cli.main(args); return; diff --git a/src/vs/platform/backup/electron-main/backupMainService.ts b/src/vs/platform/backup/electron-main/backupMainService.ts index ac9d7f2a86d..1bd2f63f6cd 100644 --- a/src/vs/platform/backup/electron-main/backupMainService.ts +++ b/src/vs/platform/backup/electron-main/backupMainService.ts @@ -54,21 +54,23 @@ export class BackupMainService implements IBackupMainService { backups = Object.create(null); } - // read empty workspaces backups first - if (backups.emptyWorkspaceInfos) { - this.emptyWindows = await this.validateEmptyWorkspaces(backups.emptyWorkspaceInfos); - } + // validate empty workspaces backups first + this.emptyWindows = await this.validateEmptyWorkspaces(backups.emptyWorkspaceInfos); // read workspace backups let rootWorkspaces: IWorkspaceBackupInfo[] = []; try { if (Array.isArray(backups.rootURIWorkspaces)) { - rootWorkspaces = backups.rootURIWorkspaces.map(workspace => ({ workspace: { id: workspace.id, configPath: URI.parse(workspace.configURIPath) }, remoteAuthority: workspace.remoteAuthority })); + rootWorkspaces = backups.rootURIWorkspaces.map(workspace => ({ + workspace: { id: workspace.id, configPath: URI.parse(workspace.configURIPath) }, + remoteAuthority: workspace.remoteAuthority + })); } } catch (e) { // ignore URI parsing exceptions } + // validate workspace backups this.workspaces = await this.validateWorkspaces(rootWorkspaces); // read folder backups @@ -81,6 +83,7 @@ export class BackupMainService implements IBackupMainService { // ignore URI parsing exceptions } + // validate folder backups this.folders = await this.validateFolders(workspaceFolders); // save again in case some workspaces or folders have been removed diff --git a/src/vs/platform/issue/electron-main/issueMainService.ts b/src/vs/platform/issue/electron-main/issueMainService.ts index 1eb0ac224bc..0df99eba03e 100644 --- a/src/vs/platform/issue/electron-main/issueMainService.ts +++ b/src/vs/platform/issue/electron-main/issueMainService.ts @@ -308,7 +308,6 @@ export class IssueMainService implements ICommonIssueService { additionalArguments: [`--vscode-window-config=${ipcObjectUrl.resource.toString()}`, '--context-isolation' /* TODO@bpasero: Use process.contextIsolateed when 13-x-y is adopted (https://github.com/electron/electron/pull/28030) */], v8CacheOptions: browserCodeLoadingCacheStrategy, enableWebSQL: false, - enableRemoteModule: false, spellcheck: false, nativeWindowOpen: true, zoomFactor: zoomLevelToZoomFactor(options.zoomLevel), diff --git a/src/vs/platform/product/common/product.ts b/src/vs/platform/product/common/product.ts index 4a0b94187d6..1eafa991bd9 100644 --- a/src/vs/platform/product/common/product.ts +++ b/src/vs/platform/product/common/product.ts @@ -54,7 +54,7 @@ else { // Running out of sources if (Object.keys(product).length === 0) { Object.assign(product, { - version: '1.57.0-dev', + version: '1.58.0-dev', nameShort: isWeb ? 'Code Web - OSS Dev' : 'Code - OSS Dev', nameLong: isWeb ? 'Code Web - OSS Dev' : 'Code - OSS Dev', applicationName: 'code-oss', diff --git a/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts b/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts index f62912e56d1..a2d420a49fe 100644 --- a/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts +++ b/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts @@ -170,7 +170,6 @@ export class SharedProcess extends Disposable implements ISharedProcess { nodeIntegration: true, contextIsolation: false, enableWebSQL: false, - enableRemoteModule: false, spellcheck: false, nativeWindowOpen: true, images: false, diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index c597738aa69..9ec6e9fd476 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -186,7 +186,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { [`--vscode-window-config=${this.configObjectUrl.resource.toString()}`], v8CacheOptions: browserCodeLoadingCacheStrategy, enableWebSQL: false, - enableRemoteModule: false, spellcheck: false, nativeWindowOpen: true, webviewTag: true, diff --git a/test/unit/electron/index.js b/test/unit/electron/index.js index 7d85f302c7d..99bb64e92a4 100644 --- a/test/unit/electron/index.js +++ b/test/unit/electron/index.js @@ -168,7 +168,6 @@ app.on('ready', () => { nodeIntegration: true, contextIsolation: false, enableWebSQL: false, - enableRemoteModule: false, spellcheck: false, nativeWindowOpen: true, webviewTag: true From 8163cfd8c54073c9587003ab56503f8dcc47e536 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 4 Jun 2021 01:23:49 -0700 Subject: [PATCH 13/91] Make sure we layout editors in sideBySideEditor after they are created (#125445) Fixes #125202 This make sure we always invoke `layout` when a new editor is created in a split view. Due to the caching added in 0449a18b7bb1d8b3cf7138df63e03126ba47c21d, the `WebviewEditor` created by the split view never had `layout` called on it Not sure if this is best fix for this issue. If not, I suggest we revert 0449a18b7bb1d8b3cf7138df63e03126ba47c21d and then revisit it next iteration --- src/vs/workbench/browser/parts/editor/sideBySideEditor.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts b/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts index 926dc846f47..8c8348bdef1 100644 --- a/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts +++ b/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts @@ -219,6 +219,8 @@ export class SideBySideEditor extends EditorPane { this.secondaryEditorPane.setInput(secondaryInput, undefined, context, token), this.primaryEditorPane.setInput(primaryInput, options, context, token)] ); + + this.layout(this.dimension); } override updateStyles(): void { From f99e1c358f0fa9e9f5bd38022e7b8cac04553711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 4 Jun 2021 10:38:59 +0200 Subject: [PATCH 14/91] fixes issue with asExternalUri API --- src/vs/workbench/api/common/extHost.api.impl.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index c8e2f72ad98..54c40c33d51 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -321,14 +321,20 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostUrls.createAppUri(uri); } - if (!matchesScheme(uri, Schemas.http) && !matchesScheme(uri, Schemas.https)) { + const isHttp = matchesScheme(uri, Schemas.http) || matchesScheme(uri, Schemas.https); + + if (!isHttp) { checkProposedApiEnabled(extension); // https://github.com/microsoft/vscode/issues/124263 } try { return await extHostWindow.asExternalUri(uri, { allowTunneling: !!initData.remote.authority }); - } catch { - return uri; + } catch (err) { + if (isHttp) { + return uri; + } + + throw err; } }, get remoteName() { From 7954c27d2d9f3095e231432d8e5ac020c775e3bd Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 4 Jun 2021 10:34:32 +0200 Subject: [PATCH 15/91] Fixes #125478. --- .../inlineCompletions/inlineCompletionsModel.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts index 89e0bfd7577..f9121021d5f 100644 --- a/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts @@ -19,6 +19,8 @@ import { EditOperation } from 'vs/editor/common/core/editOperation'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { MutableDisposable } from 'vs/editor/contrib/inlineCompletions/utils'; +import { RedoCommand, UndoCommand } from 'vs/editor/browser/editorExtensions'; +import { CoreEditingCommands } from 'vs/editor/browser/controller/coreCommands'; export class InlineCompletionsModel extends Disposable implements GhostTextWidgetModel { protected readonly onDidChangeEmitter = new Emitter(); @@ -36,7 +38,13 @@ export class InlineCompletionsModel extends Disposable implements GhostTextWidge this._register(commandService.onDidExecuteCommand(e => { // These commands don't trigger onDidType. - const commands = new Set(['undo', 'redo', 'tab']); + const commands = new Set([ + UndoCommand.id, + RedoCommand.id, + CoreEditingCommands.Tab.id, + CoreEditingCommands.DeleteLeft.id, + CoreEditingCommands.DeleteRight.id + ]); if (commands.has(e.commandId) && editor.hasTextFocus()) { this.handleUserInput(); } From 5efc2e7abcd47dd5aeaf26b21d6feed94096aa6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 4 Jun 2021 10:51:53 +0200 Subject: [PATCH 16/91] :lipstick: related to #125445 --- .../browser/parts/editor/sideBySideEditor.ts | 39 ++++++++----------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts b/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts index 8c8348bdef1..bf1508b3dde 100644 --- a/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts +++ b/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts @@ -184,11 +184,23 @@ export class SideBySideEditor extends EditorPane { ]); } - private setNewInput(newInput: SideBySideEditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise { - const secondaryEditor = this.doCreateEditor(newInput.secondary, assertIsDefined(this.secondaryEditorContainer)); - const primaryEditor = this.doCreateEditor(newInput.primary, assertIsDefined(this.primaryEditorContainer)); + private async setNewInput(newInput: SideBySideEditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise { + this.secondaryEditorPane = this.doCreateEditor(newInput.secondary, assertIsDefined(this.secondaryEditorContainer)); + this.primaryEditorPane = this.doCreateEditor(newInput.primary, assertIsDefined(this.primaryEditorContainer)); - return this.onEditorsCreated(secondaryEditor, primaryEditor, newInput.secondary, newInput.primary, options, context, token); + this.layout(this.dimension); + + this._onDidChangeSizeConstraints.input = Event.any( + Event.map(this.secondaryEditorPane.onDidChangeSizeConstraints, () => undefined), + Event.map(this.primaryEditorPane.onDidChangeSizeConstraints, () => undefined) + ); + + this.onDidCreateEditors.fire(undefined); + + await Promise.all([ + this.secondaryEditorPane.setInput(newInput.secondary, undefined, context, token), + this.primaryEditorPane.setInput(newInput.primary, options, context, token)] + ); } private doCreateEditor(editorInput: EditorInput, container: HTMLElement): EditorPane { @@ -204,25 +216,6 @@ export class SideBySideEditor extends EditorPane { return editor; } - private async onEditorsCreated(secondary: EditorPane, primary: EditorPane, secondaryInput: EditorInput, primaryInput: EditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise { - this.secondaryEditorPane = secondary; - this.primaryEditorPane = primary; - - this._onDidChangeSizeConstraints.input = Event.any( - Event.map(secondary.onDidChangeSizeConstraints, () => undefined), - Event.map(primary.onDidChangeSizeConstraints, () => undefined) - ); - - this.onDidCreateEditors.fire(undefined); - - await Promise.all([ - this.secondaryEditorPane.setInput(secondaryInput, undefined, context, token), - this.primaryEditorPane.setInput(primaryInput, options, context, token)] - ); - - this.layout(this.dimension); - } - override updateStyles(): void { super.updateStyles(); From 708951c25ac30cbb8d0e0fc3519dbe3a7d677271 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 4 Jun 2021 10:55:30 +0200 Subject: [PATCH 17/91] files - fix pfs#Promises to not capture fs methods --- src/vs/base/node/pfs.ts | 60 +++++++++-------- .../diagnostics/node/diagnosticsService.ts | 67 ++++++++----------- .../platform/terminal/node/terminalProcess.ts | 29 +++----- .../common/workingCopyBackupService.ts | 4 +- 4 files changed, 75 insertions(+), 85 deletions(-) diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index 40a81246b02..e334da6a3a4 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -644,8 +644,8 @@ export async function exists(path: string): Promise { //#region Promise based fs methods /** - * Note: prefer this namespace over the `fs.promises` API - * to enable `graceful-fs` to function properly. Given issue + * Prefer this helper class over the `fs.promises` API to + * enable `graceful-fs` to function properly. Given issue * https://github.com/isaacs/node-graceful-fs/issues/160 it * is evident that the module only takes care of the non-promise * based fs methods. @@ -653,43 +653,49 @@ export async function exists(path: string): Promise { * Another reason is `realpath` being entirely different in * the promise based implementation compared to the other * one (https://github.com/microsoft/vscode/issues/118562) + * + * Note: using getters for a reason, since `graceful-fs` + * patching might kick in later after modules have been + * loaded we need to defer access to fs methods. + * (https://github.com/microsoft/vscode/issues/124176) */ -export namespace Promises { - export const access = promisify(fs.access); +export const Promises = new class { - export const stat = promisify(fs.stat); - export const lstat = promisify(fs.lstat); - export const utimes = promisify(fs.utimes); + get access() { return promisify(fs.access); } - export const read = promisify(fs.read); - export const readFile = promisify(fs.readFile); + get stat() { return promisify(fs.stat); } + get lstat() { return promisify(fs.lstat); } + get utimes() { return promisify(fs.utimes); } - export const write = promisify(fs.write); - export const writeFile = promisify(fs.writeFile); + get read() { return promisify(fs.read); } + get readFile() { return promisify(fs.readFile); } - export const appendFile = promisify(fs.appendFile); + get write() { return promisify(fs.write); } + get writeFile() { return promisify(fs.writeFile); } - export const fdatasync = promisify(fs.fdatasync); - export const truncate = promisify(fs.truncate); + get appendFile() { return promisify(fs.appendFile); } - export const rename = promisify(fs.rename); - export const copyFile = promisify(fs.copyFile); + get fdatasync() { return promisify(fs.fdatasync); } + get truncate() { return promisify(fs.truncate); } - export const open = promisify(fs.open); - export const close = promisify(fs.close); + get rename() { return promisify(fs.rename); } + get copyFile() { return promisify(fs.copyFile); } - export const symlink = promisify(fs.symlink); - export const readlink = promisify(fs.readlink); + get open() { return promisify(fs.open); } + get close() { return promisify(fs.close); } - export const chmod = promisify(fs.chmod); + get symlink() { return promisify(fs.symlink); } + get readlink() { return promisify(fs.readlink); } - export const readdir = promisify(fs.readdir); - export const mkdir = promisify(fs.mkdir); + get chmod() { return promisify(fs.chmod); } - export const unlink = promisify(fs.unlink); - export const rmdir = promisify(fs.rmdir); + get readdir() { return promisify(fs.readdir); } + get mkdir() { return promisify(fs.mkdir); } - export const realpath = promisify(fs.realpath); -} + get unlink() { return promisify(fs.unlink); } + get rmdir() { return promisify(fs.rmdir); } + + get realpath() { return promisify(fs.realpath); } +}; //#endregion diff --git a/src/vs/platform/diagnostics/node/diagnosticsService.ts b/src/vs/platform/diagnostics/node/diagnosticsService.ts index a66ffda0236..7e2da77e0af 100644 --- a/src/vs/platform/diagnostics/node/diagnosticsService.ts +++ b/src/vs/platform/diagnostics/node/diagnosticsService.ts @@ -5,7 +5,6 @@ import * as osLib from 'os'; import { virtualMachineHint } from 'vs/base/node/id'; import { IDiagnosticsService, IMachineInfo, WorkspaceStats, WorkspaceStatItem, PerformanceInfo, SystemInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError, isRemoteDiagnosticError, IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnostics'; -import { exists, readFile } from 'fs'; import { join, basename } from 'vs/base/common/path'; import { parse, ParseError, getNodeType } from 'vs/base/common/json'; import { listProcesses } from 'vs/base/node/ps'; @@ -18,7 +17,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { Iterable } from 'vs/base/common/iterator'; import { Schemas } from 'vs/base/common/network'; import { ByteSize } from 'vs/platform/files/common/files'; -import { IDirent, readdir } from 'vs/base/node/pfs'; +import { IDirent, Promises, readdir } from 'vs/base/node/pfs'; export interface VersionInfo { vscodeVersion: string; @@ -168,45 +167,37 @@ export function getMachineInfo(): IMachineInfo { return machineInfo; } -export function collectLaunchConfigs(folder: string): Promise { - let launchConfigs = new Map(); +export async function collectLaunchConfigs(folder: string): Promise { + try { + const launchConfigs = new Map(); + const launchConfig = join(folder, '.vscode', 'launch.json'); - let launchConfig = join(folder, '.vscode', 'launch.json'); - return new Promise((resolve, reject) => { - exists(launchConfig, (doesExist) => { - if (doesExist) { - readFile(launchConfig, (err, contents) => { - if (err) { - return resolve([]); + const contents = await Promises.readFile(launchConfig); + + const errors: ParseError[] = []; + const json = parse(contents.toString(), errors); + if (errors.length) { + console.log(`Unable to parse ${launchConfig}`); + return []; + } + + if (getNodeType(json) === 'object' && json['configurations']) { + for (const each of json['configurations']) { + const type = each['type']; + if (type) { + if (launchConfigs.has(type)) { + launchConfigs.set(type, launchConfigs.get(type)! + 1); + } else { + launchConfigs.set(type, 1); } - - const errors: ParseError[] = []; - const json = parse(contents.toString(), errors); - if (errors.length) { - console.log(`Unable to parse ${launchConfig}`); - return resolve([]); - } - - if (getNodeType(json) === 'object' && json['configurations']) { - for (const each of json['configurations']) { - const type = each['type']; - if (type) { - if (launchConfigs.has(type)) { - launchConfigs.set(type, launchConfigs.get(type)! + 1); - } else { - launchConfigs.set(type, 1); - } - } - } - } - - return resolve(asSortedItems(launchConfigs)); - }); - } else { - return resolve([]); + } } - }); - }); + } + + return asSortedItems(launchConfigs); + } catch (error) { + return []; + } } export class DiagnosticsService implements IDiagnosticsService { diff --git a/src/vs/platform/terminal/node/terminalProcess.ts b/src/vs/platform/terminal/node/terminalProcess.ts index b37b6ab2c15..000c9c5b896 100644 --- a/src/vs/platform/terminal/node/terminalProcess.ts +++ b/src/vs/platform/terminal/node/terminalProcess.ts @@ -5,7 +5,6 @@ import * as path from 'vs/base/common/path'; import type * as pty from 'node-pty'; -import * as fs from 'fs'; import * as os from 'os'; import { Event, Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -461,7 +460,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess return Promise.resolve(this._initialCwd); } - getCwd(): Promise { + async getCwd(): Promise { if (isMacintosh) { // Disable cwd lookup on macOS Big Sur due to spawn blocking thread (darwin v20 is macOS // Big Sur) https://github.com/Microsoft/vscode/issues/105446 @@ -486,24 +485,18 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess } if (isLinux) { - return new Promise(resolve => { - if (!this._ptyProcess) { - resolve(this._initialCwd); - return; - } - this._logService.trace('IPty#pid'); - fs.readlink('/proc/' + this._ptyProcess.pid + '/cwd', (err, linkedstr) => { - if (err) { - resolve(this._initialCwd); - } - resolve(linkedstr); - }); - }); + if (!this._ptyProcess) { + return this._initialCwd; + } + this._logService.trace('IPty#pid'); + try { + return await Promises.readlink(`/proc/${this._ptyProcess.pid}/cwd`); + } catch (error) { + return this._initialCwd; + } } - return new Promise(resolve => { - resolve(this._initialCwd); - }); + return this._initialCwd; } getLatency(): Promise { diff --git a/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts b/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts index 54eadefea64..a6a8e075dd1 100644 --- a/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts +++ b/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts @@ -19,7 +19,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Schemas } from 'vs/base/common/network'; import { hash } from 'vs/base/common/hash'; import { isEmptyObject } from 'vs/base/common/types'; -import { IWorkingCopyBackupMeta, IWorkingCopyIdentifier } from 'vs/workbench/services/workingCopy/common/workingCopy'; +import { IWorkingCopyBackupMeta, IWorkingCopyIdentifier, NO_TYPE_ID } from 'vs/workbench/services/workingCopy/common/workingCopy'; export class WorkingCopyBackupsModel { @@ -404,7 +404,7 @@ class NativeWorkingCopyBackupServiceImpl extends Disposable implements IWorkingC } return { - typeId: typeId ?? '', // Fallback for previous backups that do not encode the typeId (TODO@bpasero remove me eventually) + typeId: typeId ?? NO_TYPE_ID, resource: URI.parse(resourcePreamble) }; } From 922f866a282bc91bdc07502df9919c31b499be1e Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 4 Jun 2021 11:33:50 +0200 Subject: [PATCH 18/91] run menu: more precise context keys --- .../browser/parts/titlebar/menubarControl.ts | 10 ---------- .../contrib/debug/browser/debug.contribution.ts | 12 ++++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 7d5201ed058..144ec97e830 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -91,16 +91,6 @@ MenuRegistry.appendMenuItem(MenuId.MenubarMainMenu, { order: 5 }); -MenuRegistry.appendMenuItem(MenuId.MenubarMainMenu, { - submenu: MenuId.MenubarDebugMenu, - title: { - value: 'Run', - original: 'Run', - mnemonicTitle: localize({ key: 'mRun', comment: ['&& denotes a mnemonic'] }, "&&Run") - }, - order: 6 -}); - MenuRegistry.appendMenuItem(MenuId.MenubarMainMenu, { submenu: MenuId.MenubarTerminalMenu, title: { diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index 634f016ea68..b5a853fa432 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -50,6 +50,7 @@ import { registerColors } from 'vs/workbench/contrib/debug/browser/debugColors'; import { DebugEditorContribution } from 'vs/workbench/contrib/debug/browser/debugEditorContribution'; import { FileAccess } from 'vs/base/common/network'; import * as icons from 'vs/workbench/contrib/debug/browser/debugIcons'; +import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; const debugCategory = nls.localize('debugCategory', "Debug"); registerColors(); @@ -178,6 +179,17 @@ if (isMacintosh) { // Debug menu +MenuRegistry.appendMenuItem(MenuId.MenubarMainMenu, { + submenu: MenuId.MenubarDebugMenu, + title: { + value: 'Run', + original: 'Run', + mnemonicTitle: nls.localize({ key: 'mRun', comment: ['&& denotes a mnemonic'] }, "&&Run") + }, + when: ContextKeyExpr.or(CONTEXT_DEBUGGERS_AVAILABLE, IsWebContext.toNegated()), + order: 6 +}); + MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { group: '1_debug', command: { From 54dd1429b642b7062d98eed239261d5949f7eca9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 4 Jun 2021 11:50:12 +0200 Subject: [PATCH 19/91] startup timings uses now `exit` and not `quit`, fyi @bpasero --- .../contrib/performance/electron-sandbox/startupTimings.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/performance/electron-sandbox/startupTimings.ts b/src/vs/workbench/contrib/performance/electron-sandbox/startupTimings.ts index f0dcc668f43..c7b7bdae4d9 100644 --- a/src/vs/workbench/contrib/performance/electron-sandbox/startupTimings.ts +++ b/src/vs/workbench/contrib/performance/electron-sandbox/startupTimings.ts @@ -70,10 +70,10 @@ export class StartupTimings implements IWorkbenchContribution { chunks.push(VSBuffer.fromString(`${this._timerService.startupMetrics.ellapsed}\t${this._productService.nameShort}\t${(this._productService.commit || '').slice(0, 10) || '0000000000'}\t${sessionId}\t${standardStartupError === undefined ? 'standard_start' : 'NO_standard_start : ' + standardStartupError}\n`)); await this._fileService.writeFile(uri, VSBuffer.concat(chunks)); }).then(() => { - this._nativeHostService.quit(); + this._nativeHostService.exit(); }).catch(err => { console.error(err); - this._nativeHostService.quit(); + this._nativeHostService.exit(); }); } From 93e61e267caa3f4c3cc5e2712a2d387455d10580 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 4 Jun 2021 12:01:16 +0200 Subject: [PATCH 20/91] fix compile error --- .../contrib/performance/electron-sandbox/startupTimings.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/performance/electron-sandbox/startupTimings.ts b/src/vs/workbench/contrib/performance/electron-sandbox/startupTimings.ts index c7b7bdae4d9..684e9e0d6ec 100644 --- a/src/vs/workbench/contrib/performance/electron-sandbox/startupTimings.ts +++ b/src/vs/workbench/contrib/performance/electron-sandbox/startupTimings.ts @@ -70,10 +70,10 @@ export class StartupTimings implements IWorkbenchContribution { chunks.push(VSBuffer.fromString(`${this._timerService.startupMetrics.ellapsed}\t${this._productService.nameShort}\t${(this._productService.commit || '').slice(0, 10) || '0000000000'}\t${sessionId}\t${standardStartupError === undefined ? 'standard_start' : 'NO_standard_start : ' + standardStartupError}\n`)); await this._fileService.writeFile(uri, VSBuffer.concat(chunks)); }).then(() => { - this._nativeHostService.exit(); + this._nativeHostService.exit(0); }).catch(err => { console.error(err); - this._nativeHostService.exit(); + this._nativeHostService.exit(0); }); } From 4b0c17e1808274e75c04eecb4e6980f3f57dd16a Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 4 Jun 2021 12:02:50 +0200 Subject: [PATCH 21/91] fixes #115535 --- .../workbench/contrib/files/browser/views/explorerViewer.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 49095f56fca..aa024f8993a 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -831,6 +831,10 @@ export class FileDragAndDrop implements ITreeDragAndDrop { if (!containsDragType(originalEvent, DataTransfers.FILES, CodeDataTransfers.FILES, DataTransfers.RESOURCES)) { return false; } + if (isWeb && originalEvent.dataTransfer?.types.indexOf('Files') === -1) { + // DnD from vscode to web is not supported #115535. Only if we are dragging from native finder / explorer then the "Files" data transfer will be set + return false; + } } // Other-Tree DND From 620434543f53f0211475a5e79bcf894aab8dcf25 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 4 Jun 2021 12:10:56 +0200 Subject: [PATCH 22/91] * renames editor.suggest.showSuggestionPreview to editor.suggest.preview * renames editor.suggest.showInlineCompletions to editor.inlineSuggest.enabled --- src/vs/editor/common/config/editorOptions.ts | 71 ++++++++++++++----- .../common/standalone/standaloneEnums.ts | 3 +- .../inlineCompletions/ghostTextController.ts | 3 +- .../inlineCompletionsModel.ts | 4 +- .../suggestWidgetAdapterModel.ts | 2 +- src/vs/monaco.d.ts | 20 ++++-- 6 files changed, 75 insertions(+), 28 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index d3a46c0ad6f..16902de9bd6 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -382,6 +382,7 @@ export interface IEditorOptions { * Suggest options. */ suggest?: ISuggestOptions; + inlineSuggest?: IInlineSuggestOptions; /** * Smart select options. */ @@ -3140,6 +3141,51 @@ class EditorScrollbar extends BaseEditorOption>; + +/** + * Configuration options for inline suggestions + */ +class InlineEditorSuggest extends BaseEditorOption { + constructor() { + const defaults: InternalInlineSuggestOptions = { + enabled: false + }; + + super( + EditorOption.inlineSuggest, 'inlineSuggest', defaults, + { + 'editor.inlineSuggest.enabled': { + type: 'boolean', + default: defaults.enabled, + description: nls.localize('inlineSuggest.enabled', "Controls whether to automatically show inline suggestions in the editor.") + }, + } + ); + } + + public validate(_input: any): InternalInlineSuggestOptions { + if (!_input || typeof _input !== 'object') { + return this.defaultValue; + } + const input = _input as IInlineSuggestOptions; + return { + enabled: boolean(input.enabled, this.defaultValue.enabled), + }; + } +} + +//#endregion + //#region suggest /** @@ -3177,11 +3223,7 @@ export interface ISuggestOptions { /** * Enable or disable the rendering of the suggestion preview. */ - showSuggestionPreview?: boolean; - /** - * Enable or disable the rendering of automatic inline completions. - */ - showInlineCompletions?: boolean; + preview?: boolean; /** * Enable or disable the default expansion of the ghost text as used * by the suggestion preview or the inline completions. @@ -3318,9 +3360,8 @@ class EditorSuggest extends BaseEditorOption>; + /** * Configuration options for editor suggest widget */ @@ -3847,11 +3857,7 @@ declare namespace monaco.editor { /** * Enable or disable the rendering of the suggestion preview. */ - showSuggestionPreview?: boolean; - /** - * Enable or disable the rendering of automatic inline completions. - */ - showInlineCompletions?: boolean; + preview?: boolean; /** * Enable or disable the default expansion of the ghost text as used * by the suggestion preview or the inline completions. @@ -4141,7 +4147,8 @@ declare namespace monaco.editor { pixelRatio = 125, tabFocusMode = 126, layoutInfo = 127, - wrappingInfo = 128 + wrappingInfo = 128, + inlineSuggest = 129 } export const EditorOptions: { acceptSuggestionOnCommitCharacter: IEditorOption; @@ -4250,6 +4257,7 @@ declare namespace monaco.editor { smoothScrolling: IEditorOption; stopRenderingLineAfter: IEditorOption; suggest: IEditorOption; + inlineSuggest: IEditorOption; suggestFontSize: IEditorOption; suggestLineHeight: IEditorOption; suggestOnTriggerCharacters: IEditorOption; From f8c061e73d77c728363fcc6a46643ca4a3a125fd Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 4 Jun 2021 12:43:49 +0200 Subject: [PATCH 23/91] restricted trust status bar item should use rich hover. Fixes #125408 --- .../browser/workspace.contribution.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts index e2b4e7033de..00c4d71678a 100644 --- a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts +++ b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts @@ -35,7 +35,7 @@ import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; import { dirname, resolve } from 'vs/base/common/path'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import product from 'vs/platform/product/common/product'; -import { MarkdownString } from 'vs/base/common/htmlContent'; +import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent'; import { isSingleFolderWorkspaceIdentifier, toWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { Schemas } from 'vs/base/common/network'; import { STATUS_BAR_PROMINENT_ITEM_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_FOREGROUND } from 'vs/workbench/common/theme'; @@ -45,6 +45,7 @@ import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IBannerItem, IBannerService } from 'vs/workbench/services/banner/browser/bannerService'; import { isVirtualWorkspace } from 'vs/platform/remote/common/remoteHosts'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; +import { LIST_WORKSPACE_UNSUPPORTED_EXTENSIONS_COMMAND_ID } from 'vs/workbench/contrib/extensions/common/extensions'; const BANNER_RESTRICTED_MODE = 'workbench.banner.restrictedMode'; const BANNER_VIRTUAL_WORKSPACE = 'workbench.banner.virtualWorkspace'; @@ -442,20 +443,33 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon const color = new ThemeColor(STATUS_BAR_PROMINENT_ITEM_FOREGROUND); let ariaLabel = ''; + let toolTip: IMarkdownString | string | undefined; switch (this.workspaceContextService.getWorkbenchState()) { case WorkbenchState.EMPTY: { ariaLabel = trusted ? localize('status.ariaTrustedWindow', "This window is trusted.") : localize('status.ariaUntrustedWindow', "Restricted Mode: Some features are disabled because this window is not trusted."); + toolTip = trusted ? ariaLabel : { + value: localize('status.tooltipUntrustedWindow', "Restricted Mode: [Some features](command:{1}) are disabled because this window is not trusted.", LIST_WORKSPACE_UNSUPPORTED_EXTENSIONS_COMMAND_ID), + isTrusted: true + }; break; } case WorkbenchState.FOLDER: { ariaLabel = trusted ? localize('status.ariaTrustedFolder', "This folder is trusted.") : localize('status.ariaUntrustedFolder', "Restricted Mode: Some features are disabled because this folder is not trusted."); + toolTip = trusted ? ariaLabel : { + value: localize('status.tooltipUntrustedFolder', "Restricted Mode: [Some features](command:{1}) are disabled because this folder is not trusted", LIST_WORKSPACE_UNSUPPORTED_EXTENSIONS_COMMAND_ID), + isTrusted: true + }; break; } case WorkbenchState.WORKSPACE: { ariaLabel = trusted ? localize('status.ariaTrustedWorkspace', "This workspace is trusted.") : localize('status.ariaUntrustedWorkspace', "Restricted Mode: Some features are disabled because this workspace is not trusted."); + toolTip = trusted ? ariaLabel : { + value: localize('status.tooltipUntrustedWorkspace', "Restricted Mode: [Some features](command:{1}) are disabled because this workspace is not trusted", LIST_WORKSPACE_UNSUPPORTED_EXTENSIONS_COMMAND_ID), + isTrusted: true + }; break; } } @@ -464,7 +478,7 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon name: localize('status.WorkspaceTrust', "Workspace Trust"), text: trusted ? `$(shield)` : `$(shield) ${text}`, ariaLabel: ariaLabel, - tooltip: ariaLabel, + tooltip: toolTip, command: 'workbench.trust.manage', backgroundColor, color From 3300006ee17380d347bed349559d024fb6ef041a Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 4 Jun 2021 12:46:06 +0200 Subject: [PATCH 24/91] * Renames command ids, context keys and command titles to Inline Suggestion. * Renames menu item, makes it proposed API. Fixes #125034. --- .../inlineCompletions/ghostTextController.ts | 52 +++++++++---------- .../inlineCompletionsHoverParticipant.ts | 16 +++--- .../inlineCompletionsModel.ts | 2 +- src/vs/platform/actions/common/actions.ts | 2 +- .../api/common/menusExtensionPoint.ts | 9 ++-- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/vs/editor/contrib/inlineCompletions/ghostTextController.ts b/src/vs/editor/contrib/inlineCompletions/ghostTextController.ts index 4574fc1e3e5..4d9e2c6d94e 100644 --- a/src/vs/editor/contrib/inlineCompletions/ghostTextController.ts +++ b/src/vs/editor/contrib/inlineCompletions/ghostTextController.ts @@ -19,8 +19,8 @@ import { ContextKeyExpr, IContextKeyService, RawContextKey } from 'vs/platform/c import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export class GhostTextController extends Disposable { - public static readonly inlineCompletionsVisible = new RawContextKey('inlineCompletionsVisible ', false, nls.localize('inlineCompletionsVisible', "Whether inline suggestions are visible")); - public static readonly inlineCompletionSuggestsIndentation = new RawContextKey('inlineCompletionSuggestsIndentation', false, nls.localize('inlineCompletionSuggestsIndentation', "Whether the inline suggestion suggests extending indentation")); + public static readonly inlineSuggestionVisible = new RawContextKey('inlineSuggestionVisible ', false, nls.localize('inlineSuggestionVisible', "Whether an inline suggestion is visible")); + public static readonly inlineSuggestionHasIndentation = new RawContextKey('inlineSuggestionHasIndentation', false, nls.localize('inlineSuggestionHasIndentation', "Whether the inline suggestion starts with whitespace")); static ID = 'editor.contrib.ghostTextController'; @@ -110,10 +110,10 @@ export class GhostTextController extends Disposable { // Currently the global state is updated directly, which may lead to conflicts if multiple ghost texts are active. class GhostTextContextKeys { private lastInlineCompletionVisibleValue = false; - private readonly inlineCompletionVisible = GhostTextController.inlineCompletionsVisible.bindTo(this.contextKeyService); + private readonly inlineCompletionVisible = GhostTextController.inlineSuggestionVisible.bindTo(this.contextKeyService); private lastInlineCompletionSuggestsIndentationValue = false; - private readonly inlineCompletionSuggestsIndentation = GhostTextController.inlineCompletionSuggestsIndentation.bindTo(this.contextKeyService); + private readonly inlineCompletionSuggestsIndentation = GhostTextController.inlineSuggestionHasIndentation.bindTo(this.contextKeyService); constructor(private readonly contextKeyService: IContextKeyService) { } @@ -239,10 +239,10 @@ export class ActiveGhostTextController extends Disposable { const GhostTextCommand = EditorCommand.bindToContribution(GhostTextController.get); registerEditorCommand(new GhostTextCommand({ - id: 'commitInlineCompletion', + id: 'editor.action.inlineSuggest.commit', precondition: ContextKeyExpr.and( - GhostTextController.inlineCompletionsVisible, - GhostTextController.inlineCompletionSuggestsIndentation.toNegated(), + GhostTextController.inlineSuggestionVisible, + GhostTextController.inlineSuggestionHasIndentation.toNegated(), EditorContextKeys.tabMovesFocus.toNegated() ), kbOpts: { @@ -255,8 +255,8 @@ registerEditorCommand(new GhostTextCommand({ })); registerEditorCommand(new GhostTextCommand({ - id: 'hideInlineCompletion', - precondition: GhostTextController.inlineCompletionsVisible, + id: 'editor.action.inlineSuggest.hide', + precondition: GhostTextController.inlineSuggestionVisible, kbOpts: { weight: 100, primary: KeyCode.Escape, @@ -266,13 +266,13 @@ registerEditorCommand(new GhostTextCommand({ } })); -export class ShowNextInlineCompletionAction extends EditorAction { - public static ID = 'editor.action.showNextInlineCompletion'; +export class ShowNextInlineSuggestionAction extends EditorAction { + public static ID = 'editor.action.inlineSuggest.showNext'; constructor() { super({ - id: ShowNextInlineCompletionAction.ID, - label: nls.localize('showNextInlineCompletion', "Show Next Inline Completion"), - alias: 'Show Next Inline Completion', + id: ShowNextInlineSuggestionAction.ID, + label: nls.localize('action.inlineSuggest.showNext', "Show Next Inline Suggestion"), + alias: 'Show Next Inline Suggestion', precondition: EditorContextKeys.writable, kbOpts: { weight: 100, @@ -290,13 +290,13 @@ export class ShowNextInlineCompletionAction extends EditorAction { } } -export class ShowPreviousInlineCompletionAction extends EditorAction { - public static ID = 'editor.action.showPreviousInlineCompletion'; +export class ShowPreviousInlineSuggestionAction extends EditorAction { + public static ID = 'editor.action.inlineSuggest.showPrevious'; constructor() { super({ - id: ShowPreviousInlineCompletionAction.ID, - label: nls.localize('showPreviousInlineCompletion', "Show Previous Inline Completion"), - alias: 'Show Previous Inline Completion', + id: ShowPreviousInlineSuggestionAction.ID, + label: nls.localize('action.inlineSuggest.showPrevious', "Show Previous Inline Suggestion"), + alias: 'Show Previous Inline Suggestion', precondition: EditorContextKeys.writable, kbOpts: { weight: 100, @@ -314,12 +314,12 @@ export class ShowPreviousInlineCompletionAction extends EditorAction { } } -export class TriggerInlineCompletionsAction extends EditorAction { +export class TriggerInlineSuggestionAction extends EditorAction { constructor() { super({ - id: 'editor.action.triggerInlineCompletions', - label: nls.localize('triggerInlineCompletionsAction', "Trigger Inline Completions"), - alias: 'Trigger Inline Completions', + id: 'editor.action.inlineSuggest.trigger', + label: nls.localize('action.inlineSuggest.trigger', "Trigger Inline Suggestion"), + alias: 'Trigger Inline Suggestion', precondition: EditorContextKeys.writable }); } @@ -333,6 +333,6 @@ export class TriggerInlineCompletionsAction extends EditorAction { } registerEditorContribution(GhostTextController.ID, GhostTextController); -registerEditorAction(TriggerInlineCompletionsAction); -registerEditorAction(ShowNextInlineCompletionAction); -registerEditorAction(ShowPreviousInlineCompletionAction); +registerEditorAction(TriggerInlineSuggestionAction); +registerEditorAction(ShowNextInlineSuggestionAction); +registerEditorAction(ShowPreviousInlineSuggestionAction); diff --git a/src/vs/editor/contrib/inlineCompletions/inlineCompletionsHoverParticipant.ts b/src/vs/editor/contrib/inlineCompletions/inlineCompletionsHoverParticipant.ts index e3d89be22cf..a28945427df 100644 --- a/src/vs/editor/contrib/inlineCompletions/inlineCompletionsHoverParticipant.ts +++ b/src/vs/editor/contrib/inlineCompletions/inlineCompletionsHoverParticipant.ts @@ -9,7 +9,7 @@ import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/brows import { Range } from 'vs/editor/common/core/range'; import { IModelDecoration } from 'vs/editor/common/model'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; -import { GhostTextController, ShowNextInlineCompletionAction, ShowPreviousInlineCompletionAction } from 'vs/editor/contrib/inlineCompletions/ghostTextController'; +import { GhostTextController, ShowNextInlineSuggestionAction, ShowPreviousInlineSuggestionAction } from 'vs/editor/contrib/inlineCompletions/ghostTextController'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; @@ -77,19 +77,19 @@ export class InlineCompletionsHoverParticipant implements IEditorHoverParticipan renderHoverParts(hoverParts: InlineCompletionsHover[], fragment: DocumentFragment, statusBar: IEditorHoverStatusBar): IDisposable { const menu = this._menuService.createMenu( - MenuId.InlineCompletionsActions, + MenuId.InlineSuggestionActions, this._contextKeyService ); statusBar.addAction({ - label: nls.localize('showNextInlineCompletion', "Next"), - commandId: ShowNextInlineCompletionAction.ID, - run: () => this._commandService.executeCommand(ShowNextInlineCompletionAction.ID) + label: nls.localize('showNextInlineSuggestion', "Next"), + commandId: ShowNextInlineSuggestionAction.ID, + run: () => this._commandService.executeCommand(ShowNextInlineSuggestionAction.ID) }); statusBar.addAction({ - label: nls.localize('showPreviousInlineCompletion', "Previous"), - commandId: ShowPreviousInlineCompletionAction.ID, - run: () => this._commandService.executeCommand(ShowPreviousInlineCompletionAction.ID) + label: nls.localize('showPreviousInlineSuggestion', "Previous"), + commandId: ShowPreviousInlineSuggestionAction.ID, + run: () => this._commandService.executeCommand(ShowPreviousInlineSuggestionAction.ID) }); for (const [_, group] of menu.getActions()) { diff --git a/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts index 7b8be69478c..8f540dd3fa6 100644 --- a/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts @@ -346,7 +346,7 @@ class InlineCompletionsSession extends BaseGhostTextWidgetModel { const cache = this.cache.replace(undefined); this.editor.executeEdits( - 'inlineCompletions.accept', + 'inlineSuggestion.accept', [ EditOperation.replaceMove(completion.range, completion.text) ] diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index f0e548fea19..67ab359f4d3 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -171,7 +171,7 @@ export class MenuId { static readonly TerminalTabEmptyAreaContext = new MenuId('TerminalTabEmptyAreaContext'); static readonly TerminalInlineTabContext = new MenuId('TerminalInlineTabContext'); static readonly WebviewContext = new MenuId('WebviewContext'); - static readonly InlineCompletionsActions = new MenuId('InlineCompletionsActions'); + static readonly InlineSuggestionActions = new MenuId('InlineSuggestionActions'); readonly id: number; readonly _debugName: string; diff --git a/src/vs/workbench/api/common/menusExtensionPoint.ts b/src/vs/workbench/api/common/menusExtensionPoint.ts index 727ff93374e..f44407d19c9 100644 --- a/src/vs/workbench/api/common/menusExtensionPoint.ts +++ b/src/vs/workbench/api/common/menusExtensionPoint.ts @@ -233,10 +233,11 @@ const apiMenus: IAPIMenu[] = [ description: localize('view.tunnelPortInline', "The Ports view item port inline menu") }, { - key: 'editor/inlineCompletions/actions', - id: MenuId.InlineCompletionsActions, - description: localize('inlineCompletions.actions', "The actions shown when hovering on an inline completion"), - supportsSubmenus: false + key: 'editor/inlineSuggestion/actions', + id: MenuId.InlineSuggestionActions, + description: localize('inlineSuggestion.actions', "The actions shown when hovering on an inline suggestion"), + supportsSubmenus: false, + proposed: true }, ]; From 2ba1dcb0c9c0bcceace8968e67f92fec0511a4be Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 4 Jun 2021 13:06:21 +0200 Subject: [PATCH 25/91] Removes setting ghostTextExpanded. Fixes #125037. --- src/vs/editor/common/config/editorOptions.ts | 12 ------------ .../contrib/inlineCompletions/ghostTextWidget.ts | 4 +++- src/vs/monaco.d.ts | 5 ----- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 16902de9bd6..41e5b7b46cb 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -3224,11 +3224,6 @@ export interface ISuggestOptions { * Enable or disable the rendering of the suggestion preview. */ preview?: boolean; - /** - * Enable or disable the default expansion of the ghost text as used - * by the suggestion preview or the inline completions. - */ - ghostTextExpanded?: boolean; /** * Show details inline with the label. Defaults to true. */ @@ -3361,7 +3356,6 @@ class EditorSuggest extends BaseEditorOption