From 72defdc77c3dae16cff9ad97a8cf51389a944c55 Mon Sep 17 00:00:00 2001 From: Eno Yao <2587575267@qq.com> Date: Wed, 18 Nov 2020 16:08:01 +0800 Subject: [PATCH 001/200] Support greater than and less than --- .../platform/contextkey/common/contextkey.ts | 154 +++++++++++++++++- 1 file changed, 153 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index 01bef2897ce..15802baa72b 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -32,6 +32,8 @@ export const enum ContextKeyExprType { Or = 9, In = 10, NotIn = 11, + Greater = 12, + Less = 13, } export interface IContextKeyExprMapper { @@ -57,7 +59,7 @@ export interface IContextKeyExpression { export type ContextKeyExpression = ( ContextKeyFalseExpr | ContextKeyTrueExpr | ContextKeyDefinedExpr | ContextKeyNotExpr | ContextKeyEqualsExpr | ContextKeyNotEqualsExpr | ContextKeyRegexExpr - | ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr | ContextKeyInExpr | ContextKeyNotInExpr + | ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr | ContextKeyInExpr | ContextKeyNotInExpr | ContextKeyGreaterExpr | ContextKeyLessExpr ); export abstract class ContextKeyExpr { @@ -102,6 +104,14 @@ export abstract class ContextKeyExpr { return ContextKeyOrExpr.create(expr); } + public static greater(key: string, value: any): ContextKeyExpression { + return ContextKeyGreaterExpr.create(key, value); + } + + public static less(key: string, value: any): ContextKeyExpression { + return ContextKeyLessExpr.create(key, value); + } + public static deserialize(serialized: string | null | undefined, strict: boolean = false): ContextKeyExpression | undefined { if (!serialized) { return undefined; @@ -143,6 +153,16 @@ export abstract class ContextKeyExpr { return ContextKeyInExpr.create(pieces[0].trim(), pieces[1].trim()); } + if (serializedOne.indexOf('>') >= 0) { + let pieces = serializedOne.split('>'); + return ContextKeyGreaterExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict)); + } + + if (serializedOne.indexOf('<') >= 0) { + let pieces = serializedOne.split('<'); + return ContextKeyLessExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict)); + } + if (/^\!\s*/.test(serializedOne)) { return ContextKeyNotExpr.create(serializedOne.substr(1).trim()); } @@ -650,6 +670,138 @@ export class ContextKeyNotExpr implements IContextKeyExpression { } } +export class ContextKeyGreaterExpr implements IContextKeyExpression { + + public static create(key: string, value: any): ContextKeyExpression { + if (typeof value === 'boolean') { + return (value ? ContextKeyDefinedExpr.create(key) : ContextKeyNotExpr.create(key)); + } + const staticValue = STATIC_VALUES.get(key); + if (typeof staticValue === 'boolean') { + const trueValue = staticValue ? 'true' : 'false'; + return (value === trueValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE); + } + return new ContextKeyGreaterExpr(key, value); + } + + public readonly type = ContextKeyExprType.Greater; + + private constructor(private readonly key: string, private readonly value: any) { + } + + public cmp(other: ContextKeyExpression): number { + if (other.type !== this.type) { + return this.type - other.type; + } + if (this.key < other.key) { + return -1; + } + if (this.key > other.key) { + return 1; + } + if (this.value < other.value) { + return -1; + } + if (this.value > other.value) { + return 1; + } + return 0; + } + + public equals(other: ContextKeyExpression): boolean { + if (other.type === this.type) { + return (this.key === other.key && this.value === other.value); + } + return false; + } + + public evaluate(context: IContext): boolean { + return (Number(context.getValue(this.key)) > this.value); + } + + public serialize(): string { + return `${this.key} > '${this.value}'`; + } + + public keys(): string[] { + return [this.key]; + } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression { + return mapFnc.mapEquals(this.key, this.value); + } + + public negate(): ContextKeyExpression { + return ContextKeyNotEqualsExpr.create(this.key, this.value); + } +} + +export class ContextKeyLessExpr implements IContextKeyExpression { + + public static create(key: string, value: any): ContextKeyExpression { + if (typeof value === 'boolean') { + return (value ? ContextKeyDefinedExpr.create(key) : ContextKeyNotExpr.create(key)); + } + const staticValue = STATIC_VALUES.get(key); + if (typeof staticValue === 'boolean') { + const trueValue = staticValue ? 'true' : 'false'; + return (value === trueValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE); + } + return new ContextKeyLessExpr(key, value); + } + + public readonly type = ContextKeyExprType.Less; + + private constructor(private readonly key: string, private readonly value: any) { + } + + public cmp(other: ContextKeyExpression): number { + if (other.type !== this.type) { + return this.type - other.type; + } + if (this.key < other.key) { + return -1; + } + if (this.key > other.key) { + return 1; + } + if (this.value < other.value) { + return -1; + } + if (this.value > other.value) { + return 1; + } + return 0; + } + + public equals(other: ContextKeyExpression): boolean { + if (other.type === this.type) { + return (this.key === other.key && this.value === other.value); + } + return false; + } + + public evaluate(context: IContext): boolean { + return (Number(context.getValue(this.key)) < this.value); + } + + public serialize(): string { + return `${this.key} < '${this.value}'`; + } + + public keys(): string[] { + return [this.key]; + } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression { + return mapFnc.mapEquals(this.key, this.value); + } + + public negate(): ContextKeyExpression { + return ContextKeyNotEqualsExpr.create(this.key, this.value); + } +} + export class ContextKeyRegexExpr implements IContextKeyExpression { public static create(key: string, regexp: RegExp | null): ContextKeyRegexExpr { From 206fbe0bb3847a43f8cd3a7caafeff2d219116b2 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Mon, 23 Nov 2020 11:19:31 -0800 Subject: [PATCH 002/200] debug: use native logging in extension host https://github.com/microsoft/vscode/issues/104686 --- src/bootstrap-fork.js | 35 ++++++++++++++++--- .../debug/common/extensionHostDebug.ts | 9 ----- .../debug/common/extensionHostDebugIpc.ts | 16 +-------- .../api/browser/mainThreadConsole.ts | 11 +----- .../contrib/debug/browser/debugService.ts | 11 ------ .../localProcessExtensionHost.ts | 10 ++---- 6 files changed, 34 insertions(+), 58 deletions(-) diff --git a/src/bootstrap-fork.js b/src/bootstrap-fork.js index 0cd75027286..91822e6d234 100644 --- a/src/bootstrap-fork.js +++ b/src/bootstrap-fork.js @@ -135,18 +135,43 @@ function pipeLoggingToParent() { && !(obj instanceof Date); } + /** + * + * @param {'log' | 'warn' | 'error'} severity + * @param {string} args + */ + function safeSendConsoleMessage(severity, args) { + safeSend({ type: '__$console', severity, arguments: args }); + } + + /** + * @param {'log' | 'info' | 'warn' | 'error'} method + * @param {'log' | 'warn' | 'error'} severity + */ + function wrapConsoleMethod(method, severity) { + if (process.env.VSCODE_LOG_NATIVE === 'true') { + const original = console[method]; + console[method] = function () { + safeSendConsoleMessage(severity, safeToArray(arguments)); + original.apply(console, arguments); + }; + } else { + console[method] = function () { safeSendConsoleMessage(severity, safeToArray(arguments)); }; + } + } + // Pass console logging to the outside so that we have it in the main side if told so if (process.env.VERBOSE_LOGGING === 'true') { - console.log = function () { safeSend({ type: '__$console', severity: 'log', arguments: safeToArray(arguments) }); }; - console.info = function () { safeSend({ type: '__$console', severity: 'log', arguments: safeToArray(arguments) }); }; - console.warn = function () { safeSend({ type: '__$console', severity: 'warn', arguments: safeToArray(arguments) }); }; - } else { + wrapConsoleMethod('log', 'log'); + wrapConsoleMethod('warn', 'log'); + wrapConsoleMethod('error', 'warn'); + } else if (process.env.VSCODE_LOG_NATIVE !== 'true') { console.log = function () { /* ignore */ }; console.warn = function () { /* ignore */ }; console.info = function () { /* ignore */ }; } - console.error = function () { safeSend({ type: '__$console', severity: 'error', arguments: safeToArray(arguments) }); }; + wrapConsoleMethod('error', 'error'); } function handleExceptions() { diff --git a/src/vs/platform/debug/common/extensionHostDebug.ts b/src/vs/platform/debug/common/extensionHostDebug.ts index b263bdd9c1c..b30c4e44e73 100644 --- a/src/vs/platform/debug/common/extensionHostDebug.ts +++ b/src/vs/platform/debug/common/extensionHostDebug.ts @@ -5,7 +5,6 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { Event } from 'vs/base/common/event'; -import { IRemoteConsoleLog } from 'vs/base/common/console'; import { IProcessEnvironment } from 'vs/base/common/platform'; export const IExtensionHostDebugService = createDecorator('extensionHostDebugService'); @@ -16,11 +15,6 @@ export interface IAttachSessionEvent { port: number; } -export interface ILogToSessionEvent { - sessionId: string; - log: IRemoteConsoleLog; -} - export interface ITerminateSessionEvent { sessionId: string; subId?: string; @@ -50,9 +44,6 @@ export interface IExtensionHostDebugService { attachSession(sessionId: string, port: number, subId?: string): void; readonly onAttachSession: Event; - logToSession(sessionId: string, log: IRemoteConsoleLog): void; - readonly onLogToSession: Event; - terminateSession(sessionId: string, subId?: string): void; readonly onTerminateSession: Event; diff --git a/src/vs/platform/debug/common/extensionHostDebugIpc.ts b/src/vs/platform/debug/common/extensionHostDebugIpc.ts index 60011be13e3..09c2a1916fa 100644 --- a/src/vs/platform/debug/common/extensionHostDebugIpc.ts +++ b/src/vs/platform/debug/common/extensionHostDebugIpc.ts @@ -4,9 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { IServerChannel, IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IReloadSessionEvent, ICloseSessionEvent, IAttachSessionEvent, ILogToSessionEvent, ITerminateSessionEvent, IExtensionHostDebugService, IOpenExtensionWindowResult } from 'vs/platform/debug/common/extensionHostDebug'; +import { IReloadSessionEvent, ICloseSessionEvent, IAttachSessionEvent, ITerminateSessionEvent, IExtensionHostDebugService, IOpenExtensionWindowResult } from 'vs/platform/debug/common/extensionHostDebug'; import { Event, Emitter } from 'vs/base/common/event'; -import { IRemoteConsoleLog } from 'vs/base/common/console'; import { Disposable } from 'vs/base/common/lifecycle'; import { IProcessEnvironment } from 'vs/base/common/platform'; @@ -17,7 +16,6 @@ export class ExtensionHostDebugBroadcastChannel implements IServerChan private readonly _onCloseEmitter = new Emitter(); private readonly _onReloadEmitter = new Emitter(); private readonly _onTerminateEmitter = new Emitter(); - private readonly _onLogToEmitter = new Emitter(); private readonly _onAttachEmitter = new Emitter(); call(ctx: TContext, command: string, arg?: any): Promise { @@ -28,8 +26,6 @@ export class ExtensionHostDebugBroadcastChannel implements IServerChan return Promise.resolve(this._onReloadEmitter.fire({ sessionId: arg[0] })); case 'terminate': return Promise.resolve(this._onTerminateEmitter.fire({ sessionId: arg[0] })); - case 'log': - return Promise.resolve(this._onLogToEmitter.fire({ sessionId: arg[0], log: arg[1] })); case 'attach': return Promise.resolve(this._onAttachEmitter.fire({ sessionId: arg[0], port: arg[1], subId: arg[2] })); } @@ -44,8 +40,6 @@ export class ExtensionHostDebugBroadcastChannel implements IServerChan return this._onReloadEmitter.event; case 'terminate': return this._onTerminateEmitter.event; - case 'log': - return this._onLogToEmitter.event; case 'attach': return this._onAttachEmitter.event; } @@ -85,14 +79,6 @@ export class ExtensionHostDebugChannelClient extends Disposable implements IExte return this.channel.listen('attach'); } - logToSession(sessionId: string, log: IRemoteConsoleLog): void { - this.channel.call('log', [sessionId, log]); - } - - get onLogToSession(): Event { - return this.channel.listen('log'); - } - terminateSession(sessionId: string, subId?: string): void { this.channel.call('terminate', [sessionId, subId]); } diff --git a/src/vs/workbench/api/browser/mainThreadConsole.ts b/src/vs/workbench/api/browser/mainThreadConsole.ts index 4a244875f42..d678f21bc67 100644 --- a/src/vs/workbench/api/browser/mainThreadConsole.ts +++ b/src/vs/workbench/api/browser/mainThreadConsole.ts @@ -10,22 +10,18 @@ import { IRemoteConsoleLog, log } from 'vs/base/common/console'; import { logRemoteEntry } from 'vs/workbench/services/extensions/common/remoteConsoleUtil'; import { parseExtensionDevOptions } from 'vs/workbench/services/extensions/common/extensionDevOptions'; import { ILogService } from 'vs/platform/log/common/log'; -import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug'; @extHostNamedCustomer(MainContext.MainThreadConsole) export class MainThreadConsole implements MainThreadConsoleShape { - private readonly _isExtensionDevHost: boolean; private readonly _isExtensionDevTestFromCli: boolean; constructor( - extHostContext: IExtHostContext, + _extHostContext: IExtHostContext, @IEnvironmentService private readonly _environmentService: IEnvironmentService, @ILogService private readonly _logService: ILogService, - @IExtensionHostDebugService private readonly _extensionHostDebugService: IExtensionHostDebugService, ) { const devOpts = parseExtensionDevOptions(this._environmentService); - this._isExtensionDevHost = devOpts.isExtensionDevHost; this._isExtensionDevTestFromCli = devOpts.isExtensionDevTestFromCli; } @@ -43,10 +39,5 @@ export class MainThreadConsole implements MainThreadConsoleShape { if (this._isExtensionDevTestFromCli) { logRemoteEntry(this._logService, entry); } - - // Broadcast to other windows if we are in development mode - else if (this._environmentService.debugExtensionHost.debugId && (!this._environmentService.isBuilt || this._isExtensionDevHost)) { - this._extensionHostDebugService.logToSession(this._environmentService.debugExtensionHost.debugId, entry); - } } } diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index 4e99febee24..03e5dd87899 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -25,7 +25,6 @@ import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/bro import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { parse, getFirstFrame } from 'vs/base/common/console'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IAction, Action } from 'vs/base/common/actions'; @@ -149,16 +148,6 @@ export class DebugService implements IDebugService { session.disconnect(); } })); - this.toDispose.push(this.extensionHostDebugService.onLogToSession(event => { - const session = this.model.getSession(event.sessionId, true); - if (session) { - // extension logged output -> show it in REPL - const sev = event.log.severity === 'warn' ? severity.Warning : event.log.severity === 'error' ? severity.Error : severity.Info; - const { args, stack } = parse(event.log); - const frame = !!stack ? getFirstFrame(stack) : undefined; - session.logToRepl(sev, args, frame); - } - })); this.toDispose.push(this.viewModel.onDidFocusStackFrame(() => { this.onStateChange(); diff --git a/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts index 5ec4c4bbae8..024c8f95fde 100644 --- a/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts @@ -151,13 +151,12 @@ export class LocalProcessExtensionHost implements IExtensionHost { this._messageProtocol = Promise.all([ this._tryListenOnPipe(), this._tryFindDebugPort() - ]).then(data => { - const pipeName = data[0]; - const portNumber = data[1]; + ]).then(([pipeName, portNumber]) => { const env = objects.mixin(objects.deepClone(process.env), { AMD_ENTRYPOINT: 'vs/workbench/services/extensions/node/extensionHostProcess', PIPE_LOGGING: 'true', VERBOSE_LOGGING: true, + VSCODE_LOG_NATIVE: this._isExtensionDevHost, VSCODE_IPC_HOOK_EXTHOST: pipeName, VSCODE_HANDLES_UNCAUGHT_ERRORS: true, VSCODE_LOG_STACK: !this._isExtensionDevTestFromCli && (this._isExtensionDevHost || !this._environmentService.isBuilt || this._productService.quality !== 'stable' || this._environmentService.verbose), @@ -497,11 +496,6 @@ export class LocalProcessExtensionHost implements IExtensionHost { // Send to local console log(entry, 'Extension Host'); - - // Broadcast to other windows if we are in development mode - if (this._environmentService.debugExtensionHost.debugId && (!this._environmentService.isBuilt || this._isExtensionDevHost)) { - this._extensionHostDebugService.logToSession(this._environmentService.debugExtensionHost.debugId, entry); - } } } From 304d3d7e36f7cf483a0d1cd88e0bfc3a1b12f3e5 Mon Sep 17 00:00:00 2001 From: Martin Desrosiers Date: Mon, 30 Nov 2020 12:53:16 -0800 Subject: [PATCH 003/200] Handle rejected promise in history delayer --- src/vs/editor/contrib/find/findWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 33944824331..597af6c3271 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -380,7 +380,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL } private _delayedUpdateHistory() { - this._updateHistoryDelayer.trigger(this._updateHistory.bind(this)); + this._updateHistoryDelayer.trigger(this._updateHistory.bind(this)).then(undefined, onUnexpectedError); } private _updateHistory() { From c96643feab09926d21cc0559579dcffe71017d54 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 1 Dec 2020 19:01:22 +0100 Subject: [PATCH 004/200] Fix #111598 --- .../contrib/preferences/browser/keybindingsEditor.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts index 43c3806aa16..7b7c3dd59ed 100644 --- a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts +++ b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts @@ -691,8 +691,10 @@ export class KeybindingsEditor extends EditorPane implements IKeybindingsEditorP ...(keybindingItemEntry.keybindingItem.keybinding ? [this.createDefineKeybindingAction(keybindingItemEntry), this.createAddKeybindingAction(keybindingItemEntry)] : [this.createDefineKeybindingAction(keybindingItemEntry)]), + new Separator(), this.createRemoveAction(keybindingItemEntry), this.createResetAction(keybindingItemEntry), + new Separator(), this.createDefineWhenExpressionAction(keybindingItemEntry), new Separator(), this.createShowConflictsAction(keybindingItemEntry)] @@ -713,7 +715,7 @@ export class KeybindingsEditor extends EditorPane implements IKeybindingsEditorP private createDefineKeybindingAction(keybindingItemEntry: IKeybindingItemEntry): IAction { return { - label: keybindingItemEntry.keybindingItem.keybinding ? localize('changeLabel', "Change Keybinding") : localize('addLabel', "Add Keybinding"), + label: keybindingItemEntry.keybindingItem.keybinding ? localize('changeLabel', "Change Keybinding...") : localize('addLabel', "Add Keybinding..."), enabled: true, id: KEYBINDINGS_EDITOR_COMMAND_DEFINE, run: () => this.defineKeybinding(keybindingItemEntry, false) @@ -722,7 +724,7 @@ export class KeybindingsEditor extends EditorPane implements IKeybindingsEditorP private createAddKeybindingAction(keybindingItemEntry: IKeybindingItemEntry): IAction { return { - label: localize('addLabel', "Add Keybinding"), + label: localize('addLabel', "Add Keybinding..."), enabled: true, id: KEYBINDINGS_EDITOR_COMMAND_ADD, run: () => this.defineKeybinding(keybindingItemEntry, true) From 4d9277a23a035cb0493a856ce4b1174d0db5512c Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Tue, 1 Dec 2020 10:07:32 -0800 Subject: [PATCH 005/200] Optimize autosave message when changing settings. Fixes #111648 --- src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index d6c34ed2e81..7abb3fca76f 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -735,7 +735,7 @@ export class SettingsEditor2 extends EditorPane { private notifyNoSaveNeeded() { if (!this.storageService.getBoolean(SETTINGS_AUTOSAVE_NOTIFIED_KEY, StorageScope.GLOBAL, false)) { this.storageService.store(SETTINGS_AUTOSAVE_NOTIFIED_KEY, true, StorageScope.GLOBAL, StorageTarget.USER); - this.notificationService.info(localize('settingsNoSaveNeeded', "Your changes are automatically saved as you edit.")); + this.notificationService.info(localize('settingsNoSaveNeeded', "Changes to settings are saved automatically.")); } } From a0aeb3a559215f89b87d79692c83bb2d7033472a Mon Sep 17 00:00:00 2001 From: dataleaky <68432397+dataleaky@users.noreply.github.com> Date: Tue, 1 Dec 2020 23:39:50 +0500 Subject: [PATCH 006/200] Update package.json --- extensions/html-language-features/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index 3e7a0dbd62d..c2c211ccbaa 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -144,7 +144,7 @@ "null" ], "scope": "resource", - "default": "null", + "default": null, "description": "%html.format.wrapAttributesIndentSize.desc%" }, "html.format.templating": { From 8fa61d9652c6131ec6c3d770aeabb3f1651ade0f Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 1 Dec 2020 15:21:39 +0100 Subject: [PATCH 007/200] Fix a dependency URL --- ThirdPartyNotices.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index f4b36447f47..0d0db3acade 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -66,7 +66,7 @@ This project incorporates components from the projects listed below. The origina 59. vscode-codicons version 0.0.1 (https://github.com/microsoft/vscode-codicons) 60. vscode-logfile-highlighter version 2.8.0 (https://github.com/emilast/vscode-logfile-highlighter) 61. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift) -62. Web Background Synchronization (https://github.com/WICG/BackgroundSync) +62. Web Background Synchronization (https://github.com/WICG/background-sync) %% atom/language-clojure NOTICES AND INFORMATION BEGIN HERE From b2c2c20fe74766d724baced51e45618000ee7f67 Mon Sep 17 00:00:00 2001 From: rebornix Date: Tue, 1 Dec 2020 14:12:30 -0800 Subject: [PATCH 008/200] fix #109626. --- src/vs/workbench/contrib/notebook/browser/media/notebook.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/contrib/notebook/browser/media/notebook.css b/src/vs/workbench/contrib/notebook/browser/media/notebook.css index 11a3fd0ebdf..3547b989dd4 100644 --- a/src/vs/workbench/contrib/notebook/browser/media/notebook.css +++ b/src/vs/workbench/contrib/notebook/browser/media/notebook.css @@ -535,6 +535,11 @@ cursor: grab; } +.monaco-workbench .notebookOverlay.notebook-editor-editable > .cell-list-container > .monaco-list > .monaco-scrollable-element > .scrollbar.visible { + z-index: 50; + cursor: default; +} + .monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator .codicon:hover { cursor: pointer; } From 9dba02c075b4247dc18fccebc1ad0fba4bf04d22 Mon Sep 17 00:00:00 2001 From: rebornix Date: Tue, 1 Dec 2020 14:19:15 -0800 Subject: [PATCH 009/200] re #109594. --- .../notebook/browser/contrib/scm/scm.ts | 163 ------------------ 1 file changed, 163 deletions(-) delete mode 100644 src/vs/workbench/contrib/notebook/browser/contrib/scm/scm.ts diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/scm/scm.ts b/src/vs/workbench/contrib/notebook/browser/contrib/scm/scm.ts deleted file mode 100644 index 670a805cf79..00000000000 --- a/src/vs/workbench/contrib/notebook/browser/contrib/scm/scm.ts +++ /dev/null @@ -1,163 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { INotebookEditorContribution, INotebookEditor } from '../../notebookBrowser'; -import { registerNotebookContribution } from '../../notebookEditorExtensions'; -import { ISCMService } from 'vs/workbench/contrib/scm/common/scm'; -import { createProviderComparer } from 'vs/workbench/contrib/scm/browser/dirtydiffDecorator'; -import { first, ThrottledDelayer } from 'vs/base/common/async'; -import { INotebookService } from '../../../common/notebookService'; -import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; -import { FileService } from 'vs/platform/files/common/fileService'; -import { IFileService } from 'vs/platform/files/common/files'; -import { URI } from 'vs/base/common/uri'; - -export class SCMController extends Disposable implements INotebookEditorContribution { - static id: string = 'workbench.notebook.findController'; - private _lastDecorationId: string[] = []; - private _localDisposable = new DisposableStore(); - private _originalDocument: NotebookTextModel | undefined = undefined; - private _originalResourceDisposableStore = new DisposableStore(); - private _diffDelayer = new ThrottledDelayer(200); - - private _lastVersion = -1; - - - constructor( - private readonly _notebookEditor: INotebookEditor, - @IFileService private readonly _fileService: FileService, - @ISCMService private readonly _scmService: ISCMService, - @INotebookService private readonly _notebookService: INotebookService - - ) { - super(); - - if (!this._notebookEditor.isEmbedded) { - this._register(this._notebookEditor.onDidChangeModel(() => { - this._localDisposable.clear(); - this._originalResourceDisposableStore.clear(); - this._diffDelayer.cancel(); - this.update(); - - if (this._notebookEditor.textModel) { - this._localDisposable.add(this._notebookEditor.textModel.onDidChangeContent((e) => { - this.update(); - })); - } - })); - - this._register(this._notebookEditor.onWillDispose(() => { - this._localDisposable.clear(); - this._originalResourceDisposableStore.clear(); - })); - - this.update(); - } - } - - private async _resolveNotebookDocument(uri: URI, viewType: string) { - const providers = this._scmService.repositories.map(r => r.provider); - const rootedProviders = providers.filter(p => !!p.rootUri); - - rootedProviders.sort(createProviderComparer(uri)); - - const result = await first(rootedProviders.map(p => () => p.getOriginalResource(uri))); - - if (!result) { - this._originalDocument = undefined; - this._originalResourceDisposableStore.clear(); - return; - } - - if (result.toString() === this._originalDocument?.uri.toString()) { - // original document not changed - return; - } - - this._originalResourceDisposableStore.add(this._fileService.watch(result)); - this._originalResourceDisposableStore.add(this._fileService.onDidFilesChange(e => { - if (e.contains(result)) { - this._originalDocument = undefined; - this._originalResourceDisposableStore.clear(); - this.update(); - } - })); - - const originalDocument = await this._notebookService.resolveNotebook(viewType, result, false); - this._originalResourceDisposableStore.add({ - dispose: () => { - this._originalDocument?.dispose(); - this._originalDocument = undefined; - } - }); - - this._originalDocument = originalDocument; - } - - async update() { - if (!this._diffDelayer) { - return; - } - - await this._diffDelayer - .trigger(async () => { - const modifiedDocument = this._notebookEditor.textModel; - if (!modifiedDocument) { - return; - } - - if (this._lastVersion >= modifiedDocument.versionId) { - return; - } - - this._lastVersion = modifiedDocument.versionId; - await this._resolveNotebookDocument(modifiedDocument.uri, modifiedDocument.viewType); - - if (!this._originalDocument) { - this._clear(); - return; - } - - // const diff = new LcsDiff(new CellSequence(this._originalDocument), new CellSequence(modifiedDocument)); - // const diffResult = diff.ComputeDiff(false); - - // const decorations: INotebookDeltaDecoration[] = []; - // diffResult.changes.forEach(change => { - // if (change.originalLength === 0) { - // // doesn't exist in original - // for (let i = 0; i < change.modifiedLength; i++) { - // decorations.push({ - // handle: modifiedDocument.cells[change.modifiedStart + i].handle, - // options: { gutterClassName: 'nb-gutter-cell-inserted' } - // }); - // } - // } else { - // if (change.modifiedLength === 0) { - // // diff.deleteCount - // // removed from original - // } else { - // // modification - // for (let i = 0; i < change.modifiedLength; i++) { - // decorations.push({ - // handle: modifiedDocument.cells[change.modifiedStart + i].handle, - // options: { gutterClassName: 'nb-gutter-cell-changed' } - // }); - // } - // } - // } - // }); - - - // this._lastDecorationId = this._notebookEditor.deltaCellDecorations(this._lastDecorationId, decorations); - }); - } - - private _clear() { - this._lastDecorationId = this._notebookEditor.deltaCellDecorations(this._lastDecorationId, []); - } -} - -registerNotebookContribution(SCMController.id, SCMController); From 5e54da666cd0cd3c67110ac2cf81a334b1f9af6d Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 1 Dec 2020 17:03:25 -0800 Subject: [PATCH 010/200] fix #111675 and #111673 --- .../src/features/smartSelect.ts | 89 +++++++------------ .../src/test/smartSelect.test.ts | 25 +++++- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/extensions/markdown-language-features/src/features/smartSelect.ts b/extensions/markdown-language-features/src/features/smartSelect.ts index 0fca6a5483c..ae6b79faa34 100644 --- a/extensions/markdown-language-features/src/features/smartSelect.ts +++ b/extensions/markdown-language-features/src/features/smartSelect.ts @@ -131,9 +131,17 @@ function createInlineRange(document: vscode.TextDocument, cursorPosition: vscode const lineText = document.lineAt(cursorPosition.line).text; const boldSelection = createBoldRange(lineText, cursorPosition.character, cursorPosition.line, parent); const italicSelection = createOtherInlineRange(lineText, cursorPosition.character, cursorPosition.line, true, parent); - const linkSelection = createLinkRange(lineText, cursorPosition.character, cursorPosition.line, boldSelection ? boldSelection : italicSelection || parent); + let comboSelection: vscode.SelectionRange | undefined; + if (boldSelection && italicSelection && !boldSelection.range.isEqual(italicSelection.range)) { + if (boldSelection.range.contains(italicSelection.range)) { + comboSelection = createOtherInlineRange(lineText, cursorPosition.character, cursorPosition.line, true, boldSelection); + } else if (italicSelection.range.contains(boldSelection.range)) { + comboSelection = createBoldRange(lineText, cursorPosition.character, cursorPosition.line, italicSelection); + } + } + const linkSelection = createLinkRange(lineText, cursorPosition.character, cursorPosition.line, comboSelection || boldSelection || italicSelection || parent); const inlineCodeBlockSelection = createOtherInlineRange(lineText, cursorPosition.character, cursorPosition.line, false, linkSelection || parent); - return inlineCodeBlockSelection || linkSelection || boldSelection || italicSelection; + return inlineCodeBlockSelection || linkSelection || comboSelection || boldSelection || italicSelection; } function createFencedRange(token: Token, cursorLine: number, document: vscode.TextDocument, parent?: vscode.SelectionRange): vscode.SelectionRange { @@ -154,61 +162,31 @@ function createFencedRange(token: Token, cursorLine: number, document: vscode.Te } function createBoldRange(lineText: string, cursorChar: number, cursorLine: number, parent?: vscode.SelectionRange): vscode.SelectionRange | undefined { - // find closest ** that occurs before cursor position - let startBold = lineText.substring(0, cursorChar).lastIndexOf('**'); - - // find closest ** that occurs after the start ** - const endBoldIndex = lineText.substring(startBold + 2).indexOf('**'); - let endBold = startBold + 2 + lineText.substring(startBold + 2).indexOf('**'); - - if (startBold >= 0 && endBoldIndex >= 0 && startBold + 1 < endBold && startBold <= cursorChar && endBold >= cursorChar) { - const range = new vscode.Range(cursorLine, startBold, cursorLine, endBold + 2); - // **content cursor content** so select content then ** on both sides - const contentRange = new vscode.Range(cursorLine, startBold + 2, cursorLine, endBold); - return new vscode.SelectionRange(contentRange, new vscode.SelectionRange(range, parent)); - } else if (startBold >= 0) { - // **content**cursor or **content*cursor* - // find end ** from end of start ** to end of line (since the cursor is within the end stars) - let adjustedEnd = startBold + 2 + lineText.substring(startBold + 2).indexOf('**'); - startBold = lineText.substring(0, adjustedEnd - 2).lastIndexOf('**'); - if (adjustedEnd >= 0 && cursorChar === adjustedEnd || cursorChar === adjustedEnd + 1) { - if (lineText.charAt(adjustedEnd + 1) === '*') { - // *cursor* so need to extend end to include the second * - adjustedEnd += 1; - } - return new vscode.SelectionRange(new vscode.Range(cursorLine, startBold, cursorLine, adjustedEnd + 1), parent); - } - } else if (endBold > 0) { - // cursor**content** or *cursor*content** - // find start ** from start of string to cursor + 2 (since the cursor is within the start stars) - const adjustedStart = lineText.substring(0, cursorChar + 2).lastIndexOf('**'); - endBold = adjustedStart + 2 + lineText.substring(adjustedStart + 2).indexOf('**'); - if (adjustedStart >= 0 && adjustedStart === cursorChar || adjustedStart === cursorChar - 1) { - return new vscode.SelectionRange(new vscode.Range(cursorLine, adjustedStart, cursorLine, endBold + 2), parent); - } + const regex = /(?:^|(?<=\s))(?:\*\*\s*([^*]+)(?:\*\s*([^*]+)\s*?\*)*([^*]+)\s*?\*\*)/g; + const matches = [...lineText.matchAll(regex)].filter(match => lineText.indexOf(match[0]) <= cursorChar && lineText.indexOf(match[0]) + match[0].length >= cursorChar); + if (matches.length > 0) { + // should only be one match, so select first and index 0 contains the entire match + const bold = matches[0][0]; + const startIndex = lineText.indexOf(bold); + const cursorOnStars = cursorChar === startIndex || cursorChar === startIndex + 1 || cursorChar === startIndex + bold.length || cursorChar === startIndex + bold.length - 1; + const contentAndStars = new vscode.SelectionRange(new vscode.Range(cursorLine, startIndex, cursorLine, startIndex + bold.length), parent); + const content = new vscode.SelectionRange(new vscode.Range(cursorLine, startIndex + 2, cursorLine, startIndex + bold.length - 2), contentAndStars); + return cursorOnStars ? contentAndStars : content; } return undefined; } function createOtherInlineRange(lineText: string, cursorChar: number, cursorLine: number, isItalic: boolean, parent?: vscode.SelectionRange): vscode.SelectionRange | undefined { - const type = isItalic ? '*' : '`'; - const start = lineText.substring(0, cursorChar + 1).lastIndexOf(type); - let end = lineText.substring(cursorChar).indexOf(type); - - if (start >= 0 && end >= 0) { - end += cursorChar; - // ensure there's no * or ` before end - const intermediate = lineText.substring(start + 1, end - 1).indexOf(type); - if (intermediate < 0) { - const range = new vscode.Range(cursorLine, start, cursorLine, end + 1); - if (cursorChar > start && cursorChar <= end) { - // within the content so select content then include the stars or backticks - const contentRange = new vscode.Range(cursorLine, start + 1, cursorLine, end); - return new vscode.SelectionRange(contentRange, new vscode.SelectionRange(range, parent)); - } else if (cursorChar === start) { - return new vscode.SelectionRange(range, parent); - } - } + const regex = isItalic ? /(?:^|(?<=\s))(?:\*\s*([^*]+)(?:\*\*\s*([^*]+)\s*?\*\*)*([^*]+)\s*?\*)/g : /\`[^\`]*\`/g; + const matches = [...lineText.matchAll(regex)].filter(match => lineText.indexOf(match[0]) <= cursorChar && lineText.indexOf(match[0]) + match[0].length >= cursorChar); + if (matches.length > 0) { + // should only be one match, so select first and index 0 contains the entire match + const match = matches[0][0]; + const startIndex = lineText.indexOf(match); + const cursorOnType = cursorChar === startIndex || cursorChar === startIndex + match.length; + const contentAndType = new vscode.SelectionRange(new vscode.Range(cursorLine, startIndex, cursorLine, startIndex + match.length), parent); + const content = new vscode.SelectionRange(new vscode.Range(cursorLine, startIndex + 1, cursorLine, startIndex + match.length - 1), contentAndType); + return cursorOnType ? contentAndType : content; } return undefined; } @@ -228,11 +206,12 @@ function createLinkRange(lineText: string, cursorChar: number, cursorLine: numbe // determine if cursor is within [text] or (url) in order to know which should be selected const nearestType = cursorChar >= lineText.indexOf(linkText) && cursorChar < lineText.indexOf(linkText) + linkText.length ? linkText : url; + const indexOfType = lineText.indexOf(nearestType); // determine if cursor is on a bracket or paren and if so, return the [content] or (content), skipping over the content range - const cursorOnType = cursorChar === lineText.indexOf(nearestType) || cursorChar === lineText.indexOf(nearestType) + nearestType.length; + const cursorOnType = cursorChar === indexOfType || cursorChar === indexOfType + nearestType.length; - const contentAndNearestType = new vscode.SelectionRange(new vscode.Range(cursorLine, lineText.indexOf(nearestType), cursorLine, lineText.indexOf(nearestType) + nearestType.length), linkRange); - const content = new vscode.SelectionRange(new vscode.Range(cursorLine, lineText.indexOf(nearestType) + 1, cursorLine, lineText.indexOf(nearestType) + nearestType.length - 1), contentAndNearestType); + const contentAndNearestType = new vscode.SelectionRange(new vscode.Range(cursorLine, indexOfType, cursorLine, indexOfType + nearestType.length), linkRange); + const content = new vscode.SelectionRange(new vscode.Range(cursorLine, indexOfType + 1, cursorLine, indexOfType + nearestType.length - 1), contentAndNearestType); return cursorOnType ? contentAndNearestType : content; } return undefined; diff --git a/extensions/markdown-language-features/src/test/smartSelect.test.ts b/extensions/markdown-language-features/src/test/smartSelect.test.ts index 98f2a5de607..15fb24e32ff 100644 --- a/extensions/markdown-language-features/src/test/smartSelect.test.ts +++ b/extensions/markdown-language-features/src/test/smartSelect.test.ts @@ -520,10 +520,10 @@ suite('markdown.SmartSelect', () => { `paragraph`, `## sub header`, `- list`, - `- stuff here [text]**${CURSOR}items in here** and **here**`, + `- stuff here [text] **${CURSOR}items in here** and **here**`, `- list` )); - assertNestedRangesEqual(ranges![0], [6, 21, 6, 44], [6, 19, 6, 46], [6, 0, 6, 59], [5, 0, 7, 6], [4, 0, 7, 6], [1, 0, 7, 6], [0, 0, 7, 6]); + assertNestedRangesEqual(ranges![0], [6, 22, 6, 45], [6, 20, 6, 47], [6, 0, 6, 60], [5, 0, 7, 6], [4, 0, 7, 6], [1, 0, 7, 6], [0, 0, 7, 6]); }); test('Smart select link in paragraph with multiple links', async () => { const ranges = await getSelectionRangesForDocument( @@ -567,6 +567,27 @@ suite('markdown.SmartSelect', () => { )); assertNestedRangesEqual(ranges![0], [0, 2, 0, 21], [0, 1, 0, 22], [0, 1, 0, 42], [0, 1, 0, 42], [0, 0, 0, 43], [0, 0, 0, 43]); }); + test('Smart select italic on end', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `*word1 word2 word3${CURSOR}*` + )); + assertNestedRangesEqual(ranges![0], [0, 1, 0, 28], [0, 0, 0, 29], [0, 0, 0, 29]); + }); + test('Smart select italic then bold', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `outer text **bold words *italic ${CURSOR} words* bold words** outer text` + )); + assertNestedRangesEqual(ranges![0], [0, 25, 0, 48], [0, 24, 0, 49], [0, 13, 0, 60], [0, 11, 0, 62], [0, 0, 0, 73]); + }); + test('Smart select bold then italic', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `outer text *italic words **bold ${CURSOR} words** italic words* outer text` + )); + assertNestedRangesEqual(ranges![0], [0, 27, 0, 48], [0, 25, 0, 50], [0, 12, 0, 63], [0, 11, 0, 64], [0, 0, 0, 75]); + }); }); function assertNestedLineNumbersEqual(range: vscode.SelectionRange, ...expectedRanges: [number, number][]) { From 647cecb29dcefb6da5b57b020194e426e34e4b20 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 1 Dec 2020 20:55:23 -0800 Subject: [PATCH 011/200] build: exclude electron-11.x.y branch from continuous build Fixes https://github.com/microsoft/vscode/issues/111313 --- azure-pipelines.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b2f9a13c2b7..cce8119d463 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -16,3 +16,8 @@ jobs: vmImage: macOS-latest steps: - template: build/azure-pipelines/darwin/continuous-build-darwin.yml + +trigger: + branches: + exclude: + - electron-11.x.y From 60f5e6ee9a1bddd9114b8db54ef066231cafe46c Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 1 Dec 2020 21:00:48 -0800 Subject: [PATCH 012/200] build: disable exploration sync --- build/azure-pipelines/exploration-build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/azure-pipelines/exploration-build.yml b/build/azure-pipelines/exploration-build.yml index c20ff939ad9..840d5e41c2d 100644 --- a/build/azure-pipelines/exploration-build.yml +++ b/build/azure-pipelines/exploration-build.yml @@ -38,3 +38,5 @@ steps: git push origin HEAD:electron-11.x.y displayName: Sync & Merge Exploration + +trigger: none From d9ea0ced98f8527fc605364372ddbcdc54d476f2 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 1 Dec 2020 21:02:25 -0800 Subject: [PATCH 013/200] build: fix config --- build/azure-pipelines/exploration-build.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/build/azure-pipelines/exploration-build.yml b/build/azure-pipelines/exploration-build.yml index 840d5e41c2d..4a7acf129b3 100644 --- a/build/azure-pipelines/exploration-build.yml +++ b/build/azure-pipelines/exploration-build.yml @@ -1,12 +1,7 @@ pool: vmImage: "Ubuntu-16.04" -trigger: - branches: - include: ["master"] -pr: - branches: - include: ["master"] +trigger: none steps: - task: NodeTool@0 @@ -38,5 +33,3 @@ steps: git push origin HEAD:electron-11.x.y displayName: Sync & Merge Exploration - -trigger: none From c76a42acc648e82ea9fd0225e893e3ed697daaf4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 2 Dec 2020 08:06:48 +0100 Subject: [PATCH 014/200] Bad rendering of status bar item with error background color (fix #111618) --- src/vs/vscode.proposed.d.ts | 4 ++-- .../workbench/api/common/extHostStatusBar.ts | 24 ++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 9609c022a7c..292af786ee1 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -2311,8 +2311,8 @@ declare module 'vscode' { * `ThemeColors` with id `statusBarItem.errorBackground`. Other `ThemeColors` * will be ignored. * - * When setting the background color to `statusBarItem.errorBackground`, it is - * recommended to also set `color` to `statusBarItem.errorForeground`. + * When setting the background color to `statusBarItem.errorBackground`, the + * `color` property will automatically be set to `statusBarItem.errorForeground`. */ backgroundColor: ThemeColor | undefined; } diff --git a/src/vs/workbench/api/common/extHostStatusBar.ts b/src/vs/workbench/api/common/extHostStatusBar.ts index aa0b5df6cdb..a89e9fe3081 100644 --- a/src/vs/workbench/api/common/extHostStatusBar.ts +++ b/src/vs/workbench/api/common/extHostStatusBar.ts @@ -15,7 +15,15 @@ import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common export class ExtHostStatusBarEntry implements vscode.StatusBarItem { private static ID_GEN = 0; - private static ALLOWED_BACKGROUND_COLORS = new Set(['statusBarItem.errorBackground']); + + private static ALLOWED_BACKGROUND_COLORS = (() => { + const map = new Map(); + + // https://github.com/microsoft/vscode/issues/110214 + map.set('statusBarItem.errorBackground', new ThemeColor('statusBarItem.errorForeground')); + + return map; + })(); private _id: number; private _alignment: number; @@ -79,6 +87,10 @@ export class ExtHostStatusBarEntry implements vscode.StatusBarItem { } public get backgroundColor(): ThemeColor | undefined { + if (this._extension) { + checkProposedApiEnabled(this._extension); + } + return this._backgroundColor; } @@ -167,9 +179,15 @@ export class ExtHostStatusBarEntry implements vscode.StatusBarItem { this._timeoutHandle = setTimeout(() => { this._timeoutHandle = undefined; + // If a background color is set, the foreground is determined + let color = this._color; + if (this._backgroundColor) { + color = ExtHostStatusBarEntry.ALLOWED_BACKGROUND_COLORS.get(this._backgroundColor.id); + } + // Set to status bar - this._proxy.$setEntry(this.id, this._statusId, this._statusName, this.text, this.tooltip, this._command?.internal, this.color, - this.backgroundColor, this._alignment === ExtHostStatusBarAlignment.Left ? MainThreadStatusBarAlignment.LEFT : MainThreadStatusBarAlignment.RIGHT, + this._proxy.$setEntry(this.id, this._statusId, this._statusName, this._text, this._tooltip, this._command?.internal, color, + this._backgroundColor, this._alignment === ExtHostStatusBarAlignment.Left ? MainThreadStatusBarAlignment.LEFT : MainThreadStatusBarAlignment.RIGHT, this._priority, this._accessibilityInformation); }, 0); } From b2ef11885736635690387782cb3deb17d98912ee Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 2 Dec 2020 08:12:28 +0100 Subject: [PATCH 015/200] window.restoreWindows: preserve description polish (fix #111607) --- src/vs/workbench/electron-sandbox/desktop.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts index 43d45e49904..63bc327faa9 100644 --- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts +++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts @@ -213,7 +213,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema'; 'type': 'string', 'enum': ['preserve', 'all', 'folders', 'one', 'none'], 'enumDescriptions': [ - nls.localize('window.reopenFolders.preserve', "Reopen all windows. If a folder or workspace is opened (e.g. from the command line) it opens as new window. Files will open in one of the restored windows."), + nls.localize('window.reopenFolders.preserve', "Always reopen all windows. If a folder or workspace is opened (e.g. from the command line) it opens as a new window unless it was opened before. If files are opened they will open in one of the restored windows."), nls.localize('window.reopenFolders.all', "Reopen all windows unless a folder, workspace or file is opened (e.g. from the command line)."), nls.localize('window.reopenFolders.folders', "Reopen all windows that had folders or workspaces opened unless a folder, workspace or file is opened (e.g. from the command line)."), nls.localize('window.reopenFolders.one', "Reopen the last active window unless a folder, workspace or file is opened (e.g. from the command line)."), From 14bf08070504ba8ab2a24af353d0a58472e0609a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 2 Dec 2020 08:41:33 +0100 Subject: [PATCH 016/200] Keep Editors Open menu choice in the editor '...' menu should be a checked option (fix #111668) --- .../browser/parts/editor/editor.contribution.ts | 2 +- .../workbench/browser/parts/editor/editorCommands.ts | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 67b1c29733b..fdb0a57ac9d 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -464,7 +464,7 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands. MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.SHOW_EDITORS_IN_GROUP, title: nls.localize('showOpenedEditors', "Show Opened Editors") }, group: '3_open', order: 10 }); MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID, title: nls.localize('closeAll', "Close All") }, group: '5_close', order: 10 }); MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.CLOSE_SAVED_EDITORS_COMMAND_ID, title: nls.localize('closeAllSaved', "Close Saved") }, group: '5_close', order: 20 }); -MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.KEEP_EDITORS_COMMAND_ID, title: nls.localize('toggleKeepEditors', "Keep Editors Open") }, when: ContextKeyExpr.has('config.workbench.editor.enablePreview'), group: '7_settings', order: 10 }); +MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.TOGGLE_KEEP_EDITORS_COMMAND_ID, title: nls.localize('toggleKeepEditors', "Keep Editors Open"), toggled: ContextKeyExpr.not('config.workbench.editor.enablePreview') }, group: '7_settings', order: 10 }); interface IEditorToolItem { id: string; title: string; icon?: { dark?: URI; light?: URI; } | ThemeIcon; } diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index c776c18a2f2..dcece5343cb 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -40,7 +40,7 @@ export const CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID = 'workbench.action.closeOt export const MOVE_ACTIVE_EDITOR_COMMAND_ID = 'moveActiveEditor'; export const LAYOUT_EDITOR_GROUPS_COMMAND_ID = 'layoutEditorGroups'; export const KEEP_EDITOR_COMMAND_ID = 'workbench.action.keepEditor'; -export const KEEP_EDITORS_COMMAND_ID = 'workbench.action.keepEditors'; +export const TOGGLE_KEEP_EDITORS_COMMAND_ID = 'workbench.action.toggleKeepEditors'; export const SHOW_EDITORS_IN_GROUP = 'workbench.action.showEditorsInGroup'; export const PIN_EDITOR_COMMAND_ID = 'workbench.action.pinEditor'; @@ -899,19 +899,23 @@ function registerOtherEditorCommands(): void { }); CommandsRegistry.registerCommand({ - id: KEEP_EDITORS_COMMAND_ID, + id: TOGGLE_KEEP_EDITORS_COMMAND_ID, handler: accessor => { const configurationService = accessor.get(IConfigurationService); const notificationService = accessor.get(INotificationService); const openerService = accessor.get(IOpenerService); // Update setting - configurationService.updateValue('workbench.editor.enablePreview', false); + const currentSetting = configurationService.getValue('workbench.editor.enablePreview'); + const newSetting = currentSetting === true ? false : true; + configurationService.updateValue('workbench.editor.enablePreview', newSetting); // Inform user notificationService.prompt( Severity.Info, - nls.localize('disablePreview', "Preview editors have been disabled in settings."), + newSetting ? + nls.localize('enablePreview', "Preview editors have been enabled in settings.") : + nls.localize('disablePreview', "Preview editors have been disabled in settings."), [{ label: nls.localize('learnMode', "Learn More"), run: () => openerService.open('https://go.microsoft.com/fwlink/?linkid=2147473') }] From c44732014de3bfe009d56b4eb7371ef7d2a4987c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 2 Dec 2020 09:51:29 +0100 Subject: [PATCH 017/200] windows - prefer to focus window where files open in --- .../electron-main/windowsMainService.ts | 152 +++++++++++------- 1 file changed, 91 insertions(+), 61 deletions(-) diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index 74beab39da6..6bcedb5c761 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -3,10 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as fs from 'fs'; +import { statSync, unlink } from 'fs'; import { basename, normalize, join, posix } from 'vs/base/common/path'; import { localize } from 'vs/nls'; -import * as arrays from 'vs/base/common/arrays'; +import { coalesce, distinct, firstOrDefault } from 'vs/base/common/arrays'; import { IBackupMainService } from 'vs/platform/backup/electron-main/backup'; import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup'; import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService'; @@ -447,46 +447,55 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic } // Open based on config - const usedWindows = this.doOpen(openConfig, workspacesToOpen, foldersToOpen, emptyToRestore, emptyToOpen, filesToOpen, foldersToAdd); + const { windows: usedWindows, filesOpenedInWindow } = this.doOpen(openConfig, workspacesToOpen, foldersToOpen, emptyToRestore, emptyToOpen, filesToOpen, foldersToAdd); this.logService.trace(`windowsManager#open used window count ${usedWindows.length} (workspacesToOpen: ${workspacesToOpen.length}, foldersToOpen: ${foldersToOpen.length}, emptyToRestore: ${emptyToRestore.length}, emptyToOpen: ${emptyToOpen})`); // Make sure to pass focus to the most relevant of the windows if we open multiple if (usedWindows.length > 1) { - const focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && !openConfig.cli['file-uri'] && !openConfig.cli['folder-uri'] && !(openConfig.urisToOpen && openConfig.urisToOpen.length); - let focusLastOpened = true; - let focusLastWindow = true; - // 1.) focus last active window if we are not instructed to open any paths - if (focusLastActive) { - const lastActiveWindow = usedWindows.filter(window => this.windowsState.lastActiveWindow && window.backupPath === this.windowsState.lastActiveWindow.backupPath); - if (lastActiveWindow.length) { - lastActiveWindow[0].focus(); - focusLastOpened = false; - focusLastWindow = false; - } + // 1.) focus window we opened files in always with highest priority + if (filesOpenedInWindow) { + filesOpenedInWindow.focus(); } - // 2.) if instructed to open paths, focus last window which is not restored - if (focusLastOpened) { - for (let i = usedWindows.length - 1; i >= 0; i--) { - const usedWindow = usedWindows[i]; - if ( - (usedWindow.openedWorkspace && workspacesToRestore.some(workspace => usedWindow.openedWorkspace && workspace.workspace.id === usedWindow.openedWorkspace.id)) || // skip over restored workspace - (usedWindow.backupPath && emptyToRestore.some(empty => usedWindow.backupPath && empty.backupFolder === basename(usedWindow.backupPath))) // skip over restored empty window - ) { - continue; + // Otherwise, find a good window based on open params + else { + const focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && !openConfig.cli['file-uri'] && !openConfig.cli['folder-uri'] && !(openConfig.urisToOpen && openConfig.urisToOpen.length); + let focusLastOpened = true; + let focusLastWindow = true; + + // 2.) focus last active window if we are not instructed to open any paths + if (focusLastActive) { + const lastActiveWindow = usedWindows.filter(window => this.windowsState.lastActiveWindow && window.backupPath === this.windowsState.lastActiveWindow.backupPath); + if (lastActiveWindow.length) { + lastActiveWindow[0].focus(); + focusLastOpened = false; + focusLastWindow = false; } - - usedWindow.focus(); - focusLastWindow = false; - break; } - } - // 3.) finally, always ensure to have at least last used window focused - if (focusLastWindow) { - usedWindows[usedWindows.length - 1].focus(); + // 3.) if instructed to open paths, focus last window which is not restored + if (focusLastOpened) { + for (let i = usedWindows.length - 1; i >= 0; i--) { + const usedWindow = usedWindows[i]; + if ( + (usedWindow.openedWorkspace && workspacesToRestore.some(workspace => usedWindow.openedWorkspace && workspace.workspace.id === usedWindow.openedWorkspace.id)) || // skip over restored workspace + (usedWindow.backupPath && emptyToRestore.some(empty => usedWindow.backupPath && empty.backupFolder === basename(usedWindow.backupPath))) // skip over restored empty window + ) { + continue; + } + + usedWindow.focus(); + focusLastWindow = false; + break; + } + } + + // 4.) finally, always ensure to have at least last used window focused + if (focusLastWindow) { + usedWindows[usedWindows.length - 1].focus(); + } } } @@ -513,7 +522,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic // process can continue. We do this by deleting the waitMarkerFilePath. const waitMarkerFileURI = openConfig.waitMarkerFileURI; if (openConfig.context === OpenContext.CLI && waitMarkerFileURI && usedWindows.length === 1 && usedWindows[0]) { - usedWindows[0].whenClosedOrLoaded.then(() => fs.unlink(waitMarkerFileURI.fsPath, _error => undefined)); + usedWindows[0].whenClosedOrLoaded.then(() => unlink(waitMarkerFileURI.fsPath, () => undefined)); } return usedWindows; @@ -537,8 +546,9 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic emptyToOpen: number, filesToOpen: IFilesToOpen | undefined, foldersToAdd: IFolderPathToOpen[] - ) { + ): { windows: ICodeWindow[], filesOpenedInWindow: ICodeWindow | undefined } { const usedWindows: ICodeWindow[] = []; + let filesOpenedInWindow: ICodeWindow | undefined = undefined; // Settings can decide if files/folders open in new window or not let { openFolderInNewWindow, openFilesInNewWindow } = this.shouldOpenNewWindow(openConfig); @@ -587,16 +597,18 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic else { // Do open files - usedWindows.push(this.doOpenFilesInExistingWindow(openConfig, bestWindowOrFolder, filesToOpen)); + const window = this.doOpenFilesInExistingWindow(openConfig, bestWindowOrFolder, filesToOpen); + usedWindows.push(window); - // Reset these because we handled them + // Reset `filesToOpen` because we handled them and also remember window we used filesToOpen = undefined; + filesOpenedInWindow = window; } } // Finally, if no window or folder is found, just open the files in an empty window else { - usedWindows.push(this.openInBrowserWindow({ + const window = this.openInBrowserWindow({ userEnv: openConfig.userEnv, cli: openConfig.cli, initialStartup: openConfig.initialStartup, @@ -604,29 +616,33 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic forceNewWindow: true, remoteAuthority: filesToOpen.remoteAuthority, forceNewTabbedWindow: openConfig.forceNewTabbedWindow - })); + }); + usedWindows.push(window); - // Reset these because we handled them + // Reset `filesToOpen` because we handled them and also remember window we used filesToOpen = undefined; + filesOpenedInWindow = window; } } // Handle workspaces to open (instructed and to restore) - const allWorkspacesToOpen = arrays.distinct(workspacesToOpen, workspace => workspace.workspace.id); // prevent duplicates + const allWorkspacesToOpen = distinct(workspacesToOpen, workspace => workspace.workspace.id); // prevent duplicates if (allWorkspacesToOpen.length > 0) { // Check for existing instances - const windowsOnWorkspace = arrays.coalesce(allWorkspacesToOpen.map(workspaceToOpen => findWindowOnWorkspace(WindowsMainService.WINDOWS, workspaceToOpen.workspace))); + const windowsOnWorkspace = coalesce(allWorkspacesToOpen.map(workspaceToOpen => findWindowOnWorkspace(WindowsMainService.WINDOWS, workspaceToOpen.workspace))); if (windowsOnWorkspace.length > 0) { const windowOnWorkspace = windowsOnWorkspace[0]; const filesToOpenInWindow = (filesToOpen?.remoteAuthority === windowOnWorkspace.remoteAuthority) ? filesToOpen : undefined; // Do open files - usedWindows.push(this.doOpenFilesInExistingWindow(openConfig, windowOnWorkspace, filesToOpenInWindow)); + const window = this.doOpenFilesInExistingWindow(openConfig, windowOnWorkspace, filesToOpenInWindow); + usedWindows.push(window); - // Reset these because we handled them + // Reset `filesToOpen` because we handled them and also remember window we used if (filesToOpenInWindow) { filesToOpen = undefined; + filesOpenedInWindow = window; } openFolderInNewWindow = true; // any other folders to open must open in new window then @@ -642,11 +658,13 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic const filesToOpenInWindow = (filesToOpen?.remoteAuthority === remoteAuthority) ? filesToOpen : undefined; // Do open folder - usedWindows.push(this.doOpenFolderOrWorkspace(openConfig, workspaceToOpen, openFolderInNewWindow, filesToOpenInWindow)); + const window = this.doOpenFolderOrWorkspace(openConfig, workspaceToOpen, openFolderInNewWindow, filesToOpenInWindow); + usedWindows.push(window); - // Reset these because we handled them + // Reset `filesToOpen` because we handled them and also remember window we used if (filesToOpenInWindow) { filesToOpen = undefined; + filesOpenedInWindow = window; } openFolderInNewWindow = true; // any other folders to open must open in new window then @@ -654,21 +672,23 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic } // Handle folders to open (instructed and to restore) - const allFoldersToOpen = arrays.distinct(foldersToOpen, folder => extUriBiasedIgnorePathCase.getComparisonKey(folder.folderUri)); // prevent duplicates + const allFoldersToOpen = distinct(foldersToOpen, folder => extUriBiasedIgnorePathCase.getComparisonKey(folder.folderUri)); // prevent duplicates if (allFoldersToOpen.length > 0) { // Check for existing instances - const windowsOnFolderPath = arrays.coalesce(allFoldersToOpen.map(folderToOpen => findWindowOnWorkspace(WindowsMainService.WINDOWS, folderToOpen.folderUri))); + const windowsOnFolderPath = coalesce(allFoldersToOpen.map(folderToOpen => findWindowOnWorkspace(WindowsMainService.WINDOWS, folderToOpen.folderUri))); if (windowsOnFolderPath.length > 0) { const windowOnFolderPath = windowsOnFolderPath[0]; const filesToOpenInWindow = filesToOpen?.remoteAuthority === windowOnFolderPath.remoteAuthority ? filesToOpen : undefined; // Do open files - usedWindows.push(this.doOpenFilesInExistingWindow(openConfig, windowOnFolderPath, filesToOpenInWindow)); + const window = this.doOpenFilesInExistingWindow(openConfig, windowOnFolderPath, filesToOpenInWindow); + usedWindows.push(window); - // Reset these because we handled them + // Reset `filesToOpen` because we handled them and also remember window we used if (filesToOpenInWindow) { filesToOpen = undefined; + filesOpenedInWindow = window; } openFolderInNewWindow = true; // any other folders to open must open in new window then @@ -685,11 +705,13 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic const filesToOpenInWindow = (filesToOpen?.remoteAuthority === remoteAuthority) ? filesToOpen : undefined; // Do open folder - usedWindows.push(this.doOpenFolderOrWorkspace(openConfig, folderToOpen, openFolderInNewWindow, filesToOpenInWindow)); + const window = this.doOpenFolderOrWorkspace(openConfig, folderToOpen, openFolderInNewWindow, filesToOpenInWindow); + usedWindows.push(window); - // Reset these because we handled them + // Reset `filesToOpen` because we handled them and also remember window we used if (filesToOpenInWindow) { filesToOpen = undefined; + filesOpenedInWindow = window; } openFolderInNewWindow = true; // any other folders to open must open in new window then @@ -697,13 +719,13 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic } // Handle empty to restore - const allEmptyToRestore = arrays.distinct(emptyToRestore, info => info.backupFolder); // prevent duplicates + const allEmptyToRestore = distinct(emptyToRestore, info => info.backupFolder); // prevent duplicates if (allEmptyToRestore.length > 0) { allEmptyToRestore.forEach(emptyWindowBackupInfo => { const remoteAuthority = emptyWindowBackupInfo.remoteAuthority; const filesToOpenInWindow = (filesToOpen?.remoteAuthority === remoteAuthority) ? filesToOpen : undefined; - usedWindows.push(this.openInBrowserWindow({ + const window = this.openInBrowserWindow({ userEnv: openConfig.userEnv, cli: openConfig.cli, initialStartup: openConfig.initialStartup, @@ -712,11 +734,13 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic forceNewWindow: true, forceNewTabbedWindow: openConfig.forceNewTabbedWindow, emptyWindowBackupInfo - })); + }); + usedWindows.push(window); - // Reset these because we handled them + // Reset `filesToOpen` because we handled them and also remember window we used if (filesToOpenInWindow) { filesToOpen = undefined; + filesOpenedInWindow = window; } openFolderInNewWindow = true; // any other folders to open must open in new window then @@ -732,15 +756,21 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic const remoteAuthority = filesToOpen ? filesToOpen.remoteAuthority : (openConfig.cli && openConfig.cli.remote || undefined); for (let i = 0; i < emptyToOpen; i++) { - usedWindows.push(this.doOpenEmpty(openConfig, openFolderInNewWindow, remoteAuthority, filesToOpen)); + const window = this.doOpenEmpty(openConfig, openFolderInNewWindow, remoteAuthority, filesToOpen); + usedWindows.push(window); - // Reset these because we handled them - filesToOpen = undefined; - openFolderInNewWindow = true; // any other window to open must open in new window then + // Reset `filesToOpen` because we handled them and also remember window we used + if (filesToOpen) { + filesToOpen = undefined; + filesOpenedInWindow = window; + } + + // any other window to open must open in new window then + openFolderInNewWindow = true; } } - return arrays.distinct(usedWindows); + return { windows: distinct(usedWindows), filesOpenedInWindow }; } private doOpenFilesInExistingWindow(configuration: IOpenConfiguration, window: ICodeWindow, filesToOpen?: IFilesToOpen): ICodeWindow { @@ -1163,7 +1193,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic let candidate = normalize(anyPath); try { - const candidateStat = fs.statSync(candidate); + const candidateStat = statSync(candidate); if (candidateStat.isFile()) { // Workspace (unless disabled via flag) @@ -1697,7 +1727,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic getWindowById(windowId: number): ICodeWindow | undefined { const res = WindowsMainService.WINDOWS.filter(window => window.id === windowId); - return arrays.firstOrDefault(res); + return firstOrDefault(res); } getWindowByWebContents(webContents: WebContents): ICodeWindow | undefined { From 8041440e5b6f417afec05d8e0cd677282905d520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Wed, 2 Dec 2020 10:27:04 +0100 Subject: [PATCH 018/200] linux: disable integration tests --- .../linux/product-build-linux.yml | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 1e88a0a3b53..58bb954d35c 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -130,35 +130,35 @@ steps: displayName: Run unit tests (Browser) condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - script: | - # Figure out the full absolute path of the product we just built - # including the remote server and configure the integration tests - # to run with these builds instead of running out of sources. - set -e - APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") - INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ - DISPLAY=:10 ./scripts/test-integration.sh --build --tfs "Integration Tests" - displayName: Run integration tests (Electron) - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + # - script: | + # # Figure out the full absolute path of the product we just built + # # including the remote server and configure the integration tests + # # to run with these builds instead of running out of sources. + # set -e + # APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) + # APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") + # INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ + # VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ + # DISPLAY=:10 ./scripts/test-integration.sh --build --tfs "Integration Tests" + # displayName: Run integration tests (Electron) + # condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - script: | - set -e - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH)" \ - DISPLAY=:10 ./resources/server/test/test-web-integration.sh --browser chromium - displayName: Run integration tests (Browser) - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + # - script: | + # set -e + # VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH)" \ + # DISPLAY=:10 ./resources/server/test/test-web-integration.sh --browser chromium + # displayName: Run integration tests (Browser) + # condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - script: | - set -e - APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") - INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ - DISPLAY=:10 ./resources/server/test/test-remote-integration.sh - displayName: Run remote integration tests (Electron) - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + # - script: | + # set -e + # APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) + # APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") + # INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ + # VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ + # DISPLAY=:10 ./resources/server/test/test-remote-integration.sh + # displayName: Run remote integration tests (Electron) + # condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - task: PublishPipelineArtifact@0 inputs: From 00bbeb397373f91e38fdcd55c8f827f341c16ab8 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 2 Dec 2020 10:59:02 +0100 Subject: [PATCH 019/200] Fixes #111649: Have the diff editor control `wordWrapOverride1` and the toggle word wrap action `wordWrapOverride2` such that they can function independently --- .../editor/browser/widget/codeEditorWidget.ts | 4 +- .../editor/browser/widget/diffEditorWidget.ts | 30 +--- src/vs/editor/common/config/editorOptions.ts | 61 ++++---- .../common/standalone/standaloneEnums.ts | 27 ++-- .../standalone/browser/standaloneEditor.ts | 1 - .../viewLayout/editorLayoutProvider.test.ts | 3 +- src/vs/monaco.d.ts | 39 ++--- .../codeEditor/browser/toggleWordWrap.ts | 140 +++++------------- .../performance/browser/perfviewEditor.ts | 2 +- 9 files changed, 101 insertions(+), 206 deletions(-) diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 2e5c5f443ae..e39d4773399 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -21,7 +21,7 @@ import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService import { ICommandDelegate } from 'vs/editor/browser/view/viewController'; import { IContentWidgetData, IOverlayWidgetData, View } from 'vs/editor/browser/view/viewImpl'; import { ViewUserInputEvents } from 'vs/editor/browser/view/viewUserInputEvents'; -import { ConfigurationChangedEvent, EditorLayoutInfo, IEditorOptions, EditorOption, IComputedEditorOptions, FindComputedEditorOptionValueById, filterValidationDecorations, InDiffEditorState } from 'vs/editor/common/config/editorOptions'; +import { ConfigurationChangedEvent, EditorLayoutInfo, IEditorOptions, EditorOption, IComputedEditorOptions, FindComputedEditorOptionValueById, filterValidationDecorations } from 'vs/editor/common/config/editorOptions'; import { Cursor } from 'vs/editor/common/controller/cursor'; import { CursorColumns } from 'vs/editor/common/controller/cursorCommon'; import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; @@ -1774,7 +1774,7 @@ class EditorContextKeysManager extends Disposable { this._editorTabMovesFocus.set(options.get(EditorOption.tabFocusMode)); this._editorReadonly.set(options.get(EditorOption.readOnly)); - this._inDiffEditor.set(options.get(EditorOption.inDiffEditor) !== InDiffEditorState.None); + this._inDiffEditor.set(options.get(EditorOption.inDiffEditor)); this._editorColumnSelection.set(options.get(EditorOption.columnSelection)); } diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index c7ac517ae07..957af884c00 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -20,7 +20,7 @@ import * as editorBrowser from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { DiffReview } from 'vs/editor/browser/widget/diffReview'; -import { IDiffEditorOptions, IEditorOptions, EditorLayoutInfo, EditorOption, EditorOptions, EditorFontLigatures, stringSet as validateStringSetOption, boolean as validateBooleanOption, InDiffEditorState } from 'vs/editor/common/config/editorOptions'; +import { IDiffEditorOptions, IEditorOptions, EditorLayoutInfo, EditorOption, EditorOptions, EditorFontLigatures, stringSet as validateStringSetOption, boolean as validateBooleanOption } from 'vs/editor/common/config/editorOptions'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ISelection, Selection } from 'vs/editor/common/core/selection'; @@ -212,8 +212,6 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE private _maxComputationTime: number; private _renderIndicators: boolean; private _enableSplitViewResizing: boolean; - private _wordWrap: 'off' | 'on' | 'wordWrapColumn' | 'bounded' | undefined; - private _wordWrapMinified: boolean | undefined; private _strategy!: DiffEditorWidgetStyle; private readonly _updateDecorationsRunner: RunOnceScheduler; @@ -255,9 +253,6 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._domElement = domElement; options = options || {}; - this._wordWrap = options.wordWrap; - this._wordWrapMinified = options.wordWrapMinified; - // renderSideBySide this._renderSideBySide = true; if (typeof options.renderSideBySide !== 'undefined') { @@ -685,9 +680,6 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE public updateOptions(newOptions: IDiffEditorOptions): void { - this._wordWrap = typeof newOptions.wordWrap !== 'undefined' ? newOptions.wordWrap : this._wordWrap; - this._wordWrapMinified = typeof newOptions.wordWrapMinified !== 'undefined' ? newOptions.wordWrapMinified : this._wordWrapMinified; - // Handle side by side let renderSideBySideChanged = false; if (typeof newOptions.renderSideBySide !== 'undefined') { @@ -1108,6 +1100,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE private _adjustOptionsForSubEditor(options: editorBrowser.IDiffEditorConstructionOptions): editorBrowser.IDiffEditorConstructionOptions { const clonedOptions: editorBrowser.IDiffEditorConstructionOptions = objects.deepClone(options || {}); + clonedOptions.inDiffEditor = true; clonedOptions.automaticLayout = false; clonedOptions.scrollbar = clonedOptions.scrollbar || {}; clonedOptions.scrollbar.vertical = 'visible'; @@ -1125,17 +1118,11 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE private _adjustOptionsForLeftHandSide(options: editorBrowser.IDiffEditorConstructionOptions): editorBrowser.IEditorConstructionOptions { const result = this._adjustOptionsForSubEditor(options); - result.inDiffEditor = (this._renderSideBySide ? InDiffEditorState.SideBySideLeft : InDiffEditorState.InlineLeft); if (!this._renderSideBySide) { - // do not wrap hidden editor - result.wordWrap = 'off'; - result.wordWrapMinified = false; - } else if (this._diffWordWrap === 'inherit') { - result.wordWrap = this._wordWrap; - result.wordWrapMinified = this._wordWrapMinified; + // never wrap hidden editor + result.wordWrapOverride1 = 'off'; } else { - result.wordWrap = this._diffWordWrap; - result.wordWrapMinified = this._wordWrapMinified; + result.wordWrapOverride1 = this._diffWordWrap; } result.readOnly = !this._originalIsEditable; result.extraEditorClassName = 'original-in-monaco-diff-editor'; @@ -1144,12 +1131,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE private _adjustOptionsForRightHandSide(options: editorBrowser.IDiffEditorConstructionOptions): editorBrowser.IEditorConstructionOptions { const result = this._adjustOptionsForSubEditor(options); - result.inDiffEditor = (this._renderSideBySide ? InDiffEditorState.SideBySideRight : InDiffEditorState.InlineRight); - if (this._diffWordWrap === 'inherit') { - result.wordWrap = this._wordWrap; - } else { - result.wordWrap = this._diffWordWrap; - } + result.wordWrapOverride1 = this._diffWordWrap; result.revealHorizontalRightPadding = EditorOptions.revealHorizontalRightPadding.defaultValue + DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH; result.scrollbar!.verticalHasArrows = false; result.extraEditorClassName = 'modified-in-monaco-diff-editor'; diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 98cfa68d5dd..4a30547c6b1 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -41,14 +41,6 @@ export const enum EditorAutoIndentStrategy { Full = 4 } -export const enum InDiffEditorState { - None = 0, - SideBySideLeft = 1, - SideBySideRight = 2, - InlineLeft = 3, - InlineRight = 4 -} - /** * Configuration options for the editor. */ @@ -56,7 +48,7 @@ export interface IEditorOptions { /** * This editor is used inside a diff editor. */ - inDiffEditor?: InDiffEditorState; + inDiffEditor?: boolean; /** * The aria label for the editor's textarea (when it is focused). */ @@ -272,6 +264,16 @@ export interface IEditorOptions { * Defaults to "off". */ wordWrap?: 'off' | 'on' | 'wordWrapColumn' | 'bounded'; + /** + * Override the `wordWrap` setting. + * @internal + */ + wordWrapOverride1?: 'off' | 'on' | 'inherit'; + /** + * Override the `wordWrapOverride1` setting. + * @internal + */ + wordWrapOverride2?: 'off' | 'on' | 'inherit'; /** * Control the wrapping of the editor. * When `wordWrap` = "off", the lines will never wrap. @@ -281,11 +283,6 @@ export interface IEditorOptions { * Defaults to 80. */ wordWrapColumn?: number; - /** - * Force word wrapping when the text appears to be of a minified/generated file. - * Defaults to true. - */ - wordWrapMinified?: boolean; /** * Control indentation of wrapped lines. Can be: 'none', 'same', 'indent' or 'deepIndent'. * Defaults to 'same' in vscode and to 'none' in monaco-editor. @@ -1967,8 +1964,8 @@ export class EditorLayoutInfoComputer extends ComputedEditorOption { options._write(EditorOption.wordWrap, 'off'); options._write(EditorOption.wordWrapColumn, 80); - options._write(EditorOption.wordWrapMinified, true); + options._write(EditorOption.wordWrapOverride1, 'inherit'); + options._write(EditorOption.wordWrapOverride2, 'inherit'); options._write(EditorOption.accessibilitySupport, 'auto'); const actual = EditorLayoutInfoComputer.computeLayout(options, { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 1c2d827105a..85e7066269a 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2588,14 +2588,6 @@ declare namespace monaco.editor { Full = 4 } - export enum InDiffEditorState { - None = 0, - SideBySideLeft = 1, - SideBySideRight = 2, - InlineLeft = 3, - InlineRight = 4 - } - /** * Configuration options for the editor. */ @@ -2603,7 +2595,7 @@ declare namespace monaco.editor { /** * This editor is used inside a diff editor. */ - inDiffEditor?: InDiffEditorState; + inDiffEditor?: boolean; /** * The aria label for the editor's textarea (when it is focused). */ @@ -2828,11 +2820,6 @@ declare namespace monaco.editor { * Defaults to 80. */ wordWrapColumn?: number; - /** - * Force word wrapping when the text appears to be of a minified/generated file. - * Defaults to true. - */ - wordWrapMinified?: boolean; /** * Control indentation of wrapped lines. Can be: 'none', 'same', 'indent' or 'deepIndent'. * Defaults to 'same' in vscode and to 'none' in monaco-editor. @@ -4019,15 +4006,16 @@ declare namespace monaco.editor { wordWrapBreakAfterCharacters = 112, wordWrapBreakBeforeCharacters = 113, wordWrapColumn = 114, - wordWrapMinified = 115, - wrappingIndent = 116, - wrappingStrategy = 117, - showDeprecated = 118, - editorClassName = 119, - pixelRatio = 120, - tabFocusMode = 121, - layoutInfo = 122, - wrappingInfo = 123 + wordWrapOverride1 = 115, + wordWrapOverride2 = 116, + wrappingIndent = 117, + wrappingStrategy = 118, + showDeprecated = 119, + editorClassName = 120, + pixelRatio = 121, + tabFocusMode = 122, + layoutInfo = 123, + wrappingInfo = 124 } export const EditorOptions: { acceptSuggestionOnCommitCharacter: IEditorOption; @@ -4080,7 +4068,7 @@ declare namespace monaco.editor { hideCursorInOverviewRuler: IEditorOption; highlightActiveIndentGuide: IEditorOption; hover: IEditorOption; - inDiffEditor: IEditorOption; + inDiffEditor: IEditorOption; letterSpacing: IEditorOption; lightbulb: IEditorOption; lineDecorationsWidth: IEditorOption; @@ -4146,7 +4134,8 @@ declare namespace monaco.editor { wordWrapBreakAfterCharacters: IEditorOption; wordWrapBreakBeforeCharacters: IEditorOption; wordWrapColumn: IEditorOption; - wordWrapMinified: IEditorOption; + wordWrapOverride1: IEditorOption; + wordWrapOverride2: IEditorOption; wrappingIndent: IEditorOption; wrappingStrategy: IEditorOption; editorClassName: IEditorOption; diff --git a/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts b/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts index 29ce65162d2..a0df024be67 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts @@ -10,10 +10,9 @@ import { URI } from 'vs/base/common/uri'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, ServicesAccessor, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { EditorOption, EditorOptions } from 'vs/editor/common/config/editorOptions'; +import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; -import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService'; import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; @@ -29,14 +28,7 @@ const isDominatedByLongLinesKey = 'isDominatedByLongLines'; * State written/read by the toggle word wrap action and associated with a particular model. */ interface IWordWrapTransientState { - readonly forceWordWrap: 'on' | 'off' | 'wordWrapColumn' | 'bounded'; - readonly forceWordWrapMinified: boolean; -} - -interface IWordWrapState { - readonly configuredWordWrap: 'on' | 'off' | 'wordWrapColumn' | 'bounded' | undefined; - readonly configuredWordWrapMinified: boolean; - readonly transientState: IWordWrapTransientState | null; + readonly wordWrapOverride: 'on' | 'off'; } /** @@ -49,70 +41,10 @@ export function writeTransientState(model: ITextModel, state: IWordWrapTransient /** * Read (in memory) the word wrap state for a particular model. */ -function readTransientState(model: ITextModel, codeEditorService: ICodeEditorService): IWordWrapTransientState { +function readTransientState(model: ITextModel, codeEditorService: ICodeEditorService): IWordWrapTransientState | null { return codeEditorService.getTransientModelProperty(model, transientWordWrapState); } -function readWordWrapState(model: ITextModel, configurationService: ITextResourceConfigurationService, codeEditorService: ICodeEditorService): IWordWrapState { - const editorConfig = configurationService.getValue(model.uri, 'editor') as { wordWrap: 'on' | 'off' | 'wordWrapColumn' | 'bounded'; wordWrapMinified: boolean }; - let _configuredWordWrap = editorConfig && (typeof editorConfig.wordWrap === 'string' || typeof editorConfig.wordWrap === 'boolean') ? editorConfig.wordWrap : undefined; - - // Compatibility with old true or false values - if (_configuredWordWrap === true) { - _configuredWordWrap = 'on'; - } else if (_configuredWordWrap === false) { - _configuredWordWrap = 'off'; - } - - const _configuredWordWrapMinified = editorConfig && typeof editorConfig.wordWrapMinified === 'boolean' ? editorConfig.wordWrapMinified : undefined; - const _transientState = readTransientState(model, codeEditorService); - return { - configuredWordWrap: _configuredWordWrap, - configuredWordWrapMinified: (typeof _configuredWordWrapMinified === 'boolean' ? _configuredWordWrapMinified : EditorOptions.wordWrapMinified.defaultValue), - transientState: _transientState - }; -} - -function toggleWordWrap(editor: ICodeEditor, state: IWordWrapState): IWordWrapState { - if (state.transientState) { - // toggle off => go to null - return { - configuredWordWrap: state.configuredWordWrap, - configuredWordWrapMinified: state.configuredWordWrapMinified, - transientState: null - }; - } - - let transientState: IWordWrapTransientState; - - const actualWrappingInfo = editor.getOption(EditorOption.wrappingInfo); - if (actualWrappingInfo.isWordWrapMinified) { - // => wrapping due to minified file - transientState = { - forceWordWrap: 'off', - forceWordWrapMinified: false - }; - } else if (state.configuredWordWrap !== 'off') { - // => wrapping is configured to be on (or some variant) - transientState = { - forceWordWrap: 'off', - forceWordWrapMinified: false - }; - } else { - // => wrapping is configured to be off - transientState = { - forceWordWrap: 'on', - forceWordWrapMinified: state.configuredWordWrapMinified - }; - } - - return { - configuredWordWrap: state.configuredWordWrap, - configuredWordWrapMinified: state.configuredWordWrapMinified, - transientState: transientState - }; -} - const TOGGLE_WORD_WRAP_ID = 'editor.action.toggleWordWrap'; class ToggleWordWrapAction extends EditorAction { @@ -139,7 +71,6 @@ class ToggleWordWrapAction extends EditorAction { return; } - const textResourceConfigurationService = accessor.get(ITextResourceConfigurationService); const codeEditorService = accessor.get(ICodeEditorService); const model = editor.getModel(); @@ -148,12 +79,21 @@ class ToggleWordWrapAction extends EditorAction { } // Read the current state - const currentState = readWordWrapState(model, textResourceConfigurationService, codeEditorService); + const transientState = readTransientState(model, codeEditorService); + // Compute the new state - const newState = toggleWordWrap(editor, currentState); + let newState: IWordWrapTransientState | null; + if (transientState) { + newState = null; + } else { + const actualWrappingInfo = editor.getOption(EditorOption.wrappingInfo); + const wordWrapOverride = (actualWrappingInfo.wrappingColumn === -1 ? 'on' : 'off'); + newState = { wordWrapOverride }; + } + // Write the new state // (this will cause an event and the controller will apply the state) - writeTransientState(model, newState.transientState, codeEditorService); + writeTransientState(model, newState, codeEditorService); } } @@ -162,24 +102,23 @@ class ToggleWordWrapController extends Disposable implements IEditorContribution public static readonly ID = 'editor.contrib.toggleWordWrapController'; constructor( - private readonly editor: ICodeEditor, - @IContextKeyService readonly contextKeyService: IContextKeyService, - @ITextResourceConfigurationService readonly configurationService: ITextResourceConfigurationService, - @ICodeEditorService readonly codeEditorService: ICodeEditorService + private readonly _editor: ICodeEditor, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @ICodeEditorService private readonly _codeEditorService: ICodeEditorService ) { super(); - const options = this.editor.getOptions(); + const options = this._editor.getOptions(); const wrappingInfo = options.get(EditorOption.wrappingInfo); - const isWordWrapMinified = this.contextKeyService.createKey(isWordWrapMinifiedKey, wrappingInfo.isWordWrapMinified); - const isDominatedByLongLines = this.contextKeyService.createKey(isDominatedByLongLinesKey, wrappingInfo.isDominatedByLongLines); + const isWordWrapMinified = this._contextKeyService.createKey(isWordWrapMinifiedKey, wrappingInfo.isWordWrapMinified); + const isDominatedByLongLines = this._contextKeyService.createKey(isDominatedByLongLinesKey, wrappingInfo.isDominatedByLongLines); let currentlyApplyingEditorConfig = false; - this._register(editor.onDidChangeConfiguration((e) => { + this._register(_editor.onDidChangeConfiguration((e) => { if (!e.hasChanged(EditorOption.wrappingInfo)) { return; } - const options = this.editor.getOptions(); + const options = this._editor.getOptions(); const wrappingInfo = options.get(EditorOption.wrappingInfo); isWordWrapMinified.set(wrappingInfo.isWordWrapMinified); isDominatedByLongLines.set(wrappingInfo.isDominatedByLongLines); @@ -189,25 +128,25 @@ class ToggleWordWrapController extends Disposable implements IEditorContribution } })); - this._register(editor.onDidChangeModel((e) => { + this._register(_editor.onDidChangeModel((e) => { ensureWordWrapSettings(); })); - this._register(codeEditorService.onDidChangeTransientModelProperty(() => { + this._register(_codeEditorService.onDidChangeTransientModelProperty(() => { ensureWordWrapSettings(); })); const ensureWordWrapSettings = () => { - if (this.editor.getContribution(DefaultSettingsEditorContribution.ID)) { + if (this._editor.getContribution(DefaultSettingsEditorContribution.ID)) { // in the settings editor... return; } - if (this.editor.isSimpleWidget) { + if (this._editor.isSimpleWidget) { // in a simple widget... return; } // Ensure correct word wrap settings - const newModel = this.editor.getModel(); + const newModel = this._editor.getModel(); if (!newModel) { return; } @@ -216,33 +155,22 @@ class ToggleWordWrapController extends Disposable implements IEditorContribution return; } - // Read current configured values and toggle state - const desiredState = readWordWrapState(newModel, this.configurationService, this.codeEditorService); + const transientState = readTransientState(newModel, this._codeEditorService); // Apply the state try { currentlyApplyingEditorConfig = true; - this._applyWordWrapState(desiredState); + this._applyWordWrapState(transientState); } finally { currentlyApplyingEditorConfig = false; } }; } - private _applyWordWrapState(state: IWordWrapState): void { - if (state.transientState) { - // toggle is on - this.editor.updateOptions({ - wordWrap: state.transientState.forceWordWrap, - wordWrapMinified: state.transientState.forceWordWrapMinified - }); - return; - } - - // toggle is off - this.editor.updateOptions({ - wordWrap: state.configuredWordWrap, - wordWrapMinified: state.configuredWordWrapMinified + private _applyWordWrapState(state: IWordWrapTransientState | null): void { + const wordWrapOverride2 = state ? state.wordWrapOverride : 'inherit'; + this._editor.updateOptions({ + wordWrapOverride2: wordWrapOverride2 }); } } diff --git a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts index 6569ec09cff..60f7caa47e1 100644 --- a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts +++ b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts @@ -108,7 +108,7 @@ class PerfModelContentProvider implements ITextModelContentProvider { this._modelDisposables.push(langId); this._modelDisposables.push(this._extensionService.onDidChangeExtensionsStatus(this._updateModel, this)); - writeTransientState(this._model, { forceWordWrap: 'off', forceWordWrapMinified: false }, this._editorService); + writeTransientState(this._model, { wordWrapOverride: 'off' }, this._editorService); } this._updateModel(); return Promise.resolve(this._model); From 1cad5ab365f1456e9da77744711aaf271c243688 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 2 Dec 2020 11:14:45 +0100 Subject: [PATCH 020/200] Prepend `vs/nls` to `workerMain.js` (fixes #111599) --- src/buildfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/buildfile.js b/src/buildfile.js index f6d1c647d9d..c0400de76c0 100644 --- a/src/buildfile.js +++ b/src/buildfile.js @@ -10,7 +10,7 @@ function entrypoint(name) { exports.base = [{ name: 'vs/base/common/worker/simpleWorker', include: ['vs/editor/common/services/editorSimpleWorker'], - prepend: ['vs/loader.js'], + prepend: ['vs/loader.js', 'vs/nls.js'], append: ['vs/base/worker/workerMain'], dest: 'vs/base/worker/workerMain.js' }]; From 6d4532c4849c36bb8d3fab87f17555f768b67b0c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 2 Dec 2020 11:31:36 +0100 Subject: [PATCH 021/200] align continue bisect messages, https://github.com/microsoft/vscode/issues/111667 --- .../services/extensionManagement/browser/extensionBisect.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts b/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts index 4a1b9272761..67087d3591b 100644 --- a/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts +++ b/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts @@ -249,7 +249,7 @@ registerAction2(class extends Action2 { return; } if (seeingBad === undefined) { - seeingBad = await this._checkForBad(dialogService); + seeingBad = await this._checkForBad(dialogService, bisectService); } if (seeingBad === undefined) { await bisectService.reset(); @@ -290,10 +290,10 @@ registerAction2(class extends Action2 { hostService.reload(); } - private async _checkForBad(dialogService: IDialogService) { + private async _checkForBad(dialogService: IDialogService, bisectService: IExtensionBisectService) { const options = { cancelId: 2, - detail: localize('detail.next', "Are you still seeing the problem for which you have started extension bisect?") + detail: localize('bisect', "Extension Bisect is active and has disabled {0} extensions. Check if you can still reproduce the problem and proceed by selecting from these options.", bisectService.disabledCount), }; const res = await dialogService.show( Severity.Info, From a1e5a1a593154dbe30973f941caed2b8ab89fd6c Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 2 Dec 2020 11:47:16 +0100 Subject: [PATCH 022/200] Small typo in notebook mime type icon description. Fixes #111674 --- src/vs/workbench/contrib/notebook/browser/notebookIcons.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/notebook/browser/notebookIcons.ts b/src/vs/workbench/contrib/notebook/browser/notebookIcons.ts index c0d6564bdad..6780f1fa93f 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookIcons.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookIcons.ts @@ -29,4 +29,4 @@ export const collapsedIcon = registerIcon('notebook-collapsed', Codicon.chevronR export const expandedIcon = registerIcon('notebook-expanded', Codicon.chevronDown, localize('expandedIcon', 'Icon to annotated a expanded section in notebook editors.')); export const openAsTextIcon = registerIcon('notebook-open-as-text', Codicon.fileCode, localize('openAsTextIcon', 'Icon to open the notebook in a text editor.')); export const revertIcon = registerIcon('notebook-revert', Codicon.discard, localize('revertIcon', 'Icon to revert in notebook editors.')); -export const mimetypeIcon = registerIcon('notebook-mimetype', Codicon.code, localize('mimetypeIcon', 'Icon for a mime type notebook editors.')); +export const mimetypeIcon = registerIcon('notebook-mimetype', Codicon.code, localize('mimetypeIcon', 'Icon for a mime type in notebook editors.')); From 2388291cbc74d38dd311d7b97ed942074023dc70 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 2 Dec 2020 11:47:31 +0100 Subject: [PATCH 023/200] start extension bisect with all extensions disabled and stop early if problem reproduces, https://github.com/microsoft/vscode/issues/111672 --- .../browser/extensionBisect.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts b/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts index 67087d3591b..5e3038ace18 100644 --- a/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts +++ b/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts @@ -47,21 +47,18 @@ class BisectState { try { interface Raw extends BisectState { } const data: Raw = JSON.parse(raw); - return new BisectState(data.extensions, data.low, data.high); + return new BisectState(data.extensions, data.low, data.high, data.mid); } catch { return undefined; } } - readonly mid: number; - constructor( readonly extensions: string[], readonly low: number, readonly high: number, - ) { - this.mid = ((low + high) / 2) | 0; - } + readonly mid: number = ((low + high) / 2) | 0 + ) { } } class ExtensionBisectService implements IExtensionBisectService { @@ -111,7 +108,7 @@ class ExtensionBisectService implements IExtensionBisectService { throw new Error('invalid state'); } const extensionIds = extensions.map(ext => ext.identifier.id); - const newState = new BisectState(extensionIds, 0, extensionIds.length); + const newState = new BisectState(extensionIds, 0, extensionIds.length, 0); this._storageService.store(ExtensionBisectService._storageKey, JSON.stringify(newState), StorageScope.GLOBAL, StorageTarget.MACHINE); await this._storageService.flush(); } @@ -120,6 +117,10 @@ class ExtensionBisectService implements IExtensionBisectService { if (!this._state) { throw new Error('invalid state'); } + // check if bad when all extensions are disabled + if (seeingBad && this._state.mid === 0 && this._state.high === this._state.extensions.length) { + return { bad: true, id: '' }; + } // check if there is only one left if (this._state.low === this._state.high - 1) { await this.reset(); @@ -215,7 +216,7 @@ registerAction2(class extends Action2 { const res = await dialogService.confirm({ message: localize('msg.start', "Extension Bisect"), - detail: localize('detail.start', "Extension Bisect will use binary search to find an extension that causes a problem. During the process the window reloads repeatedly (~{0} times). Each time you must confirm if you are still seeing problems.", 1 + Math.log2(extensions.length) | 0), + detail: localize('detail.start', "Extension Bisect will use binary search to find an extension that causes a problem. During the process the window reloads repeatedly (~{0} times). Each time you must confirm if you are still seeing problems.", 2 + Math.log2(extensions.length) | 0), primaryButton: localize('msg2', "Start Extension Bisect") }); @@ -265,7 +266,7 @@ registerAction2(class extends Action2 { if (done.bad) { // DONE but nothing found await dialogService.show(Severity.Info, localize('done.msg', "Extension Bisect"), [], { - detail: localize('done.detail2', "Extension Bisect is done but no extension has been identified. This might be a problem with {0}", productService.nameShort) + detail: localize('done.detail2', "Extension Bisect is done but no extension has been identified. This might be a problem with {0}.", productService.nameShort) }); } else { From 914b5633f52eb8aecf884427ae888605814852b8 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 2 Dec 2020 12:00:55 +0100 Subject: [PATCH 024/200] fixes #111593 --- .../contrib/debug/browser/debugEditorContribution.ts | 4 ++++ src/vs/workbench/contrib/debug/browser/exceptionWidget.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts index d88475e263c..dbd53aa5bba 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts @@ -452,9 +452,13 @@ export class DebugEditorContribution implements IDebugEditorContribution { closeExceptionWidget(): void { if (this.exceptionWidget) { + const shouldFocusEditor = this.exceptionWidget.hasfocus(); this.exceptionWidget.dispose(); this.exceptionWidget = undefined; this.exceptionWidgetVisible.set(false); + if (shouldFocusEditor) { + this.editor.focus(); + } } } diff --git a/src/vs/workbench/contrib/debug/browser/exceptionWidget.ts b/src/vs/workbench/contrib/debug/browser/exceptionWidget.ts index cd8159ad070..67a12c4892c 100644 --- a/src/vs/workbench/contrib/debug/browser/exceptionWidget.ts +++ b/src/vs/workbench/contrib/debug/browser/exceptionWidget.ts @@ -120,4 +120,8 @@ export class ExceptionWidget extends ZoneWidget { // Focus into the container for accessibility purposes so the exception and stack trace gets read this.container?.focus(); } + + hasfocus(): boolean { + return dom.isAncestor(document.activeElement, this.container); + } } From e024fd8b967d532588aa1da1c5a9c5129b0d658c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 2 Dec 2020 12:01:31 +0100 Subject: [PATCH 025/200] add cancel-option to continue bisect model dialog, https://github.com/microsoft/vscode/issues/111667 --- .../browser/extensionBisect.ts | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts b/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts index 5e3038ace18..9498ec70955 100644 --- a/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts +++ b/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts @@ -250,7 +250,11 @@ registerAction2(class extends Action2 { return; } if (seeingBad === undefined) { - seeingBad = await this._checkForBad(dialogService, bisectService); + const goodBadStopCancel = await this._checkForBad(dialogService, bisectService); + if (goodBadStopCancel === null) { + return; + } + seeingBad = goodBadStopCancel; } if (seeingBad === undefined) { await bisectService.reset(); @@ -291,21 +295,23 @@ registerAction2(class extends Action2 { hostService.reload(); } - private async _checkForBad(dialogService: IDialogService, bisectService: IExtensionBisectService) { + private async _checkForBad(dialogService: IDialogService, bisectService: IExtensionBisectService): Promise { const options = { - cancelId: 2, + cancelId: 3, detail: localize('bisect', "Extension Bisect is active and has disabled {0} extensions. Check if you can still reproduce the problem and proceed by selecting from these options.", bisectService.disabledCount), }; const res = await dialogService.show( Severity.Info, localize('msg.next', "Extension Bisect"), - [localize('next.good', "Good now"), localize('next.bad', "This is bad"), localize('next.stop', "Stop Bisect")], + [localize('next.good', "Good now"), localize('next.bad', "This is bad"), localize('next.stop', "Stop Bisect"), localize('next.cancel', "Cancel")], options ); - if (res.choice === options.cancelId) { - return undefined; + switch (res.choice) { + case 0: return false; //good now + case 1: return true; //bad + case 2: return undefined; //stop } - return res.choice === 1; + return null; //cancel } }); From 37302386478ae702a0d9ab71b0190c189e079383 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 2 Dec 2020 12:04:51 +0100 Subject: [PATCH 026/200] fixes #111601 --- src/vs/workbench/contrib/debug/browser/breakpointsView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index c57458f49a5..0ba7b791070 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -209,7 +209,7 @@ export class BreakpointsView extends ViewPane { actions.push(new Separator()); } if (element instanceof ExceptionBreakpoint && element.supportsCondition) { - actions.push(new Action('workbench.action.debug.editExceptionBreakpointCondition', nls.localize('editCondition', "Edit Condition..."), '', true, async () => { + actions.push(new Action('workbench.action.debug.editExceptionBreakpointCondition', nls.localize('editCondition', "Edit Condition"), '', true, async () => { this.debugService.getViewModel().setSelectedBreakpoint(element); this.onBreakpointsChange(); })); From 399be0e5645e885d50cae9d4a3477c433fb0ed06 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 2 Dec 2020 12:30:42 +0100 Subject: [PATCH 027/200] fixes #111671 --- .../contrib/debug/browser/breakpointsView.ts | 71 ++++++++++--------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 0ba7b791070..8e0a7c2c27b 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -190,44 +190,47 @@ export class BreakpointsView extends ViewPane { const actions: IAction[] = []; const element = e.element; - const breakpointType = element instanceof Breakpoint && element.logMessage ? nls.localize('Logpoint', "Logpoint") : nls.localize('Breakpoint', "Breakpoint"); - if (element instanceof Breakpoint || element instanceof FunctionBreakpoint) { - actions.push(new Action('workbench.action.debug.openEditorAndEditBreakpoint', nls.localize('editBreakpoint', "Edit {0}...", breakpointType), '', true, async () => { - if (element instanceof Breakpoint) { - const editor = await openBreakpointSource(element, false, false, true, this.debugService, this.editorService); - if (editor) { - const codeEditor = editor.getControl(); - if (isCodeEditor(codeEditor)) { - codeEditor.getContribution(BREAKPOINT_EDITOR_CONTRIBUTION_ID).showBreakpointWidget(element.lineNumber, element.column); - } - } - } else { + if (element instanceof ExceptionBreakpoint) { + if (element.supportsCondition) { + actions.push(new Action('workbench.action.debug.editExceptionBreakpointCondition', nls.localize('editCondition', "Edit Condition"), '', true, async () => { this.debugService.getViewModel().setSelectedBreakpoint(element); this.onBreakpointsChange(); - } - })); + })); + } + } else { + const breakpointType = element instanceof Breakpoint && element.logMessage ? nls.localize('Logpoint', "Logpoint") : nls.localize('Breakpoint', "Breakpoint"); + if (element instanceof Breakpoint || element instanceof FunctionBreakpoint) { + actions.push(new Action('workbench.action.debug.openEditorAndEditBreakpoint', nls.localize('editBreakpoint', "Edit {0}...", breakpointType), '', true, async () => { + if (element instanceof Breakpoint) { + const editor = await openBreakpointSource(element, false, false, true, this.debugService, this.editorService); + if (editor) { + const codeEditor = editor.getControl(); + if (isCodeEditor(codeEditor)) { + codeEditor.getContribution(BREAKPOINT_EDITOR_CONTRIBUTION_ID).showBreakpointWidget(element.lineNumber, element.column); + } + } + } else { + this.debugService.getViewModel().setSelectedBreakpoint(element); + this.onBreakpointsChange(); + } + })); + actions.push(new Separator()); + } + + + actions.push(new RemoveBreakpointAction(RemoveBreakpointAction.ID, nls.localize('removeBreakpoint', "Remove {0}", breakpointType), this.debugService)); + + if (this.debugService.getModel().getBreakpoints().length + this.debugService.getModel().getFunctionBreakpoints().length >= 1) { + actions.push(new RemoveAllBreakpointsAction(RemoveAllBreakpointsAction.ID, RemoveAllBreakpointsAction.LABEL, this.debugService, this.keybindingService)); + actions.push(new Separator()); + + actions.push(new EnableAllBreakpointsAction(EnableAllBreakpointsAction.ID, EnableAllBreakpointsAction.LABEL, this.debugService, this.keybindingService)); + actions.push(new DisableAllBreakpointsAction(DisableAllBreakpointsAction.ID, DisableAllBreakpointsAction.LABEL, this.debugService, this.keybindingService)); + } + actions.push(new Separator()); + actions.push(new ReapplyBreakpointsAction(ReapplyBreakpointsAction.ID, ReapplyBreakpointsAction.LABEL, this.debugService, this.keybindingService)); } - if (element instanceof ExceptionBreakpoint && element.supportsCondition) { - actions.push(new Action('workbench.action.debug.editExceptionBreakpointCondition', nls.localize('editCondition', "Edit Condition"), '', true, async () => { - this.debugService.getViewModel().setSelectedBreakpoint(element); - this.onBreakpointsChange(); - })); - actions.push(new Separator()); - } - - actions.push(new RemoveBreakpointAction(RemoveBreakpointAction.ID, nls.localize('removeBreakpoint', "Remove {0}", breakpointType), this.debugService)); - - if (this.debugService.getModel().getBreakpoints().length + this.debugService.getModel().getFunctionBreakpoints().length > 1) { - actions.push(new RemoveAllBreakpointsAction(RemoveAllBreakpointsAction.ID, RemoveAllBreakpointsAction.LABEL, this.debugService, this.keybindingService)); - actions.push(new Separator()); - - actions.push(new EnableAllBreakpointsAction(EnableAllBreakpointsAction.ID, EnableAllBreakpointsAction.LABEL, this.debugService, this.keybindingService)); - actions.push(new DisableAllBreakpointsAction(DisableAllBreakpointsAction.ID, DisableAllBreakpointsAction.LABEL, this.debugService, this.keybindingService)); - } - - actions.push(new Separator()); - actions.push(new ReapplyBreakpointsAction(ReapplyBreakpointsAction.ID, ReapplyBreakpointsAction.LABEL, this.debugService, this.keybindingService)); this.contextMenuService.showContextMenu({ getAnchor: () => e.anchor, From 0587f828d6e5b83dea2e61ff52a1192338fe8100 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 2 Dec 2020 12:54:02 +0100 Subject: [PATCH 028/200] fixes #111617 --- .../files/browser/views/explorerViewer.ts | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 71b44a81d1d..7197ee94609 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -20,7 +20,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IFilesConfiguration, VIEW_ID } from 'vs/workbench/contrib/files/common/files'; -import { dirname, joinPath, basename, distinctParents, basenameOrAuthority } from 'vs/base/common/resources'; +import { dirname, joinPath, basename, distinctParents } from 'vs/base/common/resources'; import { InputBox, MessageType } from 'vs/base/browser/ui/inputbox/inputBox'; import { localize } from 'vs/nls'; import { attachInputBoxStyler } from 'vs/platform/theme/common/styler'; @@ -1345,8 +1345,8 @@ export class FileDragAndDrop implements ITreeDragAndDrop { }); await this.explorerService.applyBulkEdit(resourceFileEdits, { - undoLabel: resourcesFiltered.length === 1 ? localize('copyFile', "Copy {0}", basename(resourcesFiltered[0])) : localize('copynFile', "Copy {0} files", resourcesFiltered.length), - progressLabel: resourcesFiltered.length === 1 ? localize('copyingFile', "Copying {0}", basename(resourcesFiltered[0])) : localize('copyingnFile', "Copying {0} files", resourcesFiltered.length) + undoLabel: resourcesFiltered.length === 1 ? localize('copyFile', "Copy {0}", basename(resourcesFiltered[0])) : localize('copynFile', "Copy {0} resources", resourcesFiltered.length), + progressLabel: resourcesFiltered.length === 1 ? localize('copyingFile', "Copying {0}", basename(resourcesFiltered[0])) : localize('copyingnFile', "Copying {0} resources", resourcesFiltered.length) }); // if we only add one file, just open it directly @@ -1440,9 +1440,10 @@ export class FileDragAndDrop implements ITreeDragAndDrop { // Reuse duplicate action when user copies const incrementalNaming = this.configurationService.getValue().explorer.incrementalNaming; const resourceFileEdits = sources.map(({ resource, isDirectory }) => (new ResourceFileEdit(resource, findValidPasteFileTarget(this.explorerService, target, { resource, isDirectory, allowOverwrite: false }, incrementalNaming), { copy: true }))); + const labelSufix = getFileOrFolderLabelSufix(sources); await this.explorerService.applyBulkEdit(resourceFileEdits, { - undoLabel: resourceFileEdits.length > 1 ? localize('copy', "Copy {0} files", resourceFileEdits.length) : localize('copyOneFile', "Copy {0}", basenameOrAuthority(resourceFileEdits[0].newResource!)), - progressLabel: resourceFileEdits.length > 1 ? localize('copying', "Copying {0} files", resourceFileEdits.length) : localize('copyingOneFile', "Copying {0}", basenameOrAuthority(resourceFileEdits[0].newResource!)), + undoLabel: localize('copy', "Copy {0}", labelSufix), + progressLabel: localize('copying', "Copying {0}", labelSufix), }); const editors = resourceFileEdits.filter(edit => { @@ -1457,9 +1458,10 @@ export class FileDragAndDrop implements ITreeDragAndDrop { // Do not allow moving readonly items const resourceFileEdits = sources.filter(source => !source.isReadonly).map(source => new ResourceFileEdit(source.resource, joinPath(target.resource, source.name))); + const labelSufix = getFileOrFolderLabelSufix(sources); const options = { - undoLabel: sources.length > 1 ? localize('move', "Move {0} files", sources.length) : localize('moveOneFile', "Move {0}", sources[0].name), - progressLabel: sources.length > 1 ? localize('moving', "Moving {0} files", sources.length) : localize('movingOneFile', "Moving {0}", sources[0].name), + undoLabel: localize('move', "Move {0}", labelSufix), + progressLabel: localize('moving', "Moving {0}", labelSufix) }; try { @@ -1564,3 +1566,18 @@ export class ExplorerCompressionDelegate implements ITreeCompressionDelegate i.isDirectory)) { + return `${items.length} folders`; + } + if (items.every(i => !i.isDirectory)) { + return `${items.length} files`; + } + + return `${items.length} files and folders`; +} From 806eaddcbe7bf67311ad9c79f1515335778eb8ae Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 2 Dec 2020 13:24:53 +0100 Subject: [PATCH 029/200] Fix resolveTreeItem getting called too early Fixes #111613 --- src/vs/base/browser/ui/iconLabel/iconLabel.ts | 16 ++++++++++++---- src/vs/workbench/browser/parts/views/treeView.ts | 10 ++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/vs/base/browser/ui/iconLabel/iconLabel.ts b/src/vs/base/browser/ui/iconLabel/iconLabel.ts index b996d599700..9f87da0c342 100644 --- a/src/vs/base/browser/ui/iconLabel/iconLabel.ts +++ b/src/vs/base/browser/ui/iconLabel/iconLabel.ts @@ -14,7 +14,7 @@ import { isMacintosh } from 'vs/base/common/platform'; import { IHoverDelegate, IHoverDelegateOptions, IHoverDelegateTarget } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate'; import { AnchorPosition } from 'vs/base/browser/ui/contextview/contextview'; import { IMarkdownString } from 'vs/base/common/htmlContent'; -import { isString } from 'vs/base/common/types'; +import { isFunction, isString } from 'vs/base/common/types'; import { domEvent } from 'vs/base/browser/event'; export interface IIconLabelCreationOptions { @@ -25,7 +25,7 @@ export interface IIconLabelCreationOptions { } export interface IIconLabelMarkdownString { - markdown: IMarkdownString | string | undefined | Promise; + markdown: IMarkdownString | string | undefined | (() => Promise); markdownNotSupportedFallback: string | undefined; } @@ -192,7 +192,15 @@ export class IconLabel extends Disposable { private setupCustomHover(hoverDelegate: IHoverDelegate, htmlElement: HTMLElement, markdownTooltip: string | IIconLabelMarkdownString): void { htmlElement.removeAttribute('title'); - let tooltip = isString(markdownTooltip) ? markdownTooltip : markdownTooltip.markdown; + let tooltip: () => Promise; + if (isString(markdownTooltip)) { + tooltip = async () => markdownTooltip; + } else if (isFunction(markdownTooltip.markdown)) { + tooltip = markdownTooltip.markdown; + } else { + const markdown = markdownTooltip.markdown; + tooltip = async () => markdown; + } // Testing has indicated that on Windows and Linux 500 ms matches the native hovers most closely. // On Mac, the delay is 1500. const hoverDelay = isMacintosh ? 1500 : 500; @@ -217,7 +225,7 @@ export class IconLabel extends Disposable { targetElements: [this], dispose: () => { } }; - const resolvedTooltip = await tooltip; + const resolvedTooltip = await tooltip(); if (resolvedTooltip) { hoverOptions = { text: resolvedTooltip, diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index 2d1654ec47a..dbd8ffce1a9 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -880,10 +880,12 @@ class TreeRenderer extends Disposable implements ITreeRenderer(async (resolve) => { - await node.resolve(); - resolve(node.tooltip); - }), + markdown: (): Promise => { + return new Promise(async (resolve) => { + await node.resolve(); + resolve(node.tooltip); + }); + }, markdownNotSupportedFallback: resource ? undefined : '' // Passing undefined as the fallback for a resource falls back to the old native hover }; } From f4187f22026ff6537f2ca8132ad3209fceb5071f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Wed, 2 Dec 2020 13:40:06 +0100 Subject: [PATCH 030/200] fixes #111732 #111733 --- src/vs/base/browser/ui/list/listPaging.ts | 4 ++ src/vs/platform/list/browser/listService.ts | 46 +++++++++++-------- .../bulkEdit/browser/preview/bulkEditPane.ts | 2 +- .../contrib/debug/browser/breakpointsView.ts | 12 ++--- .../extensions/browser/extensionsViews.ts | 2 +- .../files/browser/views/openEditorsView.ts | 12 ++--- .../contrib/scm/browser/scmViewPane.ts | 2 +- 7 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts index 03db9d2a60d..e2e8e849aa2 100644 --- a/src/vs/base/browser/ui/list/listPaging.ts +++ b/src/vs/base/browser/ui/list/listPaging.ts @@ -258,6 +258,10 @@ export class PagedList implements IThemable, IDisposable { return this.list.getSelection(); } + getSelectedElements(): T[] { + return this.getSelection().map(i => this.model.get(i)); + } + layout(height?: number, width?: number): void { this.list.layout(height, width); } diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index f3f321125c3..3bcc1cd12ad 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -445,11 +445,11 @@ abstract class ResourceNavigator extends Disposable { private readonly openOnFocus: boolean; private openOnSingleClick: boolean; - private readonly _onDidOpen = this._register(new Emitter>()); - readonly onDidOpen: Event> = this._onDidOpen.event; + private readonly _onDidOpen = this._register(new Emitter>()); + readonly onDidOpen: Event> = this._onDidOpen.event; constructor( - private readonly widget: ListWidget, + protected readonly widget: ListWidget, options?: IResourceNavigatorOptions ) { super(); @@ -478,12 +478,11 @@ abstract class ResourceNavigator extends Disposable { const focus = this.widget.getFocus(); this.widget.setSelection(focus, event.browserEvent); - const element = this.widget.getSelection()[0]; const preserveFocus = typeof (event.browserEvent as SelectionKeyboardEvent).preserveFocus === 'boolean' ? (event.browserEvent as SelectionKeyboardEvent).preserveFocus! : true; const pinned = !preserveFocus; const sideBySide = false; - this._open(element, preserveFocus, pinned, sideBySide, event.browserEvent); + this._open(this.getSelectedElement(), preserveFocus, pinned, sideBySide, event.browserEvent); } private onSelectionFromKeyboard(event: ITreeEvent): void { @@ -491,12 +490,11 @@ abstract class ResourceNavigator extends Disposable { return; } - const element = this.widget.getSelection()[0]; const preserveFocus = typeof (event.browserEvent as SelectionKeyboardEvent).preserveFocus === 'boolean' ? (event.browserEvent as SelectionKeyboardEvent).preserveFocus! : true; const pinned = !preserveFocus; const sideBySide = false; - this._open(element, preserveFocus, pinned, sideBySide, event.browserEvent); + this._open(this.getSelectedElement(), preserveFocus, pinned, sideBySide, event.browserEvent); } private onPointer(element: T | undefined, browserEvent: MouseEvent): void { @@ -546,23 +544,35 @@ abstract class ResourceNavigator extends Disposable { browserEvent }); } + + abstract getSelectedElement(): T | undefined; } -export class ListResourceNavigator extends ResourceNavigator { +export class ListResourceNavigator extends ResourceNavigator { + constructor( - list: List | PagedList, + protected readonly widget: List | PagedList, options?: IResourceNavigatorOptions ) { - super(list, options); + super(widget, options); + } + + getSelectedElement(): T | undefined { + return this.widget.getSelectedElements()[0]; } } class TreeResourceNavigator extends ResourceNavigator { + constructor( - tree: ObjectTree | CompressibleObjectTree | DataTree | AsyncDataTree | CompressibleAsyncDataTree, + protected readonly widget: ObjectTree | CompressibleObjectTree | DataTree | AsyncDataTree | CompressibleAsyncDataTree, options: IResourceNavigatorOptions ) { - super(tree, options); + super(widget, options); + } + + getSelectedElement(): T | undefined { + return this.widget.getSelection()[0] ?? undefined; } } @@ -597,7 +607,7 @@ export class WorkbenchObjectTree, TFilterData = void> private internals: WorkbenchTreeInternals; get contextKeyService(): IContextKeyService { return this.internals.contextKeyService; } get useAltAsMultipleSelectionModifier(): boolean { return this.internals.useAltAsMultipleSelectionModifier; } - get onDidOpen(): Event> { return this.internals.onDidOpen; } + get onDidOpen(): Event> { return this.internals.onDidOpen; } constructor( user: string, @@ -633,7 +643,7 @@ export class WorkbenchCompressibleObjectTree, TFilter private internals: WorkbenchTreeInternals; get contextKeyService(): IContextKeyService { return this.internals.contextKeyService; } get useAltAsMultipleSelectionModifier(): boolean { return this.internals.useAltAsMultipleSelectionModifier; } - get onDidOpen(): Event> { return this.internals.onDidOpen; } + get onDidOpen(): Event> { return this.internals.onDidOpen; } constructor( user: string, @@ -677,7 +687,7 @@ export class WorkbenchDataTree extends DataTree; get contextKeyService(): IContextKeyService { return this.internals.contextKeyService; } get useAltAsMultipleSelectionModifier(): boolean { return this.internals.useAltAsMultipleSelectionModifier; } - get onDidOpen(): Event> { return this.internals.onDidOpen; } + get onDidOpen(): Event> { return this.internals.onDidOpen; } constructor( user: string, @@ -722,7 +732,7 @@ export class WorkbenchAsyncDataTree extends Async private internals: WorkbenchTreeInternals; get contextKeyService(): IContextKeyService { return this.internals.contextKeyService; } get useAltAsMultipleSelectionModifier(): boolean { return this.internals.useAltAsMultipleSelectionModifier; } - get onDidOpen(): Event> { return this.internals.onDidOpen; } + get onDidOpen(): Event> { return this.internals.onDidOpen; } constructor( user: string, @@ -764,7 +774,7 @@ export class WorkbenchCompressibleAsyncDataTree e private internals: WorkbenchTreeInternals; get contextKeyService(): IContextKeyService { return this.internals.contextKeyService; } get useAltAsMultipleSelectionModifier(): boolean { return this.internals.useAltAsMultipleSelectionModifier; } - get onDidOpen(): Event> { return this.internals.onDidOpen; } + get onDidOpen(): Event> { return this.internals.onDidOpen; } constructor( user: string, @@ -855,7 +865,7 @@ class WorkbenchTreeInternals { private styler: IDisposable | undefined; private navigator: TreeResourceNavigator; - get onDidOpen(): Event> { return this.navigator.onDidOpen; } + get onDidOpen(): Event> { return this.navigator.onDidOpen; } constructor( private tree: WorkbenchObjectTree | WorkbenchCompressibleObjectTree | WorkbenchDataTree | WorkbenchAsyncDataTree | WorkbenchCompressibleAsyncDataTree, diff --git a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPane.ts b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPane.ts index 97a55f3168f..ab0172eeca7 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPane.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEditPane.ts @@ -298,7 +298,7 @@ export class BulkEditPane extends ViewPane { } } - private async _openElementAsEditor(e: IOpenEvent): Promise { + private async _openElementAsEditor(e: IOpenEvent): Promise { type Mutable = { -readonly [P in keyof T]: T[P] }; diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 8e0a7c2c27b..7fa72c43fc6 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -124,7 +124,7 @@ export class BreakpointsView extends ViewPane { const resourceNavigator = this._register(new ListResourceNavigator(this.list, { configurationService: this.configurationService })); this._register(resourceNavigator.onDidOpen(async e => { - if (e.element === null) { + if (!e.element) { return; } @@ -132,14 +132,12 @@ export class BreakpointsView extends ViewPane { return; } - const element = this.list.element(e.element); - - if (element instanceof Breakpoint) { - openBreakpointSource(element, e.sideBySide, e.editorOptions.preserveFocus || false, e.editorOptions.pinned || !e.editorOptions.preserveFocus, this.debugService, this.editorService); + if (e.element instanceof Breakpoint) { + openBreakpointSource(e.element, e.sideBySide, e.editorOptions.preserveFocus || false, e.editorOptions.pinned || !e.editorOptions.preserveFocus, this.debugService, this.editorService); } - if (e.browserEvent instanceof MouseEvent && e.browserEvent.detail === 2 && element instanceof FunctionBreakpoint && element !== this.debugService.getViewModel().getSelectedBreakpoint()) { + if (e.browserEvent instanceof MouseEvent && e.browserEvent.detail === 2 && e.element instanceof FunctionBreakpoint && e.element !== this.debugService.getViewModel().getSelectedBreakpoint()) { // double click - this.debugService.getViewModel().setSelectedBreakpoint(element); + this.debugService.getViewModel().setSelectedBreakpoint(e.element); this.onBreakpointsChange(); } })); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index 1466661faa5..932a76b68d6 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -177,7 +177,7 @@ export class ExtensionsListView extends ViewPane { const resourceNavigator = this._register(new ListResourceNavigator(this.list, { openOnSingleClick: true })); this._register(Event.debounce(Event.filter(resourceNavigator.onDidOpen, e => e.element !== null), (_, event) => event, 75, true)(options => { - this.openExtension(this.list!.model.get(options.element!), { sideByside: options.sideBySide, ...options.editorOptions }); + this.openExtension(options.element!, { sideByside: options.sideBySide, ...options.editorOptions }); })); this.bodyTemplate = { diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index 8c2a78e037d..3535108c329 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -267,20 +267,16 @@ export class OpenEditorsView extends ViewPane { })); const resourceNavigator = this._register(new ListResourceNavigator(this.list, { configurationService: this.configurationService })); this._register(resourceNavigator.onDidOpen(e => { - if (typeof e.element !== 'number') { + if (!e.element) { return; - } - - const element = this.list.element(e.element); - - if (element instanceof OpenEditor) { + } else if (e.element instanceof OpenEditor) { if (e.browserEvent instanceof MouseEvent && e.browserEvent.button === 1) { return; // middle click already handled above: closes the editor } - this.openEditor(element, { preserveFocus: e.editorOptions.preserveFocus, pinned: e.editorOptions.pinned, sideBySide: e.sideBySide }); + this.openEditor(e.element, { preserveFocus: e.editorOptions.preserveFocus, pinned: e.editorOptions.pinned, sideBySide: e.sideBySide }); } else { - this.editorGroupService.activateGroup(element); + this.editorGroupService.activateGroup(e.element); } })); diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index ed947e74315..4095bee2080 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -1900,7 +1900,7 @@ export class SCMViewPane extends ViewPane { return this.viewModel.getViewActionsContext(); } - private async open(e: IOpenEvent): Promise { + private async open(e: IOpenEvent): Promise { if (!e.element) { return; } else if (isSCMRepository(e.element)) { From b9b92e3152617ff93e903a1af018ab503eca0d53 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 2 Dec 2020 14:13:38 +0100 Subject: [PATCH 031/200] Fix tree item not getting resolved after data change Fixes #111711 --- .../api/browser/mainThreadTreeViews.ts | 6 +++++- src/vs/workbench/common/views.ts | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/browser/mainThreadTreeViews.ts b/src/vs/workbench/api/browser/mainThreadTreeViews.ts index 51f47b691ff..8e32acd7f10 100644 --- a/src/vs/workbench/api/browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/browser/mainThreadTreeViews.ts @@ -235,10 +235,14 @@ class TreeViewDataProvider implements ITreeViewDataProvider { private updateTreeItem(current: ITreeItem, treeItem: ITreeItem): void { treeItem.children = treeItem.children ? treeItem.children : undefined; if (current) { - const properties = distinct([...Object.keys(current), ...Object.keys(treeItem)]); + const properties = distinct([...Object.keys(current instanceof ResolvableTreeItem ? current.asTreeItem() : current), + ...Object.keys(treeItem)]); for (const property of properties) { (current)[property] = (treeItem)[property]; } + if (current instanceof ResolvableTreeItem) { + current.resetResolve(); + } } } } diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 08b11a95553..0744cecf620 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -704,6 +704,27 @@ export class ResolvableTreeItem implements ITreeItem { get hasResolve(): boolean { return this._hasResolve; } + public resetResolve() { + this.resolved = false; + } + public asTreeItem(): ITreeItem { + return { + handle: this.handle, + parentHandle: this.parentHandle, + collapsibleState: this.collapsibleState, + label: this.label, + description: this.description, + icon: this.icon, + iconDark: this.iconDark, + themeIcon: this.themeIcon, + resourceUri: this.resourceUri, + tooltip: this.tooltip, + contextValue: this.contextValue, + command: this.command, + children: this.children, + accessibilityInformation: this.accessibilityInformation + }; + } } export interface ITreeViewDataProvider { From 9a9c6b5557a92f68d8ec561985fd478656229a9a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 2 Dec 2020 14:21:15 +0100 Subject: [PATCH 032/200] Extra character in icon hover. Fixes #111681 --- src/vs/editor/browser/widget/diffEditorWidget.ts | 4 ++-- src/vs/platform/theme/common/iconRegistry.ts | 2 +- src/vs/workbench/contrib/search/browser/searchIcons.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 957af884c00..0730e4f00ec 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -155,8 +155,8 @@ class VisualEditorState { let DIFF_EDITOR_ID = 0; -const diffInsertIcon = registerIcon('diff-insert', Codicon.add, nls.localize('diffInsertIcon', 'Line decoration for inserts in the diff editor')); -const diffRemoveIcon = registerIcon('diff-remove', Codicon.remove, nls.localize('diffRemoveIcon', 'Line decoration for removals in the diff editor')); +const diffInsertIcon = registerIcon('diff-insert', Codicon.add, nls.localize('diffInsertIcon', 'Line decoration for inserts in the diff editor.')); +const diffRemoveIcon = registerIcon('diff-remove', Codicon.remove, nls.localize('diffRemoveIcon', 'Line decoration for removals in the diff editor.')); const ttPolicy = window.trustedTypes?.createPolicy('diffEditorWidget', { createHTML: value => value }); export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffEditor { diff --git a/src/vs/platform/theme/common/iconRegistry.ts b/src/vs/platform/theme/common/iconRegistry.ts index 68b66ae159b..a19a41a84dd 100644 --- a/src/vs/platform/theme/common/iconRegistry.ts +++ b/src/vs/platform/theme/common/iconRegistry.ts @@ -111,7 +111,7 @@ class IconRegistry implements IIconRegistry { if (existing) { if (description && !existing.description) { existing.description = description; - this.iconSchema.properties[id].markdownDescription = `${description}: $(${id})`; + this.iconSchema.properties[id].markdownDescription = `${description} $(${id})`; const enumIndex = this.iconReferenceSchema.enum.indexOf(id); if (enumIndex !== -1) { this.iconReferenceSchema.enumDescriptions[enumIndex] = description; diff --git a/src/vs/workbench/contrib/search/browser/searchIcons.ts b/src/vs/workbench/contrib/search/browser/searchIcons.ts index e556aa76df5..8c6d633bde0 100644 --- a/src/vs/workbench/contrib/search/browser/searchIcons.ts +++ b/src/vs/workbench/contrib/search/browser/searchIcons.ts @@ -9,12 +9,12 @@ import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; export const searchDetailsIcon = registerIcon('search-details', Codicon.ellipsis, localize('searchDetailsIcon', 'Icon to make search details visible.')); -export const searchShowContextIcon = registerIcon('search-show-context', Codicon.listSelection, localize('searchShowContextIcon', 'Icon for toggle the context in the search editor')); +export const searchShowContextIcon = registerIcon('search-show-context', Codicon.listSelection, localize('searchShowContextIcon', 'Icon for toggle the context in the search editor.')); export const searchHideReplaceIcon = registerIcon('search-hide-replace', Codicon.chevronRight, localize('searchHideReplaceIcon', 'Icon to collapse the replace section in the search view.')); export const searchShowReplaceIcon = registerIcon('search-show-replace', Codicon.chevronDown, localize('searchShowReplaceIcon', 'Icon to expand the replace section in the search view.')); export const searchReplaceAllIcon = registerIcon('search-replace-all', Codicon.replaceAll, localize('searchReplaceAllIcon', 'Icon for replace all in the search view.')); export const searchReplaceIcon = registerIcon('search-replace', Codicon.replace, localize('searchReplaceIcon', 'Icon for replace in the search view.')); -export const searchRemoveIcon = registerIcon('search-remove', Codicon.close, localize('searchRemoveIcon', 'Icon to remove a search result')); +export const searchRemoveIcon = registerIcon('search-remove', Codicon.close, localize('searchRemoveIcon', 'Icon to remove a search result.')); export const searchRefreshIcon = registerIcon('search-refresh', Codicon.refresh, localize('searchRefreshIcon', 'Icon for refresh in the search view.')); export const searchCollapseAllIcon = registerIcon('search-collapse-results', Codicon.collapseAll, localize('searchCollapseAllIcon', 'Icon for collapse results in the search view.')); From f622d7b6f1aa99d4800d11a977820f0a8938bf15 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 2 Dec 2020 14:27:10 +0100 Subject: [PATCH 033/200] fixes #111657 --- src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts index e2e5a774dc2..ce16e140557 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts @@ -94,7 +94,7 @@ class CopyOperation implements IFileOperation { } await this._workingCopyFileService.copy([{ source: this.oldUri, target: this.newUri }], { overwrite: this.options.overwrite, ...this.undoRedoInfo }, token); - return this._instaService.createInstance(DeleteOperation, this.newUri, this.options, { isUndoing: true }, true); + return this._instaService.createInstance(DeleteOperation, this.newUri, { recursive: true, ...this.options }, { isUndoing: true }, true); } toString(): string { From 16e91f10115aa235a5790459db1c294e93ac012c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 2 Dec 2020 14:27:54 +0100 Subject: [PATCH 034/200] fix https://github.com/microsoft/vscode/issues/111741 --- src/vs/workbench/api/common/extHostTypeConverters.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 2053893faac..d80dfae4b0c 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -274,8 +274,8 @@ export namespace MarkdownString { if (isCodeblock(markup)) { const { language, value } = markup; res = { value: '```' + language + '\n' + value + '\n```\n' }; - } else if (htmlContent.isMarkdownString(markup)) { - res = markup; + } else if (types.MarkdownString.isMarkdownString(markup)) { + res = { value: markup.value, isTrusted: markup.isTrusted, supportThemeIcons: markup.supportThemeIcons }; } else if (typeof markup === 'string') { res = { value: markup }; } else { From 5d591624ae2944da29969a9de71e1c89959b55ee Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 2 Dec 2020 14:29:21 +0100 Subject: [PATCH 035/200] add install in browser action --- .../extensions/browser/extensionEditor.ts | 3 +- .../extensions/browser/extensionsActions.ts | 36 +++++++++++++-- .../extensions/browser/extensionsList.ts | 3 +- .../browser/extensionEnablementService.ts | 18 ++++---- .../common/extensionManagement.ts | 2 +- .../common/webExtensionsScannerService.ts | 4 +- .../extensionEnablementService.test.ts | 46 ++++++++++++------- 7 files changed, 79 insertions(+), 33 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index a4b6d671ae3..7a58b96da62 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -31,7 +31,7 @@ import { UpdateAction, ReloadAction, MaliciousStatusLabelAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, ExtensionToolTipAction, SystemDisabledWarningAction, LocalInstallAction, ToggleSyncExtensionAction, SetProductIconThemeAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, UninstallAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, - InstallAnotherVersionAction, ExtensionEditorManageExtensionAction + InstallAnotherVersionAction, ExtensionEditorManageExtensionAction, WebInstallAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; @@ -422,6 +422,7 @@ export class ExtensionEditor extends EditorPane { this.instantiationService.createInstance(DisableDropDownAction), this.instantiationService.createInstance(RemoteInstallAction, false), this.instantiationService.createInstance(LocalInstallAction), + this.instantiationService.createInstance(WebInstallAction), combinedInstallAction, this.instantiationService.createInstance(InstallingLabelAction), this.instantiationService.createInstance(ActionWithDropDownAction, 'extensions.uninstall', UninstallAction.UninstallLabel, [ diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 503be3e29f8..b10bfdac82a 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -15,7 +15,7 @@ import { dispose } from 'vs/base/common/lifecycle'; import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewPaneContainer, AutoUpdateConfigurationKey, IExtensionContainer, TOGGLE_IGNORE_EXTENSION_ACTION_ID, INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID } from 'vs/workbench/contrib/extensions/common/extensions'; import { ExtensionsConfigurationInitialContent } from 'vs/workbench/contrib/extensions/common/extensionsFileTemplate'; import { IGalleryExtension, IExtensionGalleryService, INSTALL_ERROR_MALICIOUS, INSTALL_ERROR_INCOMPATIBLE, IGalleryExtensionVersion, ILocalExtension, INSTALL_ERROR_NOT_SUPPORTED, InstallOptions, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IWorkbenchExtensioManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IWorkbenchExtensioManagementService, IWebExtensionsScannerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ExtensionRecommendationReason, IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionType, ExtensionIdentifier, IExtensionDescription, IExtensionManifest, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; @@ -50,7 +50,7 @@ import { alert } from 'vs/base/browser/ui/aria/aria'; import { coalesce } from 'vs/base/common/arrays'; import { IWorkbenchThemeService, IWorkbenchTheme, IWorkbenchColorTheme, IWorkbenchFileIconTheme, IWorkbenchProductIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { ILabelService } from 'vs/platform/label/common/label'; -import { prefersExecuteOnUI, prefersExecuteOnWorkspace, canExecuteOnUI, canExecuteOnWorkspace } from 'vs/workbench/services/extensions/common/extensionsUtil'; +import { prefersExecuteOnUI, prefersExecuteOnWorkspace, canExecuteOnUI, canExecuteOnWorkspace, prefersExecuteOnWeb } from 'vs/workbench/services/extensions/common/extensionsUtil'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IProductService } from 'vs/platform/product/common/productService'; import { IFileDialogService, IDialogService } from 'vs/platform/dialogs/common/dialogs'; @@ -479,7 +479,7 @@ export abstract class InstallInOtherServerAction extends ExtensionAction { } } - private canInstall(): boolean { + protected canInstall(): boolean { // Disable if extension is not installed or not an user extension if ( !this.extension @@ -506,6 +506,11 @@ export abstract class InstallInOtherServerAction extends ExtensionAction { return true; } + // Prefers to run on Web + if (this.server === this.extensionManagementServerService.webExtensionManagementServer && prefersExecuteOnWeb(this.extension.local.manifest, this.productService, this.configurationService)) { + return true; + } + if (this.canInstallAnyWhere) { // Can run on UI if (this.server === this.extensionManagementServerService.localExtensionManagementServer && canExecuteOnUI(this.extension.local.manifest, this.productService, this.configurationService)) { @@ -577,6 +582,31 @@ export class LocalInstallAction extends InstallInOtherServerAction { } +export class WebInstallAction extends InstallInOtherServerAction { + + constructor( + @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, + @IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService, + @IProductService productService: IProductService, + @IConfigurationService configurationService: IConfigurationService, + @IWebExtensionsScannerService private readonly webExtensionsScannerService: IWebExtensionsScannerService, + ) { + super(`extensions.webInstall`, extensionManagementServerService.webExtensionManagementServer, false, extensionsWorkbenchService, extensionManagementServerService, productService, configurationService); + } + + protected getInstallLabel(): string { + return localize('install browser', "Install in Browser"); + } + + protected canInstall(): boolean { + if (super.canInstall()) { + return !!this.extension?.gallery && this.webExtensionsScannerService.canAddExtension(this.extension.gallery); + } + return false; + } + +} + export class UninstallAction extends ExtensionAction { static readonly UninstallLabel = localize('uninstallAction', "Uninstall"); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts index 6b0ed05167f..563a5534ac5 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts @@ -14,7 +14,7 @@ import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging'; import { Event } from 'vs/base/common/event'; import { domEvent } from 'vs/base/browser/event'; import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions'; -import { UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionViewItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, ExtensionToolTipAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; +import { UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionViewItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, ExtensionToolTipAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, WebInstallAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, TooltipWidget, ExtensionPackCountWidget as ExtensionPackBadgeWidget, SyncIgnoredWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets'; import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions'; @@ -112,6 +112,7 @@ export class Renderer implements IPagedRenderer { this.instantiationService.createInstance(InstallingLabelAction), this.instantiationService.createInstance(RemoteInstallAction, false), this.instantiationService.createInstance(LocalInstallAction), + this.instantiationService.createInstance(WebInstallAction), this.instantiationService.createInstance(MaliciousStatusLabelAction, false), systemDisabledWarningAction, this.instantiationService.createInstance(ManageExtensionAction) diff --git a/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts b/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts index eb5e75f1f64..94d47c9cdec 100644 --- a/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts +++ b/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts @@ -215,14 +215,16 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench } } if (extensionKind === 'web') { - const enableLocalWebWorker = this.configurationService.getValue(webWorkerExtHostConfig); - if (enableLocalWebWorker) { - // Web extensions are enabled on all configurations - return false; - } - if (this.extensionManagementServerService.localExtensionManagementServer === null) { - // Web extensions run only in the web - return false; + if (this.extensionManagementServerService.webExtensionManagementServer) { + if (server === this.extensionManagementServerService.webExtensionManagementServer) { + return false; + } + } else if (server === this.extensionManagementServerService.localExtensionManagementServer) { + const enableLocalWebWorker = this.configurationService.getValue(webWorkerExtHostConfig); + if (enableLocalWebWorker) { + // Web extensions are enabled on all configurations + return false; + } } } } diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts index 7f6e33de946..380898ba50d 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts @@ -97,7 +97,7 @@ export interface IWebExtensionsScannerService { scanExtensions(type?: ExtensionType): Promise; scanAndTranslateExtensions(type?: ExtensionType): Promise; scanAndTranslateSingleExtension(extensionLocation: URI, extensionType: ExtensionType): Promise; - canAddExtension(galleryExtension: IGalleryExtension): Promise; + canAddExtension(galleryExtension: IGalleryExtension): boolean; addExtension(galleryExtension: IGalleryExtension): Promise; removeExtension(identifier: IExtensionIdentifier, version?: string): Promise; } diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionsScannerService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionsScannerService.ts index db084cc3f1b..f0cc1bc865a 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionsScannerService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionsScannerService.ts @@ -238,12 +238,12 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten }; } - async canAddExtension(galleryExtension: IGalleryExtension): Promise { + canAddExtension(galleryExtension: IGalleryExtension): boolean { return !!galleryExtension.properties.webExtension && !!galleryExtension.webResource; } async addExtension(galleryExtension: IGalleryExtension): Promise { - if (!(await this.canAddExtension(galleryExtension))) { + if (!this.canAddExtension(galleryExtension)) { const error = new Error(localize('cannot be installed', "Cannot install '{0}' because this extension is not a web extension.", galleryExtension.displayName || galleryExtension.name)); error.name = INSTALL_ERROR_NOT_SUPPORTED; throw error; diff --git a/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts b/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts index ec8f1aca4ef..7259d0698d3 100644 --- a/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts +++ b/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts @@ -545,36 +545,48 @@ suite('ExtensionEnablementService Test', () => { assert.equal(testObject.canChangeEnablement(localWorkspaceExtension), true); }); - test('test web extension on local server is disabled by kind', async () => { + test('test web extension on local server is disabled by kind when web worker is not enabled', async () => { instantiationService.stub(IExtensionManagementServerService, aMultiExtensionManagementServerService(instantiationService)); const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`) }); + (instantiationService.get(IConfigurationService)).setUserConfiguration('extensions', { webWorker: false }); testObject = new TestExtensionEnablementService(instantiationService); - assert.ok(!testObject.isEnabled(localWorkspaceExtension)); + assert.equal(testObject.isEnabled(localWorkspaceExtension), false); assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.DisabledByExtensionKind); }); - test('test web extension on remote server is not disabled by kind when there is no local server', async () => { - instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(null, anExtensionManagementServer('vscode-remote', instantiationService), anExtensionManagementServer('web', instantiationService))); - const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) }); + test('test web extension on local server is not disabled by kind when web worker is enabled', async () => { + instantiationService.stub(IExtensionManagementServerService, aMultiExtensionManagementServerService(instantiationService)); + const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`) }); + (instantiationService.get(IConfigurationService)).setUserConfiguration('extensions', { webWorker: true }); testObject = new TestExtensionEnablementService(instantiationService); - assert.ok(testObject.isEnabled(localWorkspaceExtension)); + assert.equal(testObject.isEnabled(localWorkspaceExtension), true); assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.EnabledGlobally); }); - test('test web extension with no server is not disabled by kind when there is no local server', async () => { - instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(null, anExtensionManagementServer('vscode-remote', instantiationService), anExtensionManagementServer('web', instantiationService))); - const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: Schemas.https }) }); + test('test web extension on remote server is disabled by kind when web worker is not enabled', async () => { + instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(anExtensionManagementServer('vscode-local', instantiationService), anExtensionManagementServer('vscode-remote', instantiationService), anExtensionManagementServer('web', instantiationService))); + const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: 'vscode-remote' }) }); + (instantiationService.get(IConfigurationService)).setUserConfiguration('extensions', { webWorker: false }); testObject = new TestExtensionEnablementService(instantiationService); - assert.ok(testObject.isEnabled(localWorkspaceExtension)); - assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.EnabledGlobally); + assert.equal(testObject.isEnabled(localWorkspaceExtension), false); + assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.DisabledByExtensionKind); }); - test('test web extension with no server is not disabled by kind when there is no local and remote server', async () => { - instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(null, null, anExtensionManagementServer('web', instantiationService))); - const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: Schemas.https }) }); + test('test web extension on remote server is disabled by kind when web worker is enabled', async () => { + instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(anExtensionManagementServer('vscode-local', instantiationService), anExtensionManagementServer('vscode-remote', instantiationService), anExtensionManagementServer('web', instantiationService))); + const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: 'vscode-remote' }) }); + (instantiationService.get(IConfigurationService)).setUserConfiguration('extensions', { webWorker: true }); testObject = new TestExtensionEnablementService(instantiationService); - assert.ok(testObject.isEnabled(localWorkspaceExtension)); - assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.EnabledGlobally); + assert.equal(testObject.isEnabled(localWorkspaceExtension), false); + assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.DisabledByExtensionKind); + }); + + test('test web extension on web server is not disabled by kind', async () => { + instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(anExtensionManagementServer('vscode-local', instantiationService), anExtensionManagementServer('vscode-remote', instantiationService), anExtensionManagementServer('web', instantiationService))); + const webExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: 'web' }) }); + testObject = new TestExtensionEnablementService(instantiationService); + assert.equal(testObject.isEnabled(webExtension), true); + assert.deepEqual(testObject.getEnablementState(webExtension), EnablementState.EnabledGlobally); }); }); @@ -598,7 +610,7 @@ function anExtensionManagementServerService(localExtensionManagementServer: IExt _serviceBrand: undefined, localExtensionManagementServer, remoteExtensionManagementServer, - webExtensionManagementServer: null, + webExtensionManagementServer, getExtensionManagementServer: (extension: IExtension) => { if (extension.location.scheme === Schemas.file) { return localExtensionManagementServer; From 0be03ecc6d43213b70087fda404e30c79a2e9113 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 2 Dec 2020 14:37:43 +0100 Subject: [PATCH 036/200] fixes #111693 --- src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts index ce16e140557..7d0e8f2635e 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts @@ -93,8 +93,9 @@ class CopyOperation implements IFileOperation { return new Noop(); // not overwriting, but ignoring, and the target file exists } - await this._workingCopyFileService.copy([{ source: this.oldUri, target: this.newUri }], { overwrite: this.options.overwrite, ...this.undoRedoInfo }, token); - return this._instaService.createInstance(DeleteOperation, this.newUri, { recursive: true, ...this.options }, { isUndoing: true }, true); + const stat = await this._workingCopyFileService.copy([{ source: this.oldUri, target: this.newUri }], { overwrite: this.options.overwrite, ...this.undoRedoInfo }, token); + const folder = this.options.folder || (stat.length === 1 && stat[0].isDirectory); + return this._instaService.createInstance(DeleteOperation, this.newUri, { recursive: true, folder, ...this.options }, { isUndoing: true }, true); } toString(): string { From 8d171e649243d446bc6c0f31a732499c5b04cf16 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 2 Dec 2020 14:39:21 +0100 Subject: [PATCH 037/200] Improve multiple lock files notification Fixes #111589 --- extensions/npm/src/commands.ts | 8 ++--- extensions/npm/src/npmMain.ts | 4 +-- extensions/npm/src/npmView.ts | 4 +-- extensions/npm/src/scriptHover.ts | 6 ++-- extensions/npm/src/tasks.ts | 57 +++++++++++++++++-------------- 5 files changed, 43 insertions(+), 36 deletions(-) diff --git a/extensions/npm/src/commands.ts b/extensions/npm/src/commands.ts index 7ca92879f9b..4f9131a44b4 100644 --- a/extensions/npm/src/commands.ts +++ b/extensions/npm/src/commands.ts @@ -15,7 +15,7 @@ import { const localize = nls.loadMessageBundle(); -export function runSelectedScript() { +export function runSelectedScript(context: vscode.ExtensionContext) { let editor = vscode.window.activeTextEditor; if (!editor) { return; @@ -27,15 +27,15 @@ export function runSelectedScript() { let script = findScriptAtPosition(contents, offset); if (script) { - runScript(script, document); + runScript(context, script, document); } else { let message = localize('noScriptFound', 'Could not find a valid npm script at the selection.'); vscode.window.showErrorMessage(message); } } -export async function selectAndRunScriptFromFolder(selectedFolder: vscode.Uri) { - let taskList: FolderTaskItem[] = await detectNpmScriptsForFolder(selectedFolder); +export async function selectAndRunScriptFromFolder(context: vscode.ExtensionContext, selectedFolder: vscode.Uri) { + let taskList: FolderTaskItem[] = await detectNpmScriptsForFolder(context, selectedFolder); if (taskList && taskList.length > 0) { const quickPick = vscode.window.createQuickPick(); diff --git a/extensions/npm/src/npmMain.ts b/extensions/npm/src/npmMain.ts index 91936da6257..568c5ea3d6f 100644 --- a/extensions/npm/src/npmMain.ts +++ b/extensions/npm/src/npmMain.ts @@ -58,7 +58,7 @@ export async function activate(context: vscode.ExtensionContext): Promise })); context.subscriptions.push(vscode.commands.registerCommand('npm.packageManager', (args) => { if (args instanceof vscode.Uri) { - return getPackageManager(args); + return getPackageManager(context, args); } return ''; })); @@ -83,7 +83,7 @@ function registerTaskProvider(context: vscode.ExtensionContext): vscode.Disposab let workspaceWatcher = vscode.workspace.onDidChangeWorkspaceFolders((_e) => invalidateScriptCaches()); context.subscriptions.push(workspaceWatcher); - taskProvider = new NpmTaskProvider(); + taskProvider = new NpmTaskProvider(context); let disposable = vscode.tasks.registerTaskProvider('npm', taskProvider); context.subscriptions.push(disposable); return disposable; diff --git a/extensions/npm/src/npmView.ts b/extensions/npm/src/npmView.ts index e7eec0e84fa..8617b7f7f8d 100644 --- a/extensions/npm/src/npmView.ts +++ b/extensions/npm/src/npmView.ts @@ -146,7 +146,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider { } private async debugScript(script: NpmScript) { - startDebugging(script.task.definition.script, path.dirname(script.package.resourceUri!.fsPath), script.getFolder()); + startDebugging(this.extensionContext, script.task.definition.script, path.dirname(script.package.resourceUri!.fsPath), script.getFolder()); } private findScript(document: TextDocument, script?: NpmScript): number { @@ -190,7 +190,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider { if (!uri) { return; } - let task = await createTask('install', 'install', selection.folder.workspaceFolder, uri, undefined, []); + let task = await createTask(this.extensionContext, 'install', 'install', selection.folder.workspaceFolder, uri, undefined, []); tasks.executeTask(task); } diff --git a/extensions/npm/src/scriptHover.ts b/extensions/npm/src/scriptHover.ts index 01c0c4b8c63..48482660f52 100644 --- a/extensions/npm/src/scriptHover.ts +++ b/extensions/npm/src/scriptHover.ts @@ -30,7 +30,7 @@ export function invalidateHoverScriptsCache(document?: TextDocument) { export class NpmScriptHoverProvider implements HoverProvider { - constructor(context: ExtensionContext) { + constructor(private context: ExtensionContext) { context.subscriptions.push(commands.registerCommand('npm.runScriptFromHover', this.runScriptFromHover, this)); context.subscriptions.push(commands.registerCommand('npm.debugScriptFromHover', this.debugScriptFromHover, this)); context.subscriptions.push(workspace.onDidChangeTextDocument((e) => { @@ -103,7 +103,7 @@ export class NpmScriptHoverProvider implements HoverProvider { let documentUri = args.documentUri; let folder = workspace.getWorkspaceFolder(documentUri); if (folder) { - let task = await createTask(script, `run ${script}`, folder, documentUri); + let task = await createTask(this.context, script, `run ${script}`, folder, documentUri); await tasks.executeTask(task); } } @@ -113,7 +113,7 @@ export class NpmScriptHoverProvider implements HoverProvider { let documentUri = args.documentUri; let folder = workspace.getWorkspaceFolder(documentUri); if (folder) { - startDebugging(script, dirname(documentUri.fsPath), folder); + startDebugging(this.context, script, dirname(documentUri.fsPath), folder); } } } diff --git a/extensions/npm/src/tasks.ts b/extensions/npm/src/tasks.ts index 41e8cf45492..fac16a3960d 100644 --- a/extensions/npm/src/tasks.ts +++ b/extensions/npm/src/tasks.ts @@ -5,7 +5,7 @@ import { TaskDefinition, Task, TaskGroup, WorkspaceFolder, RelativePattern, ShellExecution, Uri, workspace, - DebugConfiguration, debug, TaskProvider, TextDocument, tasks, TaskScope, QuickPickItem, window, Position + DebugConfiguration, debug, TaskProvider, TextDocument, tasks, TaskScope, QuickPickItem, window, Position, ExtensionContext, env } from 'vscode'; import * as path from 'path'; import * as fs from 'fs'; @@ -44,15 +44,15 @@ export interface TaskWithLocation { export class NpmTaskProvider implements TaskProvider { - constructor() { + constructor(private context: ExtensionContext) { } get tasksWithLocation(): Promise { - return provideNpmScripts(); + return provideNpmScripts(this.context); } public async provideTasks() { - const tasks = await provideNpmScripts(); + const tasks = await provideNpmScripts(this.context); return tasks.map(task => task.task); } @@ -70,7 +70,7 @@ export class NpmTaskProvider implements TaskProvider { } else { packageJsonUri = _task.scope.uri.with({ path: _task.scope.uri.path + '/package.json' }); } - return createTask(kind, `${kind.script === INSTALL_SCRIPT ? '' : 'run '}${kind.script}`, _task.scope, packageJsonUri); + return createTask(this.context, kind, `${kind.script === INSTALL_SCRIPT ? '' : 'run '}${kind.script}`, _task.scope, packageJsonUri); } return undefined; } @@ -123,16 +123,23 @@ export function isWorkspaceFolder(value: any): value is WorkspaceFolder { return value && typeof value !== 'number'; } -export async function getPackageManager(folder: Uri): Promise { +export async function getPackageManager(extensionContext: ExtensionContext, folder: Uri): Promise { let packageManagerName = workspace.getConfiguration('npm', folder).get('packageManager', 'npm'); if (packageManagerName === 'auto') { const { name, multiplePMDetected } = await findPreferredPM(folder.fsPath); packageManagerName = name; - - if (multiplePMDetected) { - const multiplePMWarning = localize('npm.multiplePMWarning', 'Found multiple lockfiles for {0}. Using {1} as the preferred package manager.', folder.fsPath, packageManagerName); - window.showWarningMessage(multiplePMWarning); + const neverShowWarning = 'npm.multiplePMWarning.neverShow'; + if (multiplePMDetected && !extensionContext.globalState.get(neverShowWarning)) { + const multiplePMWarning = localize('npm.multiplePMWarning', 'Using {0} as the preferred package manager. Found multiple lockfiles for {1}.', packageManagerName, folder.fsPath); + const neverShowAgain = localize('npm.multiplePMWarning.doNotShow', "Do not show again"); + const learnMore = localize('npm.multiplePMWarning.learnMore', "Learn more"); + window.showInformationMessage(multiplePMWarning, learnMore, neverShowAgain).then(result => { + switch (result) { + case neverShowAgain: extensionContext.globalState.update(neverShowWarning, true); break; + case learnMore: env.openExternal(Uri.parse('https://nodejs.dev/learn/the-package-lock-json-file')); + } + }); } } @@ -160,7 +167,7 @@ export async function hasNpmScripts(): Promise { } } -async function detectNpmScripts(): Promise { +async function detectNpmScripts(context: ExtensionContext): Promise { let emptyTasks: TaskWithLocation[] = []; let allTasks: TaskWithLocation[] = []; @@ -177,7 +184,7 @@ async function detectNpmScripts(): Promise { let paths = await workspace.findFiles(relativePattern, '**/{node_modules,.vscode-test}/**'); for (const path of paths) { if (!isExcluded(folder, path) && !visitedPackageJsonFiles.has(path.fsPath)) { - let tasks = await provideNpmScriptsForFolder(path); + let tasks = await provideNpmScriptsForFolder(context, path); visitedPackageJsonFiles.add(path.fsPath); allTasks.push(...tasks); } @@ -191,7 +198,7 @@ async function detectNpmScripts(): Promise { } -export async function detectNpmScriptsForFolder(folder: Uri): Promise { +export async function detectNpmScriptsForFolder(context: ExtensionContext, folder: Uri): Promise { let folderTasks: FolderTaskItem[] = []; @@ -202,7 +209,7 @@ export async function detectNpmScriptsForFolder(folder: Uri): Promise = new Set(); for (const path of paths) { if (!visitedPackageJsonFiles.has(path.fsPath)) { - let tasks = await provideNpmScriptsForFolder(path); + let tasks = await provideNpmScriptsForFolder(context, path); visitedPackageJsonFiles.add(path.fsPath); folderTasks.push(...tasks.map(t => ({ label: t.task.name, task: t.task }))); } @@ -213,9 +220,9 @@ export async function detectNpmScriptsForFolder(folder: Uri): Promise { +export async function provideNpmScripts(context: ExtensionContext): Promise { if (!cachedTasks) { - cachedTasks = await detectNpmScripts(); + cachedTasks = await detectNpmScripts(context); } return cachedTasks; } @@ -251,7 +258,7 @@ function isDebugScript(script: string): boolean { return match !== null; } -async function provideNpmScriptsForFolder(packageJsonUri: Uri): Promise { +async function provideNpmScriptsForFolder(context: ExtensionContext, packageJsonUri: Uri): Promise { let emptyTasks: TaskWithLocation[] = []; let folder = workspace.getWorkspaceFolder(packageJsonUri); @@ -269,7 +276,7 @@ async function provideNpmScriptsForFolder(packageJsonUri: Uri): Promise { +export async function createTask(context: ExtensionContext, script: NpmTaskDefinition | string, cmd: string, folder: WorkspaceFolder, packageJsonUri: Uri, detail?: string, matcher?: any): Promise { let kind: NpmTaskDefinition; if (typeof script === 'string') { kind = { type: 'npm', script: script }; @@ -307,7 +314,7 @@ export async function createTask(script: NpmTaskDefinition | string, cmd: string kind = script; } - const packageManager = await getPackageManager(folder.uri); + const packageManager = await getPackageManager(context, folder.uri); async function getCommandLine(cmd: string): Promise { if (workspace.getConfiguration('npm', folder.uri).get('runSilent')) { return `${packageManager} --silent ${cmd}`; @@ -368,22 +375,22 @@ async function exists(file: string): Promise { }); } -export async function runScript(script: string, document: TextDocument) { +export async function runScript(context: ExtensionContext, script: string, document: TextDocument) { let uri = document.uri; let folder = workspace.getWorkspaceFolder(uri); if (folder) { - let task = await createTask(script, `run ${script}`, folder, uri); + let task = await createTask(context, script, `run ${script}`, folder, uri); tasks.executeTask(task); } } -export async function startDebugging(scriptName: string, cwd: string, folder: WorkspaceFolder) { +export async function startDebugging(context: ExtensionContext, scriptName: string, cwd: string, folder: WorkspaceFolder) { const config: DebugConfiguration = { type: 'pwa-node', request: 'launch', name: `Debug ${scriptName}`, cwd, - runtimeExecutable: await getPackageManager(folder.uri), + runtimeExecutable: await getPackageManager(context, folder.uri), runtimeArgs: [ 'run', scriptName, From 2ba6946272a6674f5b94c3316114fd2735f186e3 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 2 Dec 2020 15:07:34 +0100 Subject: [PATCH 038/200] fixes #111581 --- src/vs/workbench/contrib/files/browser/views/explorerViewer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 7197ee94609..9245c9733c7 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -1352,7 +1352,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { // if we only add one file, just open it directly if (resourceFileEdits.length === 1) { const item = this.explorerService.findClosest(resourceFileEdits[0].newResource!); - if (item) { + if (item && !item.isDirectory) { this.editorService.openEditor({ resource: item.resource, options: { pinned: true } }); } } From 51b1029e98f84bb5222989a7f6e70da3d62b8528 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 2 Dec 2020 15:21:34 +0100 Subject: [PATCH 039/200] Check detected tunnels before auto forwarding Fixes microsoft/vscode-remote-release#4112 --- src/vs/workbench/contrib/remote/browser/remoteExplorer.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts index 138dd8ed5d2..0c477522326 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts @@ -376,6 +376,9 @@ class LinuxAutomaticPortForwarding extends Disposable { if (this.initialCandidates.has(address)) { return undefined; } + if (mapHasAddressLocalhostOrAllInterfaces(this.remoteExplorerService.tunnelModel.detected, value.host, value.port)) { + return undefined; + } const forwarded = await this.remoteExplorerService.forward(value); if (forwarded) { this.autoForwarded.add(address); From 763b155fe9b0f72d9f0053afa2dc23664f5cd82c Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 2 Dec 2020 15:38:31 +0100 Subject: [PATCH 040/200] Fix #111574 --- .../contrib/extensions/browser/extensionsActions.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index b10bfdac82a..0aa7ddd1b10 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -1429,11 +1429,12 @@ export class ReloadAction extends ExtensionAction { } const isUninstalled = this.extension.state === ExtensionState.Uninstalled; - const runningExtension = this._runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, this.extension!.identifier))[0]; - const isSameExtensionRunning = runningExtension && this.extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension)); + const runningExtension = this._runningExtensions.find(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, this.extension!.identifier)); if (isUninstalled) { - if (isSameExtensionRunning && !this.extensionService.canRemoveExtension(runningExtension)) { + const canRemoveRunningExtension = runningExtension && this.extensionService.canRemoveExtension(runningExtension); + const isSameExtensionRunning = runningExtension && (!this.extension.server || this.extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension))); + if (!canRemoveRunningExtension && isSameExtensionRunning) { this.enabled = true; this.label = localize('reloadRequired', "Reload Required"); this.tooltip = localize('postUninstallTooltip', "Please reload Visual Studio Code to complete the uninstallation of this extension."); @@ -1442,6 +1443,7 @@ export class ReloadAction extends ExtensionAction { return; } if (this.extension.local) { + const isSameExtensionRunning = runningExtension && this.extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension)); const isEnabled = this.extensionEnablementService.isEnabled(this.extension.local); // Extension is running From 65c70884c14dff1deccc3a8ff105d54bc8c74f9a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 2 Dec 2020 15:49:52 +0100 Subject: [PATCH 041/200] Fix #106989 --- .../contrib/userDataSync/browser/userDataSync.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts index 438b3cad3c7..8a1aa13b2d8 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { Action } from 'vs/base/common/actions'; -import { toErrorMessage } from 'vs/base/common/errorMessage'; import { isPromiseCanceledError } from 'vs/base/common/errors'; import { Event } from 'vs/base/common/event'; import { Disposable, DisposableStore, dispose, MutableDisposable, toDisposable, IDisposable } from 'vs/base/common/lifecycle'; @@ -258,7 +257,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo await this.userDataSyncService.accept(syncResource, conflict.remoteResource, undefined, this.userDataAutoSyncEnablementService.isEnabled()); } } catch (e) { - this.notificationService.error(e); + this.notificationService.error(localize('accept failed', "Error while accepting changes. Please check [logs]({0}) for more details.", `command:${SHOW_SYNC_LOG_COMMAND_ID}`)); } } @@ -268,7 +267,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo await this.userDataSyncService.accept(syncResource, conflict.localResource, undefined, this.userDataAutoSyncEnablementService.isEnabled()); } } catch (e) { - this.notificationService.error(e); + this.notificationService.error(localize('accept failed', "Error while accepting changes. Please check [logs]({0}) for more details.", `command:${SHOW_SYNC_LOG_COMMAND_ID}`)); } } @@ -1050,7 +1049,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo await that.turnOff(); } catch (e) { if (!isPromiseCanceledError(e)) { - that.notificationService.error(localize('turn off failed', "Error while turning off sync: {0}", toErrorMessage(e))); + that.notificationService.error(localize('turn off failed', "Error while turning off Settings Sync. Please check [logs]({0}) for more details.", `command:${SHOW_SYNC_LOG_COMMAND_ID}`)); } } } @@ -1254,7 +1253,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio this.notificationService.warn(localize('update conflicts', "Could not resolve conflicts as there is new local version available. Please try again.")); } } else { - this.notificationService.error(e); + this.notificationService.error(localize('accept failed', "Error while accepting changes. Please check [logs]({0}) for more details.", `command:${SHOW_SYNC_LOG_COMMAND_ID}`)); } } } From 16ffa1deffd6a843024686f91fa7fbd6e514b345 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 2 Dec 2020 16:11:15 +0100 Subject: [PATCH 042/200] Add GreaterEquals and SmallerEquals and fix implementations --- .../platform/contextkey/common/contextkey.ts | 292 +++++++++++------- .../contextkey/test/common/contextkey.test.ts | 69 +++++ 2 files changed, 244 insertions(+), 117 deletions(-) diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index 15802baa72b..5b536419db9 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -33,7 +33,9 @@ export const enum ContextKeyExprType { In = 10, NotIn = 11, Greater = 12, - Less = 13, + GreaterEquals = 13, + Smaller = 14, + SmallerEquals = 15, } export interface IContextKeyExprMapper { @@ -41,6 +43,10 @@ export interface IContextKeyExprMapper { mapNot(key: string): ContextKeyExpression; mapEquals(key: string, value: any): ContextKeyExpression; mapNotEquals(key: string, value: any): ContextKeyExpression; + mapGreater(key: string, value: any): ContextKeyExpression; + mapGreaterEquals(key: string, value: any): ContextKeyExpression; + mapSmaller(key: string, value: any): ContextKeyExpression; + mapSmallerEquals(key: string, value: any): ContextKeyExpression; mapRegex(key: string, regexp: RegExp | null): ContextKeyRegexExpr; mapIn(key: string, valueKey: string): ContextKeyInExpr; } @@ -59,7 +65,9 @@ export interface IContextKeyExpression { export type ContextKeyExpression = ( ContextKeyFalseExpr | ContextKeyTrueExpr | ContextKeyDefinedExpr | ContextKeyNotExpr | ContextKeyEqualsExpr | ContextKeyNotEqualsExpr | ContextKeyRegexExpr - | ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr | ContextKeyInExpr | ContextKeyNotInExpr | ContextKeyGreaterExpr | ContextKeyLessExpr + | ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr | ContextKeyInExpr + | ContextKeyNotInExpr | ContextKeyGreaterExpr | ContextKeyGreaterEqualsExpr + | ContextKeySmallerExpr | ContextKeySmallerEqualsExpr ); export abstract class ContextKeyExpr { @@ -109,7 +117,7 @@ export abstract class ContextKeyExpr { } public static less(key: string, value: any): ContextKeyExpression { - return ContextKeyLessExpr.create(key, value); + return ContextKeySmallerExpr.create(key, value); } public static deserialize(serialized: string | null | undefined, strict: boolean = false): ContextKeyExpression | undefined { @@ -153,14 +161,24 @@ export abstract class ContextKeyExpr { return ContextKeyInExpr.create(pieces[0].trim(), pieces[1].trim()); } + if (serializedOne.indexOf('>=') >= 0) { + const pieces = serializedOne.split('>='); + return ContextKeyGreaterEqualsExpr.create(pieces[0].trim(), pieces[1].trim()); + } + if (serializedOne.indexOf('>') >= 0) { - let pieces = serializedOne.split('>'); - return ContextKeyGreaterExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict)); + const pieces = serializedOne.split('>'); + return ContextKeyGreaterExpr.create(pieces[0].trim(), pieces[1].trim()); + } + + if (serializedOne.indexOf('<=') >= 0) { + const pieces = serializedOne.split('<='); + return ContextKeySmallerEqualsExpr.create(pieces[0].trim(), pieces[1].trim()); } if (serializedOne.indexOf('<') >= 0) { - let pieces = serializedOne.split('<'); - return ContextKeyLessExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict)); + const pieces = serializedOne.split('<'); + return ContextKeySmallerExpr.create(pieces[0].trim(), pieces[1].trim()); } if (/^\!\s*/.test(serializedOne)) { @@ -322,13 +340,7 @@ export class ContextKeyDefinedExpr implements IContextKeyExpression { if (other.type !== this.type) { return this.type - other.type; } - if (this.key < other.key) { - return -1; - } - if (this.key > other.key) { - return 1; - } - return 0; + return cmp1(this.key, other.key); } public equals(other: ContextKeyExpression): boolean { @@ -382,19 +394,7 @@ export class ContextKeyEqualsExpr implements IContextKeyExpression { if (other.type !== this.type) { return this.type - other.type; } - if (this.key < other.key) { - return -1; - } - if (this.key > other.key) { - return 1; - } - if (this.value < other.value) { - return -1; - } - if (this.value > other.value) { - return 1; - } - return 0; + return cmp2(this.key, this.value, other.key, other.value); } public equals(other: ContextKeyExpression): boolean { @@ -442,19 +442,7 @@ export class ContextKeyInExpr implements IContextKeyExpression { if (other.type !== this.type) { return this.type - other.type; } - if (this.key < other.key) { - return -1; - } - if (this.key > other.key) { - return 1; - } - if (this.valueKey < other.valueKey) { - return -1; - } - if (this.valueKey > other.valueKey) { - return 1; - } - return 0; + return cmp2(this.key, this.valueKey, other.key, other.valueKey); } public equals(other: ContextKeyExpression): boolean { @@ -569,19 +557,7 @@ export class ContextKeyNotEqualsExpr implements IContextKeyExpression { if (other.type !== this.type) { return this.type - other.type; } - if (this.key < other.key) { - return -1; - } - if (this.key > other.key) { - return 1; - } - if (this.value < other.value) { - return -1; - } - if (this.value > other.value) { - return 1; - } - return 0; + return cmp2(this.key, this.value, other.key, other.value); } public equals(other: ContextKeyExpression): boolean { @@ -633,13 +609,7 @@ export class ContextKeyNotExpr implements IContextKeyExpression { if (other.type !== this.type) { return this.type - other.type; } - if (this.key < other.key) { - return -1; - } - if (this.key > other.key) { - return 1; - } - return 0; + return cmp1(this.key, other.key); } public equals(other: ContextKeyExpression): boolean { @@ -673,39 +643,21 @@ export class ContextKeyNotExpr implements IContextKeyExpression { export class ContextKeyGreaterExpr implements IContextKeyExpression { public static create(key: string, value: any): ContextKeyExpression { - if (typeof value === 'boolean') { - return (value ? ContextKeyDefinedExpr.create(key) : ContextKeyNotExpr.create(key)); - } - const staticValue = STATIC_VALUES.get(key); - if (typeof staticValue === 'boolean') { - const trueValue = staticValue ? 'true' : 'false'; - return (value === trueValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE); - } return new ContextKeyGreaterExpr(key, value); } public readonly type = ContextKeyExprType.Greater; - private constructor(private readonly key: string, private readonly value: any) { - } + private constructor( + private readonly key: string, + private readonly value: any + ) { } public cmp(other: ContextKeyExpression): number { if (other.type !== this.type) { return this.type - other.type; } - if (this.key < other.key) { - return -1; - } - if (this.key > other.key) { - return 1; - } - if (this.value < other.value) { - return -1; - } - if (this.value > other.value) { - return 1; - } - return 0; + return cmp2(this.key, this.value, other.key, other.value); } public equals(other: ContextKeyExpression): boolean { @@ -716,11 +668,11 @@ export class ContextKeyGreaterExpr implements IContextKeyExpression { } public evaluate(context: IContext): boolean { - return (Number(context.getValue(this.key)) > this.value); + return (parseFloat(context.getValue(this.key)) > parseFloat(this.value)); } public serialize(): string { - return `${this.key} > '${this.value}'`; + return `${this.key} > ${this.value}`; } public keys(): string[] { @@ -728,50 +680,32 @@ export class ContextKeyGreaterExpr implements IContextKeyExpression { } public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression { - return mapFnc.mapEquals(this.key, this.value); + return mapFnc.mapGreater(this.key, this.value); } public negate(): ContextKeyExpression { - return ContextKeyNotEqualsExpr.create(this.key, this.value); + return ContextKeySmallerEqualsExpr.create(this.key, this.value); } } -export class ContextKeyLessExpr implements IContextKeyExpression { +export class ContextKeyGreaterEqualsExpr implements IContextKeyExpression { public static create(key: string, value: any): ContextKeyExpression { - if (typeof value === 'boolean') { - return (value ? ContextKeyDefinedExpr.create(key) : ContextKeyNotExpr.create(key)); - } - const staticValue = STATIC_VALUES.get(key); - if (typeof staticValue === 'boolean') { - const trueValue = staticValue ? 'true' : 'false'; - return (value === trueValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE); - } - return new ContextKeyLessExpr(key, value); + return new ContextKeyGreaterEqualsExpr(key, value); } - public readonly type = ContextKeyExprType.Less; + public readonly type = ContextKeyExprType.GreaterEquals; - private constructor(private readonly key: string, private readonly value: any) { - } + private constructor( + private readonly key: string, + private readonly value: any + ) { } public cmp(other: ContextKeyExpression): number { if (other.type !== this.type) { return this.type - other.type; } - if (this.key < other.key) { - return -1; - } - if (this.key > other.key) { - return 1; - } - if (this.value < other.value) { - return -1; - } - if (this.value > other.value) { - return 1; - } - return 0; + return cmp2(this.key, this.value, other.key, other.value); } public equals(other: ContextKeyExpression): boolean { @@ -782,11 +716,11 @@ export class ContextKeyLessExpr implements IContextKeyExpression { } public evaluate(context: IContext): boolean { - return (Number(context.getValue(this.key)) < this.value); + return (parseFloat(context.getValue(this.key)) >= parseFloat(this.value)); } public serialize(): string { - return `${this.key} < '${this.value}'`; + return `${this.key} >= ${this.value}`; } public keys(): string[] { @@ -794,11 +728,109 @@ export class ContextKeyLessExpr implements IContextKeyExpression { } public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression { - return mapFnc.mapEquals(this.key, this.value); + return mapFnc.mapGreaterEquals(this.key, this.value); } public negate(): ContextKeyExpression { - return ContextKeyNotEqualsExpr.create(this.key, this.value); + return ContextKeySmallerExpr.create(this.key, this.value); + } +} + +export class ContextKeySmallerExpr implements IContextKeyExpression { + + public static create(key: string, value: any): ContextKeyExpression { + return new ContextKeySmallerExpr(key, value); + } + + public readonly type = ContextKeyExprType.Smaller; + + private constructor( + private readonly key: string, + private readonly value: any + ) { + } + + public cmp(other: ContextKeyExpression): number { + if (other.type !== this.type) { + return this.type - other.type; + } + return cmp2(this.key, this.value, other.key, other.value); + } + + public equals(other: ContextKeyExpression): boolean { + if (other.type === this.type) { + return (this.key === other.key && this.value === other.value); + } + return false; + } + + public evaluate(context: IContext): boolean { + return (parseFloat(context.getValue(this.key)) < parseFloat(this.value)); + } + + public serialize(): string { + return `${this.key} < ${this.value}`; + } + + public keys(): string[] { + return [this.key]; + } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression { + return mapFnc.mapSmaller(this.key, this.value); + } + + public negate(): ContextKeyExpression { + return ContextKeyGreaterEqualsExpr.create(this.key, this.value); + } +} + +export class ContextKeySmallerEqualsExpr implements IContextKeyExpression { + + public static create(key: string, value: any): ContextKeyExpression { + return new ContextKeySmallerEqualsExpr(key, value); + } + + public readonly type = ContextKeyExprType.SmallerEquals; + + private constructor( + private readonly key: string, + private readonly value: any + ) { + } + + public cmp(other: ContextKeyExpression): number { + if (other.type !== this.type) { + return this.type - other.type; + } + return cmp2(this.key, this.value, other.key, other.value); + } + + public equals(other: ContextKeyExpression): boolean { + if (other.type === this.type) { + return (this.key === other.key && this.value === other.value); + } + return false; + } + + public evaluate(context: IContext): boolean { + return (parseFloat(context.getValue(this.key)) <= parseFloat(this.value)); + } + + public serialize(): string { + return `${this.key} <= ${this.value}`; + } + + public keys(): string[] { + return [this.key]; + } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression { + return mapFnc.mapSmallerEquals(this.key, this.value); + } + + public negate(): ContextKeyExpression { + return ContextKeyGreaterExpr.create(this.key, this.value); } } @@ -1295,3 +1327,29 @@ export interface IContextKeyService { } export const SET_CONTEXT_COMMAND_ID = 'setContext'; + +function cmp1(key1: string, key2: string): number { + if (key1 < key2) { + return -1; + } + if (key1 > key2) { + return 1; + } + return 0; +} + +function cmp2(key1: string, value1: any, key2: string, value2: any): number { + if (key1 < key2) { + return -1; + } + if (key1 > key2) { + return 1; + } + if (value1 < value2) { + return -1; + } + if (value1 > value2) { + return 1; + } + return 0; +} diff --git a/src/vs/platform/contextkey/test/common/contextkey.test.ts b/src/vs/platform/contextkey/test/common/contextkey.test.ts index 2912df4b0ea..5701b9dc86b 100644 --- a/src/vs/platform/contextkey/test/common/contextkey.test.ts +++ b/src/vs/platform/contextkey/test/common/contextkey.test.ts @@ -186,4 +186,73 @@ suite('ContextKeyExpr', () => { ); assert.equal(actual!.equals(expected!), true); }); + + test('Greater, GreaterEquals, Smaller, SmallerEquals evaluate', () => { + function checkEvaluate(expr: string, ctx: any, expected: any): void { + const _expr = ContextKeyExpr.deserialize(expr)!; + assert.equal(_expr.evaluate(createContext(ctx)), expected); + } + + checkEvaluate('a>1', {}, false); + checkEvaluate('a>1', { a: 0 }, false); + checkEvaluate('a>1', { a: 1 }, false); + checkEvaluate('a>1', { a: 2 }, true); + checkEvaluate('a>1', { a: '0' }, false); + checkEvaluate('a>1', { a: '1' }, false); + checkEvaluate('a>1', { a: '2' }, true); + checkEvaluate('a>1', { a: 'a' }, false); + + checkEvaluate('a>10', { a: 2 }, false); + checkEvaluate('a>10', { a: 11 }, true); + checkEvaluate('a>10', { a: '11' }, true); + checkEvaluate('a>10', { a: '2' }, false); + checkEvaluate('a>10', { a: '11' }, true); + + checkEvaluate('a>1.1', { a: 1 }, false); + checkEvaluate('a>1.1', { a: 2 }, true); + checkEvaluate('a>1.1', { a: 11 }, true); + checkEvaluate('a>1.1', { a: '1.1' }, false); + checkEvaluate('a>1.1', { a: '2' }, true); + checkEvaluate('a>1.1', { a: '11' }, true); + + checkEvaluate('a>b', { a: 'b' }, false); + checkEvaluate('a>b', { a: 'c' }, false); + checkEvaluate('a>b', { a: 1000 }, false); + + checkEvaluate('a >= 2', { a: '1' }, false); + checkEvaluate('a >= 2', { a: '2' }, true); + checkEvaluate('a >= 2', { a: '3' }, true); + + checkEvaluate('a < 2', { a: '1' }, true); + checkEvaluate('a < 2', { a: '2' }, false); + checkEvaluate('a < 2', { a: '3' }, false); + + checkEvaluate('a <= 2', { a: '1' }, true); + checkEvaluate('a <= 2', { a: '2' }, true); + checkEvaluate('a <= 2', { a: '3' }, false); + }); + + test('Greater, GreaterEquals, Smaller, SmallerEquals negate', () => { + function checkNegate(expr: string, expected: string): void { + const a = ContextKeyExpr.deserialize(expr)!; + const b = a.negate(); + assert.equal(b.serialize(), expected); + } + + checkNegate('a>1', 'a <= 1'); + checkNegate('a>1.1', 'a <= 1.1'); + checkNegate('a>b', 'a <= b'); + + checkNegate('a>=1', 'a < 1'); + checkNegate('a>=1.1', 'a < 1.1'); + checkNegate('a>=b', 'a < b'); + + checkNegate('a<1', 'a >= 1'); + checkNegate('a<1.1', 'a >= 1.1'); + checkNegate('a= b'); + + checkNegate('a<=1', 'a > 1'); + checkNegate('a<=1.1', 'a > 1.1'); + checkNegate('a<=b', 'a > b'); + }); }); From 94dd681d16553f4e0940289f93eaa84a83054114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Wed, 2 Dec 2020 16:12:10 +0100 Subject: [PATCH 043/200] more fixes for #95697 --- src/vs/base/browser/ui/tree/abstractTree.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index f0e111e3f15..4df19745cfe 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1117,9 +1117,7 @@ class TreeNodeListMouseController extends MouseController< expandOnlyOnTwistieClick = !!this.tree.expandOnlyOnTwistieClick; } - const clickedOnFocus = this.tree.getFocus()[0] === node.element; - - if (expandOnlyOnTwistieClick && !onTwistie && e.browserEvent.detail !== 2 && !(clickedOnFocus && !node.collapsed)) { + if (expandOnlyOnTwistieClick && !onTwistie && e.browserEvent.detail !== 2) { return super.onViewPointer(e); } From f2ae4927f9419eebf6951564dc6b78b24c13905c Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 2 Dec 2020 16:18:31 +0100 Subject: [PATCH 044/200] update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c4a391eee6f..4f5198a1b1f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.52.0", - "distro": "7c9caf8254b4e707f8f7637661df05d1397f2181", + "distro": "525b7677232e7f810dd09678a784247f93df7845", "author": { "name": "Microsoft Corporation" }, @@ -197,4 +197,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} From e16d1f06d738ef620ded7a31e6a682e76017bd6d Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 2 Dec 2020 16:19:05 +0100 Subject: [PATCH 045/200] Add default URI if not provided in dialog API Fixes #111585 --- .../workbench/api/browser/mainThreadDialogs.ts | 16 ++++++++++++---- .../services/dialogs/browser/simpleFileDialog.ts | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadDialogs.ts b/src/vs/workbench/api/browser/mainThreadDialogs.ts index 938cb20c18b..afa4240f39e 100644 --- a/src/vs/workbench/api/browser/mainThreadDialogs.ts +++ b/src/vs/workbench/api/browser/mainThreadDialogs.ts @@ -23,12 +23,20 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape { // } - $showOpenDialog(options?: MainThreadDialogOpenOptions): Promise { - return Promise.resolve(this._fileDialogService.showOpenDialog(MainThreadDialogs._convertOpenOptions(options))); + async $showOpenDialog(options?: MainThreadDialogOpenOptions): Promise { + const convertedOptions = MainThreadDialogs._convertOpenOptions(options); + if (!convertedOptions.defaultUri) { + convertedOptions.defaultUri = await this._fileDialogService.defaultFilePath(); + } + return Promise.resolve(this._fileDialogService.showOpenDialog(convertedOptions)); } - $showSaveDialog(options?: MainThreadDialogSaveOptions): Promise { - return Promise.resolve(this._fileDialogService.showSaveDialog(MainThreadDialogs._convertSaveOptions(options))); + async $showSaveDialog(options?: MainThreadDialogSaveOptions): Promise { + const convertedOptions = MainThreadDialogs._convertSaveOptions(options); + if (!convertedOptions.defaultUri) { + convertedOptions.defaultUri = await this._fileDialogService.defaultFilePath(); + } + return Promise.resolve(this._fileDialogService.showSaveDialog(convertedOptions)); } private static _convertOpenOptions(options?: MainThreadDialogOpenOptions): IOpenDialogOptions { diff --git a/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts b/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts index ff3fe29fd60..e0eca9ebe37 100644 --- a/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts @@ -221,7 +221,7 @@ export class SimpleFileDialog { } private getScheme(available: readonly string[] | undefined, defaultUri: URI | undefined): string { - if (available) { + if (available && available.length > 0) { if (defaultUri && (available.indexOf(defaultUri.scheme) >= 0)) { return defaultUri.scheme; } From af29768f18350bdb9deb0cbf81982eddff285321 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 2 Dec 2020 16:18:56 +0100 Subject: [PATCH 046/200] Fix #110844 --- .../contrib/markers/browser/markersView.ts | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/markers/browser/markersView.ts b/src/vs/workbench/contrib/markers/browser/markersView.ts index 8e7ff32342c..8836c8371b2 100644 --- a/src/vs/workbench/contrib/markers/browser/markersView.ts +++ b/src/vs/workbench/contrib/markers/browser/markersView.ts @@ -54,6 +54,7 @@ import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/ur import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { groupBy } from 'vs/base/common/arrays'; import { ResourceMap } from 'vs/base/common/map'; +import { EditorResourceAccessor, SideBySideEditor } from 'vs/workbench/common/editor'; function createResourceMarkersIterator(resourceMarkers: ResourceMarkers): Iterable> { return Iterable.map(resourceMarkers.markers, m => { @@ -327,11 +328,15 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { } private setTreeSelection(): void { - if (this.tree && this.tree.getSelection().length === 0) { - const firstMarker = this.markersModel.resourceMarkers[0]?.markers[0]; - if (firstMarker) { - this.tree.setFocus([firstMarker]); - this.tree.setSelection([firstMarker]); + if (this.tree && this.tree.isVisible() && this.tree.getSelection().length === 0) { + const firstVisibleElement = this.tree.firstVisibleElement; + const marker = firstVisibleElement ? + firstVisibleElement instanceof ResourceMarkers ? firstVisibleElement.markers[0] : + firstVisibleElement instanceof Marker ? firstVisibleElement : undefined + : undefined; + if (marker) { + this.tree.setFocus([marker]); + this.tree.setSelection([marker]); } } } @@ -603,7 +608,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController { private setCurrentActiveEditor(): void { const activeEditor = this.editorService.activeEditor; - this.currentActiveResource = activeEditor ? withUndefinedAsNull(activeEditor.resource) : null; + this.currentActiveResource = activeEditor ? withUndefinedAsNull(EditorResourceAccessor.getOriginalUri(activeEditor, { supportSideBySide: SideBySideEditor.PRIMARY })) : null; } private onSelected(): void { @@ -946,6 +951,10 @@ class MarkersTree extends WorkbenchObjectTree { this.container.classList.toggle('hidden', hide); } + isVisible(): boolean { + return !this.container.classList.contains('hidden'); + } + } registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => { From 49ef641300f992f091af92605cc0a1d6366e3763 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 2 Dec 2020 16:27:53 +0100 Subject: [PATCH 047/200] fixes #111639 --- src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts index 7d0e8f2635e..f4ac30ca099 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts @@ -95,7 +95,7 @@ class CopyOperation implements IFileOperation { const stat = await this._workingCopyFileService.copy([{ source: this.oldUri, target: this.newUri }], { overwrite: this.options.overwrite, ...this.undoRedoInfo }, token); const folder = this.options.folder || (stat.length === 1 && stat[0].isDirectory); - return this._instaService.createInstance(DeleteOperation, this.newUri, { recursive: true, folder, ...this.options }, { isUndoing: true }, true); + return this._instaService.createInstance(DeleteOperation, this.newUri, { recursive: true, folder, ...this.options }, { isUndoing: true }, false); } toString(): string { From 97646e138af481ae7ec6bc794806cb88006f1ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Wed, 2 Dec 2020 16:31:21 +0100 Subject: [PATCH 048/200] workbench.tree.expandMode related to #95697 --- src/vs/platform/list/browser/listService.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 3bcc1cd12ad..b553a05811c 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -126,7 +126,7 @@ const automaticKeyboardNavigationSettingKey = 'workbench.list.automaticKeyboardN const treeIndentKey = 'workbench.tree.indent'; const treeRenderIndentGuidesKey = 'workbench.tree.renderIndentGuides'; const listSmoothScrolling = 'workbench.list.smoothScrolling'; -const treeExpandOnFolderClick = 'workbench.tree.expandOnFolderClick'; +const treeExpandMode = 'workbench.tree.expandMode'; function useAltAsMultipleSelectionModifier(configurationService: IConfigurationService): boolean { return configurationService.getValue(multiSelectModifierSettingKey) === 'alt'; @@ -849,7 +849,7 @@ function workbenchTreeDataPreamble(treeExpandOnFolderClick) + expandOnlyOnTwistieClick: options.expandOnlyOnTwistieClick ?? (configurationService.getValue<'singleClick' | 'doubleClick'>(treeExpandMode) === 'doubleClick') } as TOptions }; } @@ -951,8 +951,8 @@ class WorkbenchTreeInternals { if (e.affectsConfiguration(openModeSettingKey)) { newOptions = { ...newOptions, expandOnlyOnDoubleClick: configurationService.getValue(openModeSettingKey) === 'doubleClick' }; } - if (e.affectsConfiguration(treeExpandOnFolderClick) && options.expandOnlyOnTwistieClick === undefined) { - newOptions = { ...newOptions, expandOnlyOnTwistieClick: !configurationService.getValue(treeExpandOnFolderClick) }; + if (e.affectsConfiguration(treeExpandMode) && options.expandOnlyOnTwistieClick === undefined) { + newOptions = { ...newOptions, expandOnlyOnTwistieClick: configurationService.getValue<'singleClick' | 'doubleClick'>(treeExpandMode) === 'doubleClick' }; } if (Object.keys(newOptions).length > 0) { tree.updateOptions(newOptions); @@ -1058,10 +1058,11 @@ configurationRegistry.registerConfiguration({ 'default': true, markdownDescription: localize('automatic keyboard navigation setting', "Controls whether keyboard navigation in lists and trees is automatically triggered simply by typing. If set to `false`, keyboard navigation is only triggered when executing the `list.toggleKeyboardNavigation` command, for which you can assign a keyboard shortcut.") }, - [treeExpandOnFolderClick]: { - type: 'boolean', - default: true, - description: localize('list expand on folder click setting', "Controls whether tree folders are expanded when clicking the folder names."), + [treeExpandMode]: { + type: 'string', + enum: ['singleClick', 'doubleClick'], + default: 'singleClick', + description: localize('expand mode', "Controls how tree folders are expanded when clicking the folder names."), } } }); From 383dc83e7f61724717c274d850246eed5fcd7aee Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 2 Dec 2020 16:42:36 +0100 Subject: [PATCH 049/200] Fix the standalone editor build --- src/vs/editor/common/config/editorOptions.ts | 2 -- src/vs/monaco.d.ts | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 4a30547c6b1..1c6b481c702 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -266,12 +266,10 @@ export interface IEditorOptions { wordWrap?: 'off' | 'on' | 'wordWrapColumn' | 'bounded'; /** * Override the `wordWrap` setting. - * @internal */ wordWrapOverride1?: 'off' | 'on' | 'inherit'; /** * Override the `wordWrapOverride1` setting. - * @internal */ wordWrapOverride2?: 'off' | 'on' | 'inherit'; /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 85e7066269a..3aaef2a4771 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2811,6 +2811,14 @@ declare namespace monaco.editor { * Defaults to "off". */ wordWrap?: 'off' | 'on' | 'wordWrapColumn' | 'bounded'; + /** + * Override the `wordWrap` setting. + */ + wordWrapOverride1?: 'off' | 'on' | 'inherit'; + /** + * Override the `wordWrapOverride1` setting. + */ + wordWrapOverride2?: 'off' | 'on' | 'inherit'; /** * Control the wrapping of the editor. * When `wordWrap` = "off", the lines will never wrap. From 9cd45f96de363dbf86e8ce99c906ea0a892eaa93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Wed, 2 Dec 2020 16:43:48 +0100 Subject: [PATCH 050/200] fixes #111710 --- .../workbench/browser/actions/listCommands.ts | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/browser/actions/listCommands.ts b/src/vs/workbench/browser/actions/listCommands.ts index 5c8d8c70d1e..b71489ac38e 100644 --- a/src/vs/workbench/browser/actions/listCommands.ts +++ b/src/vs/workbench/browser/actions/listCommands.ts @@ -356,19 +356,13 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ // List if (focused instanceof List || focused instanceof PagedList) { - const list = focused; - - list.focusPreviousPage(); - list.reveal(list.getFocus()[0]); + focused.focusPreviousPage(); } // Tree else if (focused instanceof ObjectTree || focused instanceof DataTree || focused instanceof AsyncDataTree) { - const list = focused; - const fakeKeyboardEvent = new KeyboardEvent('keydown'); - list.focusPreviousPage(fakeKeyboardEvent); - list.reveal(list.getFocus()[0]); + focused.focusPreviousPage(fakeKeyboardEvent); } // Ensure DOM Focus @@ -386,19 +380,13 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ // List if (focused instanceof List || focused instanceof PagedList) { - const list = focused; - - list.focusNextPage(); - list.reveal(list.getFocus()[0]); + focused.focusNextPage(); } // Tree else if (focused instanceof ObjectTree || focused instanceof DataTree || focused instanceof AsyncDataTree) { - const list = focused; - const fakeKeyboardEvent = new KeyboardEvent('keydown'); - list.focusNextPage(fakeKeyboardEvent); - list.reveal(list.getFocus()[0]); + focused.focusNextPage(fakeKeyboardEvent); } // Ensure DOM Focus From bbdbcd333bdf449f86c1084bc96c92785e2e0b41 Mon Sep 17 00:00:00 2001 From: Eno Yao <2587575267@qq.com> Date: Wed, 2 Dec 2020 16:58:10 +0100 Subject: [PATCH 051/200] Update contextkey.ts --- src/vs/platform/contextkey/common/contextkey.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index 5b536419db9..e3d3599f614 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -7,6 +7,7 @@ import { Event } from 'vs/base/common/event'; import { isFalsyOrWhitespace } from 'vs/base/common/strings'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { isMacintosh, isLinux, isWindows, isWeb } from 'vs/base/common/platform'; +import { isEdge, isOpera, isFirefox, isWebKit, isChrome, isSafari, isWebkitWebView, isIPad, isEdgeWebView, isStandalone } from 'vs/base/browser/browser'; const STATIC_VALUES = new Map(); STATIC_VALUES.set('false', false); @@ -16,6 +17,16 @@ STATIC_VALUES.set('isLinux', isLinux); STATIC_VALUES.set('isWindows', isWindows); STATIC_VALUES.set('isWeb', isWeb); STATIC_VALUES.set('isMacNative', isMacintosh && !isWeb); +STATIC_VALUES.set('isEdge', isEdge); +STATIC_VALUES.set('isOpera', isOpera); +STATIC_VALUES.set('isFirefox', isFirefox); +STATIC_VALUES.set('isWebKit', isWebKit); +STATIC_VALUES.set('isChrome', isChrome); +STATIC_VALUES.set('isSafari', isSafari); +STATIC_VALUES.set('isWebkitWebView', isWebkitWebView); +STATIC_VALUES.set('isIPad', isIPad); +STATIC_VALUES.set('isEdgeWebView', isEdgeWebView); +STATIC_VALUES.set('isStandalone', isStandalone); const hasOwnProperty = Object.prototype.hasOwnProperty; From d79110a329157c9c726514790fe0b44b93a70570 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 2 Dec 2020 17:06:52 +0100 Subject: [PATCH 052/200] Avoid layer breaker --- .../platform/contextkey/common/contextkey.ts | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index e3d3599f614..d0f00ed362b 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -6,9 +6,9 @@ import { Event } from 'vs/base/common/event'; import { isFalsyOrWhitespace } from 'vs/base/common/strings'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { isMacintosh, isLinux, isWindows, isWeb } from 'vs/base/common/platform'; -import { isEdge, isOpera, isFirefox, isWebKit, isChrome, isSafari, isWebkitWebView, isIPad, isEdgeWebView, isStandalone } from 'vs/base/browser/browser'; +import { userAgent, isMacintosh, isLinux, isWindows, isWeb } from 'vs/base/common/platform'; +let _userAgent = userAgent || ''; const STATIC_VALUES = new Map(); STATIC_VALUES.set('false', false); STATIC_VALUES.set('true', true); @@ -17,16 +17,11 @@ STATIC_VALUES.set('isLinux', isLinux); STATIC_VALUES.set('isWindows', isWindows); STATIC_VALUES.set('isWeb', isWeb); STATIC_VALUES.set('isMacNative', isMacintosh && !isWeb); -STATIC_VALUES.set('isEdge', isEdge); -STATIC_VALUES.set('isOpera', isOpera); -STATIC_VALUES.set('isFirefox', isFirefox); -STATIC_VALUES.set('isWebKit', isWebKit); -STATIC_VALUES.set('isChrome', isChrome); -STATIC_VALUES.set('isSafari', isSafari); -STATIC_VALUES.set('isWebkitWebView', isWebkitWebView); -STATIC_VALUES.set('isIPad', isIPad); -STATIC_VALUES.set('isEdgeWebView', isEdgeWebView); -STATIC_VALUES.set('isStandalone', isStandalone); +STATIC_VALUES.set('isEdge', _userAgent.indexOf('Edg/') >= 0); +STATIC_VALUES.set('isFirefox', _userAgent.indexOf('Firefox') >= 0); +STATIC_VALUES.set('isChrome', _userAgent.indexOf('Chrome') >= 0); +STATIC_VALUES.set('isSafari', _userAgent.indexOf('Safari') >= 0); +STATIC_VALUES.set('isIPad', _userAgent.indexOf('iPad') >= 0); const hasOwnProperty = Object.prototype.hasOwnProperty; From df2c328e595101df8b96a7df17e3bd7349765d2a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 2 Dec 2020 17:23:57 +0100 Subject: [PATCH 053/200] string literal does not work with status bar item [background] color (fix #111687) --- src/vs/vscode.proposed.d.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 292af786ee1..19e8d8f1032 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -2307,12 +2307,12 @@ declare module 'vscode' { /** * The background color for this entry. * - * Note: the supported colors for background are currently limited to - * `ThemeColors` with id `statusBarItem.errorBackground`. Other `ThemeColors` - * will be ignored. + * Note: only `new ThemeColor('statusBarItem.errorBackground')` is + * supported for now. More background colors may be supported in the + * future. * - * When setting the background color to `statusBarItem.errorBackground`, the - * `color` property will automatically be set to `statusBarItem.errorForeground`. + * Note: when a background color is set, the statusbar may override + * the `color` choice to ensure the entry is readable in all themes. */ backgroundColor: ThemeColor | undefined; } From 0ac5e95251d92554d82a252420222834eec8e1c7 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 2 Dec 2020 17:48:16 +0100 Subject: [PATCH 054/200] Fix #109644 --- test/automation/src/keybindings.ts | 14 +++++++------- .../src/areas/preferences/preferences.test.ts | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/automation/src/keybindings.ts b/test/automation/src/keybindings.ts index 1de40d42bc9..4978ad09cd4 100644 --- a/test/automation/src/keybindings.ts +++ b/test/automation/src/keybindings.ts @@ -11,7 +11,7 @@ export class KeybindingsEditor { constructor(private code: Code) { } - async updateKeybinding(command: string, keybinding: string, title: string): Promise { + async updateKeybinding(command: string, commandName: string | undefined, keybinding: string, keybindingTitle: string): Promise { if (process.platform === 'darwin') { await this.code.dispatchKeybinding('cmd+k cmd+s'); } else { @@ -19,16 +19,16 @@ export class KeybindingsEditor { } await this.code.waitForActiveElement(SEARCH_INPUT); - await this.code.waitForSetValue(SEARCH_INPUT, command); + await this.code.waitForSetValue(SEARCH_INPUT, `@command:${command}`); - await this.code.waitAndClick('.keybindings-list-container .monaco-list-row.keybinding-item'); - await this.code.waitForElement('.keybindings-list-container .monaco-list-row.keybinding-item.focused.selected'); + const commandTitle = commandName ? `${commandName} (${command})` : command; + await this.code.waitAndClick(`.keybindings-list-container .monaco-list-row.keybinding-item .command span.monaco-highlighted-label[title="${commandTitle}"]`); + await this.code.waitForElement(`.keybindings-list-container .monaco-list-row.keybinding-item.focused.selected .command span.monaco-highlighted-label[title="${commandTitle}"]`); + await this.code.dispatchKeybinding('enter'); - await this.code.waitAndClick('.keybindings-list-container .monaco-list-row.keybinding-item .action-item .codicon-keybindings-add'); await this.code.waitForActiveElement('.defineKeybindingWidget .monaco-inputbox input'); - await this.code.dispatchKeybinding(keybinding); await this.code.dispatchKeybinding('enter'); - await this.code.waitForElement(`.keybindings-list-container .keybinding-label div[title="${title}"]`); + await this.code.waitForElement(`.keybindings-list-container .keybinding-label div[title="${keybindingTitle}"]`); } } diff --git a/test/smoke/src/areas/preferences/preferences.test.ts b/test/smoke/src/areas/preferences/preferences.test.ts index 1ea98dc7481..69652142369 100644 --- a/test/smoke/src/areas/preferences/preferences.test.ts +++ b/test/smoke/src/areas/preferences/preferences.test.ts @@ -22,7 +22,7 @@ export function setup() { const app = this.app as Application; await app.workbench.activitybar.waitForActivityBar(ActivityBarPosition.LEFT); - await app.workbench.keybindingsEditor.updateKeybinding('workbench.action.toggleSidebarPosition', 'ctrl+u', 'Control+U'); + await app.workbench.keybindingsEditor.updateKeybinding('workbench.action.toggleSidebarPosition', 'View: Toggle Side Bar Position', 'ctrl+u', 'Control+U'); await app.code.dispatchKeybinding('ctrl+u'); await app.workbench.activitybar.waitForActivityBar(ActivityBarPosition.RIGHT); From 2b179bff4ab1d305e095659ba0e4c736ebd03d38 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 2 Dec 2020 17:42:25 +0100 Subject: [PATCH 055/200] Extract `_undo`, `_redo` --- .../undoRedo/common/undoRedoService.ts | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/vs/platform/undoRedo/common/undoRedoService.ts b/src/vs/platform/undoRedo/common/undoRedoService.ts index 8246ccbf1be..70ead9becd0 100644 --- a/src/vs/platform/undoRedo/common/undoRedoService.ts +++ b/src/vs/platform/undoRedo/common/undoRedoService.ts @@ -811,7 +811,7 @@ export class UndoRedoService implements IUndoRedoService { if (element.canSplit()) { this._splitPastWorkspaceElement(element, ignoreResources); this._notificationService.info(message); - return new WorkspaceVerificationError(this.undo(strResource)); + return new WorkspaceVerificationError(this._undo(strResource)); } else { // Cannot safely split this workspace element => flush all undo/redo stacks for (const strResource of element.strResources) { @@ -959,7 +959,7 @@ export class UndoRedoService implements IUndoRedoService { if (result.choice === 1) { // choice: undo this file this._splitPastWorkspaceElement(element, null); - return this.undo(strResource); + return this._undo(strResource); } // choice: undo in all files @@ -1044,16 +1044,22 @@ export class UndoRedoService implements IUndoRedoService { const [, matchedStrResource] = this._findClosestUndoElementInGroup(groupId); if (matchedStrResource) { - return this.undo(matchedStrResource); + return this._undo(matchedStrResource); } } - public undo(resourceOrSource: URI | UndoRedoSource | string): Promise | void { + public undo(resourceOrSource: URI | UndoRedoSource): Promise | void { if (resourceOrSource instanceof UndoRedoSource) { const [, matchedStrResource] = this._findClosestUndoElementWithSource(resourceOrSource.id); - return matchedStrResource ? this.undo(matchedStrResource) : undefined; + return matchedStrResource ? this._undo(matchedStrResource) : undefined; } - const strResource = typeof resourceOrSource === 'string' ? resourceOrSource : this.getUriComparisonKey(resourceOrSource); + if (typeof resourceOrSource === 'string') { + return this._undo(resourceOrSource); + } + return this._undo(this.getUriComparisonKey(resourceOrSource)); + } + + private _undo(strResource: string): Promise | void { if (!this._editStacks.has(strResource)) { return; } @@ -1069,7 +1075,7 @@ export class UndoRedoService implements IUndoRedoService { const [matchedElement, matchedStrResource] = this._findClosestUndoElementInGroup(element.groupId); if (element !== matchedElement && matchedStrResource) { // there is an element in the same group that should be undone before this one - return this.undo(matchedStrResource); + return this._undo(matchedStrResource); } } @@ -1128,7 +1134,7 @@ export class UndoRedoService implements IUndoRedoService { if (element.canSplit()) { this._splitFutureWorkspaceElement(element, ignoreResources); this._notificationService.info(message); - return new WorkspaceVerificationError(this.redo(strResource)); + return new WorkspaceVerificationError(this._redo(strResource)); } else { // Cannot safely split this workspace element => flush all undo/redo stacks for (const strResource of element.strResources) { @@ -1300,16 +1306,22 @@ export class UndoRedoService implements IUndoRedoService { const [, matchedStrResource] = this._findClosestRedoElementInGroup(groupId); if (matchedStrResource) { - return this.redo(matchedStrResource); + return this._redo(matchedStrResource); } } public redo(resourceOrSource: URI | UndoRedoSource | string): Promise | void { if (resourceOrSource instanceof UndoRedoSource) { const [, matchedStrResource] = this._findClosestRedoElementWithSource(resourceOrSource.id); - return matchedStrResource ? this.redo(matchedStrResource) : undefined; + return matchedStrResource ? this._redo(matchedStrResource) : undefined; } - const strResource = typeof resourceOrSource === 'string' ? resourceOrSource : this.getUriComparisonKey(resourceOrSource); + if (typeof resourceOrSource === 'string') { + return this._redo(resourceOrSource); + } + return this._redo(this.getUriComparisonKey(resourceOrSource)); + } + + private _redo(strResource: string): Promise | void { if (!this._editStacks.has(strResource)) { return; } @@ -1325,7 +1337,7 @@ export class UndoRedoService implements IUndoRedoService { const [matchedElement, matchedStrResource] = this._findClosestRedoElementInGroup(element.groupId); if (element !== matchedElement && matchedStrResource) { // there is an element in the same group that should be redone before this one - return this.redo(matchedStrResource); + return this._redo(matchedStrResource); } } From 0db0fa8fc9676dd85a72956035659cc6671e47d8 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 2 Dec 2020 17:52:04 +0100 Subject: [PATCH 056/200] Prompt when hitting a different UndoRedoSrouce when undoing (#111640) --- .../undoRedo/common/undoRedoService.ts | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/undoRedo/common/undoRedoService.ts b/src/vs/platform/undoRedo/common/undoRedoService.ts index 70ead9becd0..2fb802fbce9 100644 --- a/src/vs/platform/undoRedo/common/undoRedoService.ts +++ b/src/vs/platform/undoRedo/common/undoRedoService.ts @@ -1051,7 +1051,7 @@ export class UndoRedoService implements IUndoRedoService { public undo(resourceOrSource: URI | UndoRedoSource): Promise | void { if (resourceOrSource instanceof UndoRedoSource) { const [, matchedStrResource] = this._findClosestUndoElementWithSource(resourceOrSource.id); - return matchedStrResource ? this._undo(matchedStrResource) : undefined; + return matchedStrResource ? this._undo(matchedStrResource, resourceOrSource.id) : undefined; } if (typeof resourceOrSource === 'string') { return this._undo(resourceOrSource); @@ -1059,7 +1059,7 @@ export class UndoRedoService implements IUndoRedoService { return this._undo(this.getUriComparisonKey(resourceOrSource)); } - private _undo(strResource: string): Promise | void { + private _undo(strResource: string, sourceId: number = 0): Promise | void { if (!this._editStacks.has(strResource)) { return; } @@ -1079,6 +1079,11 @@ export class UndoRedoService implements IUndoRedoService { } } + if (element.sourceId !== sourceId) { + // Hit a different source, prompt for confirmation + return this._confirmDifferentSourceAndContinueUndo(strResource, element); + } + try { if (element.type === UndoRedoElementType.Workspace) { return this._workspaceUndo(strResource, element); @@ -1092,6 +1097,28 @@ export class UndoRedoService implements IUndoRedoService { } } + private async _confirmDifferentSourceAndContinueUndo(strResource: string, element: StackElement): Promise { + const result = await this._dialogService.show( + Severity.Info, + nls.localize('confirmDifferentSource', "Would you like to undo '{0}'?", element.label), + [ + nls.localize('confirmDifferentSource.ok', "Undo"), + nls.localize('cancel', "Cancel"), + ], + { + cancelId: 1 + } + ); + + if (result.choice === 1) { + // choice: cancel + return; + } + + // choice: undo + return this._undo(strResource, element.sourceId); + } + private _findClosestRedoElementWithSource(sourceId: number): [StackElement | null, string | null] { if (!sourceId) { return [null, null]; From acaecbdc869c69794cbd28b802535ddfac602512 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 2 Dec 2020 17:56:53 +0100 Subject: [PATCH 057/200] fixes #111602 --- .../contrib/files/browser/fileActions.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 85ae6b84699..d26e1048b03 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -1303,24 +1303,24 @@ export const pasteFileHandler = async (accessor: ServicesAccessor) => { return { source: fileToPaste, target: targetFile }; })); - // Move/Copy File - if (pasteShouldMove) { - const resourceFileEdits = sourceTargetPairs.map(pair => new ResourceFileEdit(pair.source, pair.target)); - const options = { - progressLabel: sourceTargetPairs.length > 1 ? nls.localize('movingBulkEdit', "Moving {0} files", sourceTargetPairs.length) : nls.localize('movingFileBulkEdit', "Moving {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target)), - undoLabel: sourceTargetPairs.length > 1 ? nls.localize('moveBulkEdit', "Move {0} files", sourceTargetPairs.length) : nls.localize('moveFileBulkEdit', "Move {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target)) - }; - await explorerService.applyBulkEdit(resourceFileEdits, options); - } else { - const resourceFileEdits = sourceTargetPairs.map(pair => new ResourceFileEdit(pair.source, pair.target, { copy: true })); - const options = { - progressLabel: sourceTargetPairs.length > 1 ? nls.localize('copyingBulkEdit', "Copying {0} files", sourceTargetPairs.length) : nls.localize('copyingFileBulkEdit', "Copying {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target)), - undoLabel: sourceTargetPairs.length > 1 ? nls.localize('copyBulkEdit', "Copy {0} files", sourceTargetPairs.length) : nls.localize('copyFileBulkEdit', "Copy {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target)) - }; - await explorerService.applyBulkEdit(resourceFileEdits, options); - } - if (sourceTargetPairs.length >= 1) { + // Move/Copy File + if (pasteShouldMove) { + const resourceFileEdits = sourceTargetPairs.map(pair => new ResourceFileEdit(pair.source, pair.target)); + const options = { + progressLabel: sourceTargetPairs.length > 1 ? nls.localize('movingBulkEdit', "Moving {0} files", sourceTargetPairs.length) : nls.localize('movingFileBulkEdit', "Moving {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target)), + undoLabel: sourceTargetPairs.length > 1 ? nls.localize('moveBulkEdit', "Move {0} files", sourceTargetPairs.length) : nls.localize('moveFileBulkEdit', "Move {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target)) + }; + await explorerService.applyBulkEdit(resourceFileEdits, options); + } else { + const resourceFileEdits = sourceTargetPairs.map(pair => new ResourceFileEdit(pair.source, pair.target, { copy: true })); + const options = { + progressLabel: sourceTargetPairs.length > 1 ? nls.localize('copyingBulkEdit', "Copying {0} files", sourceTargetPairs.length) : nls.localize('copyingFileBulkEdit', "Copying {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target)), + undoLabel: sourceTargetPairs.length > 1 ? nls.localize('copyBulkEdit', "Copy {0} files", sourceTargetPairs.length) : nls.localize('copyFileBulkEdit', "Copy {0}", resources.basenameOrAuthority(sourceTargetPairs[0].target)) + }; + await explorerService.applyBulkEdit(resourceFileEdits, options); + } + const pair = sourceTargetPairs[0]; await explorerService.select(pair.target); if (sourceTargetPairs.length === 1) { From efd8b0141ecdcd4a8c499fd0c1f65b62ed3cc996 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 2 Dec 2020 18:01:42 +0100 Subject: [PATCH 058/200] explorer: update creation labels #111640 --- src/vs/workbench/contrib/files/browser/fileActions.ts | 4 ++-- .../workbench/contrib/files/browser/views/explorerViewer.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index d26e1048b03..6261006fef3 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -914,8 +914,8 @@ async function openExplorerAndCreate(accessor: ServicesAccessor, isFolder: boole try { const resourceToCreate = resources.joinPath(folder.resource, value); await explorerService.applyBulkEdit([new ResourceFileEdit(undefined, resourceToCreate, { folder: isFolder })], { - progressLabel: nls.localize('newBulkEdit', "New {0}", value), - undoLabel: nls.localize('newBulkEdit', "New {0}", value) + undoLabel: nls.localize('createBulkEdit', "Create {0}", value), + progressLabel: nls.localize('creatingBulkEdit', "Creating {0}", value) }); await refreshIfSeparator(value, explorerService); diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 9245c9733c7..f50916aee92 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -1074,7 +1074,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { } await this.explorerService.applyBulkEdit([new ResourceFileEdit(joinPath(target.resource, entry.name), undefined, { recursive: true })], { - undoLabel: localize('overwrite', "Overwriting {0}", entry.name), + undoLabel: localize('overwrite', "Overwrite {0}", entry.name), progressLabel: localize('overwriting', "Overwriting {0}", entry.name), }); From a2193cb8271ad3b9b2c1daff82a914aa9e4e2b1e Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 2 Dec 2020 10:10:21 -0800 Subject: [PATCH 059/200] fix #111714 --- .../src/features/smartSelect.ts | 8 ++-- .../src/test/smartSelect.test.ts | 39 ++++++++++++++++++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/extensions/markdown-language-features/src/features/smartSelect.ts b/extensions/markdown-language-features/src/features/smartSelect.ts index ae6b79faa34..12b2bdd78b3 100644 --- a/extensions/markdown-language-features/src/features/smartSelect.ts +++ b/extensions/markdown-language-features/src/features/smartSelect.ts @@ -34,7 +34,7 @@ export default class MarkdownSmartSelect implements vscode.SelectionRangeProvide const tokens = await this.engine.parse(document); - const blockTokens = getBlockTokensForPosition(tokens, position); + const blockTokens = getBlockTokensForPosition(tokens, position, headerRange); if (blockTokens.length === 0) { return undefined; @@ -91,13 +91,13 @@ function createHeaderRange(header: TocEntry, isClosestHeaderToPosition: boolean, // of this header then all content then header return new vscode.SelectionRange(contentRange.with(undefined, startOfChildRange), new vscode.SelectionRange(contentRange, (new vscode.SelectionRange(range, parent)))); } else { - // no children and not on this header line so select content then header + // not on this header line so select content then header return new vscode.SelectionRange(contentRange, new vscode.SelectionRange(range, parent)); } } -function getBlockTokensForPosition(tokens: Token[], position: vscode.Position): Token[] { - const enclosingTokens = tokens.filter(token => token.map && (token.map[0] <= position.line && token.map[1] > position.line) && isBlockElement(token)); +function getBlockTokensForPosition(tokens: Token[], position: vscode.Position, parent?: vscode.SelectionRange): Token[] { + const enclosingTokens = tokens.filter(token => token.map && (token.map[0] <= position.line && token.map[1] > position.line) && (!parent || (token.map[0] >= parent.range.start.line && token.map[1] <= parent.range.end.line + 1)) && isBlockElement(token)); if (enclosingTokens.length === 0) { return []; } diff --git a/extensions/markdown-language-features/src/test/smartSelect.test.ts b/extensions/markdown-language-features/src/test/smartSelect.test.ts index 15fb24e32ff..cb6b8a401e2 100644 --- a/extensions/markdown-language-features/src/test/smartSelect.test.ts +++ b/extensions/markdown-language-features/src/test/smartSelect.test.ts @@ -588,11 +588,48 @@ suite('markdown.SmartSelect', () => { )); assertNestedRangesEqual(ranges![0], [0, 27, 0, 48], [0, 25, 0, 50], [0, 12, 0, 63], [0, 11, 0, 64], [0, 0, 0, 75]); }); + test('Third level header from release notes', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `---`, + `Order: 60`, + `TOCTitle: October 2020`, + `PageTitle: Visual Studio Code October 2020`, + `MetaDescription: Learn what is new in the Visual Studio Code October 2020 Release (1.51)`, + `MetaSocialImage: 1_51/release-highlights.png`, + `Date: 2020-11-6`, + `DownloadVersion: 1.51.1`, + `---`, + `# October 2020 (version 1.51)`, + ``, + `**Update 1.51.1**: The update addresses these [issues](https://github.com/microsoft/vscode/issues?q=is%3Aissue+milestone%3A%22October+2020+Recovery%22+is%3Aclosed+).`, + ``, + ``, + ``, + `---`, + ``, + `Welcome to the October 2020 release of Visual Studio Code. As announced in the [October iteration plan](https://github.com/microsoft/vscode/issues/108473), we focused on housekeeping GitHub issues and pull requests as documented in our issue grooming guide.`, + ``, + `We also worked with our partners at GitHub on GitHub Codespaces, which ended up being more involved than originally anticipated. To that end, we'll continue working on housekeeping for part of the November iteration.`, + ``, + `During this housekeeping milestone, we also addressed several feature requests and community [pull requests](#thank-you). Read on to learn about new features and settings.`, + ``, + `## Workbench`, + ``, + `### More prominent pinned tabs`, + ``, + `${CURSOR}Pinned tabs will now always show their pin icon, even while inactive, to make them easier to identify. If an editor is both pinned and contains unsaved changes, the icon reflects both states.`, + ``, + `![Inactive pinned tabs showing pin icons](images/1_51/pinned-tabs.png)` + ) + ); + assertNestedRangesEqual(ranges![0], [27, 0, 27, 201], [26, 0, 29, 70], [25, 0, 29, 70], [24, 0, 29, 70], [23, 0, 29, 70], [10, 0, 29, 70], [9, 0, 29, 70]); + }); }); function assertNestedLineNumbersEqual(range: vscode.SelectionRange, ...expectedRanges: [number, number][]) { const lineage = getLineage(range); - assert.strictEqual(lineage.length, expectedRanges.length, `expected depth: ${expectedRanges.length}, but was ${lineage.length}`); + assert.strictEqual(lineage.length, expectedRanges.length, `expected depth: ${expectedRanges.length}, but was ${lineage.length} ${getValues(getLineage(range))}`); for (let i = 0; i < lineage.length; i++) { assertLineNumbersEqual(lineage[i], expectedRanges[i][0], expectedRanges[i][1], `parent at a depth of ${i}`); } From 4884986dd6c5c62a8b3f57779f92748e7662b686 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 2 Dec 2020 10:13:02 -0800 Subject: [PATCH 060/200] tweak smart select test --- .../markdown-language-features/src/test/smartSelect.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/markdown-language-features/src/test/smartSelect.test.ts b/extensions/markdown-language-features/src/test/smartSelect.test.ts index cb6b8a401e2..6e77d56c23c 100644 --- a/extensions/markdown-language-features/src/test/smartSelect.test.ts +++ b/extensions/markdown-language-features/src/test/smartSelect.test.ts @@ -629,7 +629,7 @@ suite('markdown.SmartSelect', () => { function assertNestedLineNumbersEqual(range: vscode.SelectionRange, ...expectedRanges: [number, number][]) { const lineage = getLineage(range); - assert.strictEqual(lineage.length, expectedRanges.length, `expected depth: ${expectedRanges.length}, but was ${lineage.length} ${getValues(getLineage(range))}`); + assert.strictEqual(lineage.length, expectedRanges.length, `expected depth: ${expectedRanges.length}, but was ${lineage.length} ${getValues(lineage)}`); for (let i = 0; i < lineage.length; i++) { assertLineNumbersEqual(lineage[i], expectedRanges[i][0], expectedRanges[i][1], `parent at a depth of ${i}`); } From a9100d686c431f3483e3ad081515b158fdbb6b84 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 2 Dec 2020 11:32:58 -0800 Subject: [PATCH 061/200] Update verification notebook milestone --- .vscode/notebooks/verification.github-issues | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/notebooks/verification.github-issues b/.vscode/notebooks/verification.github-issues index 67db0cb97d4..582859397ef 100644 --- a/.vscode/notebooks/verification.github-issues +++ b/.vscode/notebooks/verification.github-issues @@ -14,7 +14,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks \n$milestone=milestone:\"October 2020\"", + "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks \n$milestone=milestone:\"November 2020\"", "editable": true }, { From 44dafcc8408a3645e61b87af76e05c063b428f40 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 2 Dec 2020 20:48:44 +0100 Subject: [PATCH 062/200] Allow an `EncodedTokensProvider` to also provide a tokenize method --- .../standalone/browser/standaloneLanguages.ts | 25 ++++++++++++++----- src/vs/monaco.d.ts | 4 +++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 9bb40fa3750..dbf225a6c12 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -75,9 +75,11 @@ export function setLanguageConfiguration(languageId: string, configuration: Lang */ export class EncodedTokenizationSupport2Adapter implements modes.ITokenizationSupport { + private readonly _languageIdentifier: modes.LanguageIdentifier; private readonly _actual: EncodedTokensProvider; - constructor(actual: EncodedTokensProvider) { + constructor(languageIdentifier: modes.LanguageIdentifier, actual: EncodedTokensProvider) { + this._languageIdentifier = languageIdentifier; this._actual = actual; } @@ -86,6 +88,9 @@ export class EncodedTokenizationSupport2Adapter implements modes.ITokenizationSu } public tokenize(line: string, state: modes.IState, offsetDelta: number): TokenizationResult { + if (typeof this._actual.tokenize === 'function') { + return TokenizationSupport2Adapter.adaptTokenize(this._languageIdentifier.language, <{ tokenize(line: string, state: modes.IState): ILineTokens; }>this._actual, line, state, offsetDelta); + } throw new Error('Not supported!'); } @@ -114,7 +119,7 @@ export class TokenizationSupport2Adapter implements modes.ITokenizationSupport { return this._actual.getInitialState(); } - private _toClassicTokens(tokens: IToken[], language: string, offsetDelta: number): Token[] { + private static _toClassicTokens(tokens: IToken[], language: string, offsetDelta: number): Token[] { let result: Token[] = []; let previousStartIndex: number = 0; for (let i = 0, len = tokens.length; i < len; i++) { @@ -137,9 +142,9 @@ export class TokenizationSupport2Adapter implements modes.ITokenizationSupport { return result; } - public tokenize(line: string, state: modes.IState, offsetDelta: number): TokenizationResult { - let actualResult = this._actual.tokenize(line, state); - let tokens = this._toClassicTokens(actualResult.tokens, this._languageIdentifier.language, offsetDelta); + public static adaptTokenize(language: string, actual: { tokenize(line: string, state: modes.IState): ILineTokens; }, line: string, state: modes.IState, offsetDelta: number): TokenizationResult { + let actualResult = actual.tokenize(line, state); + let tokens = TokenizationSupport2Adapter._toClassicTokens(actualResult.tokens, language, offsetDelta); let endState: modes.IState; // try to save an object if possible @@ -152,6 +157,10 @@ export class TokenizationSupport2Adapter implements modes.ITokenizationSupport { return new TokenizationResult(tokens, endState); } + public tokenize(line: string, state: modes.IState, offsetDelta: number): TokenizationResult { + return TokenizationSupport2Adapter.adaptTokenize(this._languageIdentifier.language, this._actual, line, state, offsetDelta); + } + private _toBinaryTokens(tokens: IToken[], offsetDelta: number): Uint32Array { const languageId = this._languageIdentifier.id; const tokenTheme = this._standaloneThemeService.getColorTheme().tokenTheme; @@ -287,6 +296,10 @@ export interface EncodedTokensProvider { * Tokenize a line given the state at the beginning of the line. */ tokenizeEncoded(line: string, state: modes.IState): IEncodedLineTokens; + /** + * Tokenize a line given the state at the beginning of the line. + */ + tokenize?(line: string, state: modes.IState): ILineTokens; } function isEncodedTokensProvider(provider: TokensProvider | EncodedTokensProvider): provider is EncodedTokensProvider { @@ -307,7 +320,7 @@ export function setTokensProvider(languageId: string, provider: TokensProvider | } const create = (provider: TokensProvider | EncodedTokensProvider) => { if (isEncodedTokensProvider(provider)) { - return new EncodedTokenizationSupport2Adapter(provider); + return new EncodedTokenizationSupport2Adapter(languageIdentifier!, provider); } else { return new TokenizationSupport2Adapter(StaticServices.standaloneThemeService.get(), languageIdentifier!, provider); } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 3aaef2a4771..012344fa2da 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -5061,6 +5061,10 @@ declare namespace monaco.languages { * Tokenize a line given the state at the beginning of the line. */ tokenizeEncoded(line: string, state: IState): IEncodedLineTokens; + /** + * Tokenize a line given the state at the beginning of the line. + */ + tokenize?(line: string, state: IState): ILineTokens; } /** From 9d9ae54aa87749c07f83ff0687f7f2277297f1dc Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 2 Dec 2020 11:59:10 -0800 Subject: [PATCH 063/200] Add jpg to vscodeResources in order to bring gettingStarted images into the bundle --- build/gulpfile.vscode.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 6e556444fe1..1d02cbe067a 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -58,7 +58,7 @@ const vscodeResources = [ 'out-build/bootstrap-node.js', 'out-build/bootstrap-window.js', 'out-build/paths.js', - 'out-build/vs/**/*.{svg,png,html}', + 'out-build/vs/**/*.{svg,png,html,jpg}', '!out-build/vs/code/browser/**/*.html', '!out-build/vs/editor/standalone/**/*.svg', 'out-build/vs/base/common/performance.js', @@ -201,7 +201,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op const telemetry = gulp.src('.build/telemetry/**', { base: '.build/telemetry', dot: true }); - const jsFilter = util.filter(data => !data.isDirectory() &&/\.js$/.test(data.path)); + const jsFilter = util.filter(data => !data.isDirectory() && /\.js$/.test(data.path)); const root = path.resolve(path.join(__dirname, '..')); const dependenciesSrc = _.flatten(productionDependencies.map(d => path.relative(root, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`])); From b122603b86b17dc9f12883959338e1d645ddab5f Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Wed, 2 Dec 2020 12:21:03 -0800 Subject: [PATCH 064/200] Fix comment decoration weirdness, fixes https://github.com/microsoft/vscode-pull-request-github/issues/2309 --- src/vs/workbench/contrib/comments/browser/media/review.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/comments/browser/media/review.css b/src/vs/workbench/contrib/comments/browser/media/review.css index cfa7d955f41..da9c9f970d8 100644 --- a/src/vs/workbench/contrib/comments/browser/media/review.css +++ b/src/vs/workbench/contrib/comments/browser/media/review.css @@ -397,7 +397,7 @@ div.preview.inline .monaco-editor .comment-range-glyph { } .monaco-editor .margin-view-overlays > div:hover > .comment-range-glyph.comment-diff-added:before { - content: "💬"; + content: "+"; } .monaco-editor .comment-range-glyph.comment-thread { From 1fc36c35bb2468164e1c7722fbba9a94b397d08f Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 2 Dec 2020 13:32:56 -0800 Subject: [PATCH 065/200] remove extrenouus log fixes #111759 --- .../services/gettingStarted/common/gettingStartedService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/services/gettingStarted/common/gettingStartedService.ts b/src/vs/workbench/services/gettingStarted/common/gettingStartedService.ts index 6e0476e5ccc..243926c63d7 100644 --- a/src/vs/workbench/services/gettingStarted/common/gettingStartedService.ts +++ b/src/vs/workbench/services/gettingStarted/common/gettingStartedService.ts @@ -166,7 +166,6 @@ export class GettingStartedService implements IGettingStartedService { progressByEvent(event: string): void { const listening = this.eventListeners.get(event) ?? []; - console.log(event, listening, this.eventListeners); listening.forEach(id => this.progressTask(id)); } } From 253844006ab7159acdb6b8b34f175b12c4561567 Mon Sep 17 00:00:00 2001 From: rebornix Date: Wed, 2 Dec 2020 15:54:32 -0800 Subject: [PATCH 066/200] fix #111735. --- .../notebook/browser/contrib/find/findController.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/find/findController.ts b/src/vs/workbench/contrib/notebook/browser/contrib/find/findController.ts index fdabea9f6f1..2c2c46b895a 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/find/findController.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/find/findController.ts @@ -43,6 +43,7 @@ export class NotebookFindWidget extends SimpleFindReplaceWidget implements INote private _currentMatchDecorations: ICellModelDecorations[] = []; private _showTimeout: number | null = null; private _hideTimeout: number | null = null; + private _previousFocusElement?: HTMLElement; constructor( private readonly _notebookEditor: INotebookEditor, @@ -65,6 +66,10 @@ export class NotebookFindWidget extends SimpleFindReplaceWidget implements INote this._register(this._state.onFindReplaceStateChange(() => { this.onInputChanged(); })); + + this._register(DOM.addDisposableListener(this.getDomNode(), DOM.EventType.FOCUS, e => { + this._previousFocusElement = e.relatedTarget instanceof HTMLElement ? e.relatedTarget : undefined; + }, true)); } private _onFindInputKeyDown(e: IKeyboardEvent): void { @@ -167,6 +172,7 @@ export class NotebookFindWidget extends SimpleFindReplaceWidget implements INote } protected onFocusTrackerBlur() { + this._previousFocusElement = undefined; this._findWidgetFocused.reset(); } @@ -324,6 +330,11 @@ export class NotebookFindWidget extends SimpleFindReplaceWidget implements INote } else { // no op } + + if (this._previousFocusElement && this._previousFocusElement.offsetParent) { + this._previousFocusElement.focus(); + this._previousFocusElement = undefined; + } } clear() { From 5b121903fc01e4ca36e4eeefdb17cf37ceff95f8 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 2 Dec 2020 16:44:11 -0800 Subject: [PATCH 067/200] Fix issue preventing cells from leaving "running" state Fix #110973 --- .../contrib/notebook/browser/view/renderers/cellRenderer.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts index ecc1655a00f..2fccd56c7b9 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -1034,6 +1034,7 @@ export class RunStateRenderer { clear() { if (this.spinnerTimer) { clearTimeout(this.spinnerTimer); + this.spinnerTimer = undefined; } } From 5215161c8844ce4766cdbb39bd05efbd00371764 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 3 Dec 2020 00:49:27 +0000 Subject: [PATCH 068/200] fixes #108712 --- .../browser/parts/titlebar/menubarControl.ts | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 139b4530057..99fcf2b6ebe 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -11,7 +11,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IAction, Action, SubmenuAction, Separator } from 'vs/base/common/actions'; import * as DOM from 'vs/base/browser/dom'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { isMacintosh, isWeb, isIOS } from 'vs/base/common/platform'; +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'; @@ -199,13 +199,27 @@ export abstract class MenubarControl extends Disposable { if (event.affectsConfiguration('editor.accessibilitySupport')) { this.notifyUserOfCustomMenubarAccessibility(); } + + // Since we try not update when hidden, we should + // try to update the recently opened list on visibility changes + if (event.affectsConfiguration('window.menuBarVisibility')) { + this.onRecentlyOpenedChange(); + } + } + + private get menubarHidden(): boolean { + return isMacintosh && isNative ? false : getMenuBarVisibility(this.configurationService) === 'hidden'; } protected onRecentlyOpenedChange(): void { - this.workspacesService.getRecentlyOpened().then(recentlyOpened => { - this.recentlyOpened = recentlyOpened; - this.updateMenubar(); - }); + + // Do not update recently opened when the menubar is hidden #108712 + if (!this.menubarHidden) { + this.workspacesService.getRecentlyOpened().then(recentlyOpened => { + this.recentlyOpened = recentlyOpened; + this.updateMenubar(); + }); + } } private createOpenRecentMenuAction(recent: IRecent): IAction & { uri: URI } { From 2012817c0d2576dda7310981512064fd4667d2bd Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 2 Dec 2020 17:14:44 -0800 Subject: [PATCH 069/200] Fix #111699: workbench.startupEditor setting not showing Getting Started tab --- .../workbench/contrib/welcome/page/browser/welcomePage.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts index 4a6da704a94..37a7512d408 100644 --- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts @@ -105,7 +105,9 @@ export class WelcomePageContribution implements IWorkbenchContribution { }); } else { const startupEditorTypeID = startupEditorSetting === 'gettingStarted' ? gettingStartedInputTypeId : welcomeInputTypeId; - const startupEditorCtor = startupEditorSetting === 'gettingStarted' ? GettingStartedPage : WelcomePage; + const launchEditor = startupEditorSetting === 'gettingStarted' + ? instantiationService.createInstance(GettingStartedPage, {}) + : instantiationService.createInstance(WelcomePage); let options: IEditorOptions; let editor = editorService.activeEditor; @@ -118,7 +120,7 @@ export class WelcomePageContribution implements IWorkbenchContribution { } else { options = { pinned: false }; } - return instantiationService.createInstance(startupEditorCtor).openEditor(options); + return launchEditor.openEditor(options); } } return undefined; From af63e8263a14d7e1a1d469a51d5476502931806b Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 2 Dec 2020 17:27:22 -0800 Subject: [PATCH 070/200] Fix #111706: Getting started: images need alt text --- .../gettingStarted/browser/gettingStarted.ts | 6 +++++- .../gettingStarted/common/gettingStartedContent.ts | 14 +++++++------- .../common/gettingStartedRegistry.ts | 12 ++++++++---- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts index ad2d3527c2a..1eeb91b1558 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts @@ -176,11 +176,15 @@ export class GettingStartedPage extends Disposable { } this.editorInput.selectedTask = id; const taskToExpand = assertIsDefined(this.currentCategory.content.items.find(task => task.id === id)); - mediaElement.setAttribute('src', taskToExpand.media.toString()); + console.log(taskToExpand.media.path, taskToExpand.media.path.toString()); + + mediaElement.setAttribute('src', taskToExpand.media.path.toString()); + mediaElement.setAttribute('alt', taskToExpand.media.altText); taskElement.parentElement?.querySelectorAll('.expanded').forEach(node => node.classList.remove('expanded')); taskElement.classList.add('expanded'); } else { mediaElement.setAttribute('src', ''); + mediaElement.setAttribute('alt', ''); } } diff --git a/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts b/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts index 65d59be4589..64e01b6746b 100644 --- a/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts +++ b/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts @@ -12,7 +12,7 @@ type GettingStartedItem = { button: { title: string, command: string }, doneOn: { commandExecuted: string, eventFired?: never } | { eventFired: string, commandExecuted?: never, } when?: string, - media: string, + media: { type: 'image', path: string, altText: string }, }; type GettingStartedCategory = { @@ -43,7 +43,7 @@ export const content: GettingStartedContent = [ title: localize('pickColorTask.title', "Color Theme"), button: { title: localize('pickColorTask.button', "Find a Theme"), command: 'workbench.action.selectTheme' }, doneOn: { eventFired: 'themeSelected' }, - media: 'ColorTheme.jpg' + media: { type: 'image', altText: 'ColorTheme', path: 'ColorTheme.jpg', } }, { @@ -55,7 +55,7 @@ export const content: GettingStartedContent = [ command: 'workbench.extensions.action.showRecommendedKeymapExtensions' }, doneOn: { commandExecuted: 'workbench.extensions.action.showRecommendedKeymapExtensions' }, - media: 'Extensions.jpg', + media: { type: 'image', altText: 'Extensions', path: 'Extensions.jpg', } }, { @@ -67,7 +67,7 @@ export const content: GettingStartedContent = [ command: 'workbench.extensions.action.showLanguageExtensions', }, doneOn: { commandExecuted: 'workbench.extensions.action.showLanguageExtensions' }, - media: 'Languages.jpg', + media: { type: 'image', altText: 'Languages', path: 'Languages.jpg', } }, { @@ -80,7 +80,7 @@ export const content: GettingStartedContent = [ command: 'workbench.action.files.openFileFolder' }, doneOn: { commandExecuted: 'workbench.action.files.openFileFolder' }, - media: 'OpenFolder.jpg' + media: { type: 'image', altText: 'OpenFolder', path: 'OpenFolder.jpg' } }, { @@ -93,7 +93,7 @@ export const content: GettingStartedContent = [ command: 'workbench.action.files.openFolder' }, doneOn: { commandExecuted: 'workbench.action.files.openFolder' }, - media: 'OpenFolder.png' + media: { type: 'image', altText: 'OpenFolder', path: 'OpenFolder.jpg' } } ] } @@ -116,7 +116,7 @@ export const content: GettingStartedContent = [ command: 'workbench.action.showCommands' }, doneOn: { commandExecuted: 'workbench.action.showCommands' }, - media: 'https://code.visualstudio.com/assets/updates/1_51/custom-tree-hover.gif', + media: { type: 'image', altText: 'gif of a custom tree hover', path: 'https://code.visualstudio.com/assets/updates/1_51/custom-tree-hover.gif' }, } ] } diff --git a/src/vs/workbench/services/gettingStarted/common/gettingStartedRegistry.ts b/src/vs/workbench/services/gettingStarted/common/gettingStartedRegistry.ts index ace92e7ef45..5272c631147 100644 --- a/src/vs/workbench/services/gettingStarted/common/gettingStartedRegistry.ts +++ b/src/vs/workbench/services/gettingStarted/common/gettingStartedRegistry.ts @@ -25,7 +25,7 @@ export interface IGettingStartedTask { order: number, button: { title: string, command: string }, doneOn: { commandExecuted: string, eventFired?: never } | { eventFired: string, commandExecuted?: never, } - media: URI + media: { type: 'image', path: URI, altText: string }, } export interface IGettingStartedCategoryDescriptor { @@ -134,9 +134,13 @@ content.forEach(category => { category: category.id, order: index, when: ContextKeyExpr.deserialize(item.when) ?? ContextKeyExpr.true(), - media: item.media.startsWith('https://') - ? URI.parse(item.media, true) - : FileAccess.asFileUri('vs/workbench/services/gettingStarted/common/media/' + item.media, require) + media: { + type: item.media.type, + altText: item.media.altText, + path: item.media.path.startsWith('https://') + ? URI.parse(item.media.path, true) + : FileAccess.asFileUri('vs/workbench/services/gettingStarted/common/media/' + item.media.path, require) + } }); }); } From f603b548c5b98e0de999d9a11ba438eed18b517e Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 2 Dec 2020 17:48:52 -0800 Subject: [PATCH 071/200] Polish getting started styles (#111774) * Polish getting started styling * Update margins for task description --- .../gettingStarted/browser/gettingStarted.css | 98 +++++++++---------- .../gettingStarted/browser/gettingStarted.ts | 2 +- .../browser/vs_code_editor_getting_started.ts | 7 +- 3 files changed, 50 insertions(+), 57 deletions(-) diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css index 8e16b49a24c..766c3af7ccd 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css @@ -17,16 +17,15 @@ } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .header { - text-align: center; -} - -.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .title { - display: inline-block; + margin-top: 32px; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .category-title { - margin-top: 6px; - margin-bottom: 2px; + margin-bottom: 4px; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .category-description-container { @@ -34,12 +33,12 @@ } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .category-description { - font-size: 12pt; + font-size: 12px; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .category-progress { - margin-top: 6px; - font-size: 8pt; + margin-top: 12px; + font-size: 12px; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories progress { @@ -51,14 +50,13 @@ display: flex; flex-wrap: wrap; justify-content: center; - width: 70%; max-width: 900px; - margin: 20px auto; + margin: 32px auto; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide .getting-started-category { width: 330px; - min-height: 100px; + min-height: 80px; text-align: left; display: flex; } @@ -68,21 +66,20 @@ } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide .getting-started-category .codicon { - margin: 10px 8px 0 0; + margin-right: 10px; font-size: 32px; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-category { width: 330px; - height: 100px; display: flex; + padding: 40px 0 20px; margin-left: 12px; - + min-height: auto; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-category .codicon { margin-left:0; - margin-top: 28px; font-size: 22pt; } @@ -94,34 +91,35 @@ } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task { + display: flex; width: 100%; - height: 26pt; overflow: hidden; } +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task:not(.expanded) .task-description, +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task:not(.expanded) button, +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task:not(.expanded) a { + display: none; +} + .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task.expanded { width: 100%; height: unset; } -.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task .task-description-container { - padding-left: 30px; - padding-right: 4px; -} - .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task .task-title { - margin-bottom: 4px; font-size: 14pt; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task .task-description { - font-size: 11pt; + margin-top: 4px; + font-size: 13px; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task .task-next { float: right; - margin-top: 16px; + margin-top: 24px; margin-right: 25px; } @@ -130,15 +128,12 @@ } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task .codicon { - float: left; - font-size: 20pt; - position: relative; - top: -4px; - left: -1px; + margin-right: 8px; + font-size: 20px; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task-action { - margin: 10px 0 0; + margin: 20px 0 0; padding: 4px 8px; font-size: 11pt; min-width: 100px; @@ -146,7 +141,7 @@ .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail #getting-started-detail-left { min-width: 330px; - width: 33%; + width: 40%; max-width: 400px; } @@ -162,7 +157,15 @@ margin: 10px; color: inherit; text-align: left; - padding: 10px; + padding: 16px; +} + +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer button:hover { + cursor: pointer; +} + +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer button:focus { + outline-style: solid; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .prev-button { @@ -177,16 +180,6 @@ top: 2px; } -.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide .product-icon { - background-image: url('../../../../browser/media/code-icon.svg'); - width: 75px; - height: 75px; - background-size: contain; - display: inline-block; - margin-right: 20px; -} - - .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide .skip { display: block; width: 150px; @@ -195,25 +188,28 @@ } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide h1 { - font-size: 32pt; + font-size: 32px; font-weight: normal; border-bottom: none; - margin-bottom: 0; + margin: 0; + padding: 0; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide h2 { font-weight: normal; + margin: 0 0 4px 0; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide h3 { - font-weight: normal; - margin-top: 0; - margin-bottom: 0; + font-size: 18px; + font-weight: bold; + margin: 0; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide .subtitle { - font-size: 18pt; - margin-top: 0; + font-size: 16px; + margin: 0; + padding: 0; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .footer { diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts index 1eeb91b1558..fbdb9a257e3 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts @@ -288,7 +288,7 @@ export class GettingStartedPage extends Disposable { const categoryElements = category.content.items.map( (task, i, arr) => $('button.getting-started-task', { 'x-dispatch': 'selectTask:' + task.id, id: 'getting-started-task-' + task.id }, - $('.codicon' + (task.done ? '.codicon-star-full' : '.codicon-star-empty'), { id: 'done-task-' + task.id }), + $('.codicon' + (task.done ? '.codicon-pass-filled' : '.codicon-circle-large-outline'), { id: 'done-task-' + task.id }), $('.task-description-container', {}, $('h3.task-title', {}, task.title), $('.task-description.description', {}, task.description), diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/vs_code_editor_getting_started.ts b/src/vs/workbench/contrib/welcome/gettingStarted/browser/vs_code_editor_getting_started.ts index d002501a8ef..f823a50031c 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/vs_code_editor_getting_started.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/vs_code_editor_getting_started.ts @@ -11,11 +11,8 @@ export default () => `
-
-
-

${escape(localize('gettingStarted.vscode', "Visual Studio Code"))}

-

${escape(localize({ key: 'gettingStarted.editingRedefined', comment: ['Shown as subtitle on the Welcome page.'] }, "Code editing. Redefined"))}

-
+

${escape(localize('gettingStarted.vscode', "Visual Studio Code"))}

+

${escape(localize({ key: 'gettingStarted.editingRedefined', comment: ['Shown as subtitle on the Welcome page.'] }, "Code editing. Redefined"))}

From 92192baf760315ac47fb2caaf3ce6d0778962352 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Wed, 2 Dec 2020 19:56:11 -0800 Subject: [PATCH 072/200] Bring content closer to center vertical when space permitting Ref #111753 --- .../welcome/gettingStarted/browser/gettingStarted.css | 10 ++++++++++ .../browser/vs_code_editor_getting_started.ts | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css index 766c3af7ccd..f41c4c53565 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css @@ -16,6 +16,16 @@ left: 0; } +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories { + height: calc(100% - 50px); + display: flex; + flex-direction: column; +} + +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .gap { + flex: 150px 0 1 +} + .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .header { margin-top: 32px; display: flex; diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/vs_code_editor_getting_started.ts b/src/vs/workbench/contrib/welcome/gettingStarted/browser/vs_code_editor_getting_started.ts index f823a50031c..dd62545272f 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/vs_code_editor_getting_started.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/vs_code_editor_getting_started.ts @@ -10,11 +10,13 @@ export default () => `
+

${escape(localize('gettingStarted.vscode', "Visual Studio Code"))}

${escape(localize({ key: 'gettingStarted.editingRedefined', comment: ['Shown as subtitle on the Welcome page.'] }, "Code editing. Redefined"))}

+
Date: Wed, 2 Dec 2020 21:50:52 -0800 Subject: [PATCH 073/200] Slightly darken list active bg on light theme (fixes #111750) --- src/vs/platform/theme/common/colorRegistry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 70f67e0f33e..b5239353a96 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -358,7 +358,7 @@ export const diffDiagonalFill = registerColor('diffEditor.diagonalFill', { dark: */ export const listFocusBackground = registerColor('list.focusBackground', { dark: '#062F4A', light: '#D6EBFF', hc: null }, nls.localize('listFocusBackground', "List/Tree background color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listFocusForeground = registerColor('list.focusForeground', { dark: null, light: null, hc: null }, nls.localize('listFocusForeground', "List/Tree foreground color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); -export const listActiveSelectionBackground = registerColor('list.activeSelectionBackground', { dark: '#094771', light: '#0074E8', hc: null }, nls.localize('listActiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); +export const listActiveSelectionBackground = registerColor('list.activeSelectionBackground', { dark: '#094771', light: '#0060C0', hc: null }, nls.localize('listActiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listActiveSelectionForeground = registerColor('list.activeSelectionForeground', { dark: Color.white, light: Color.white, hc: null }, nls.localize('listActiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listInactiveSelectionBackground = registerColor('list.inactiveSelectionBackground', { dark: '#37373D', light: '#E4E6F1', hc: null }, nls.localize('listInactiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); export const listInactiveSelectionForeground = registerColor('list.inactiveSelectionForeground', { dark: null, light: null, hc: null }, nls.localize('listInactiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); From 4f33022639f6bb6db626520939f58a0dc6de6a92 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 3 Dec 2020 09:50:46 +0100 Subject: [PATCH 074/200] add verification query for issues from non-vscode team members --- .vscode/notebooks/my-endgame.github-issues | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.vscode/notebooks/my-endgame.github-issues b/.vscode/notebooks/my-endgame.github-issues index 402ef474e56..5222481a470 100644 --- a/.vscode/notebooks/my-endgame.github-issues +++ b/.vscode/notebooks/my-endgame.github-issues @@ -182,7 +182,7 @@ { "kind": 1, "language": "markdown", - "value": "## Issues filed by others", + "value": "## Issues filed by VSCode members", "editable": true }, { @@ -191,6 +191,18 @@ "value": "$REPOS $MILESTONE -$MINE is:issue is:closed -author:@me sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found", "editable": true }, + { + "kind": 1, + "language": "markdown", + "value": "## Issues filed by others", + "editable": true + }, + { + "kind": 2, + "language": "github-issues", + "value": "$REPOS $MILESTONE -$MINE is:issue is:closed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -author:aeschli, -author:alexdima, -author:alexr00, -author:AmandaSilver, -author:bamurtaugh, -author:bpasero, -author:btholt, -author:chrisdias, -author:chrmarti, -author:Chuxel, -author:connor4312, -author:dbaeumer, -author:deepak1556, -author:devinvalenciano, -author:digitarald, -author:eamodio, -author:egamma, -author:fiveisprime, -author:gregvanl, -author:isidorn, -author:ItalyPaleAle, -author:JacksonKearl, -author:joaomoreno, -author:jrieken, -author:kieferrm, -author:lszomoru, -author:meganrogge, -author:misolori, -author:mjbvz, -author:ornellaalt, -author:orta, -author:rebornix, -author:RMacfarlane, -author:roblourens, -author:rzhao271, -author:sana-ajani, -author:sandy081, -author:sbatten, -author:stevencl, -author:Tyriar, -author:weinand", + "editable": true + }, { "kind": 1, "language": "markdown", From 0ea221b3252e5e25da182eeec3bbee78f6f18912 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 3 Dec 2020 09:52:37 +0100 Subject: [PATCH 075/200] fix query, remove commas --- .vscode/notebooks/my-endgame.github-issues | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.vscode/notebooks/my-endgame.github-issues b/.vscode/notebooks/my-endgame.github-issues index 5222481a470..eb8380541ac 100644 --- a/.vscode/notebooks/my-endgame.github-issues +++ b/.vscode/notebooks/my-endgame.github-issues @@ -182,13 +182,13 @@ { "kind": 1, "language": "markdown", - "value": "## Issues filed by VSCode members", + "value": "## Issues filed from outside team", "editable": true }, { "kind": 2, "language": "github-issues", - "value": "$REPOS $MILESTONE -$MINE is:issue is:closed -author:@me sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found", + "value": "$REPOS $MILESTONE -$MINE is:issue is:closed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -author:aeschli -author:alexdima -author:alexr00 -author:AmandaSilver -author:bamurtaugh -author:bpasero -author:btholt -author:chrisdias -author:chrmarti -author:Chuxel -author:connor4312 -author:dbaeumer -author:deepak1556 -author:devinvalenciano -author:digitarald -author:eamodio -author:egamma -author:fiveisprime -author:gregvanl -author:isidorn -author:ItalyPaleAle -author:JacksonKearl -author:joaomoreno -author:jrieken -author:kieferrm -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:ornellaalt -author:orta -author:rebornix -author:RMacfarlane -author:roblourens -author:rzhao271 -author:sana-ajani -author:sandy081 -author:sbatten -author:stevencl -author:Tyriar -author:weinand", "editable": true }, { @@ -200,7 +200,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS $MILESTONE -$MINE is:issue is:closed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -author:aeschli, -author:alexdima, -author:alexr00, -author:AmandaSilver, -author:bamurtaugh, -author:bpasero, -author:btholt, -author:chrisdias, -author:chrmarti, -author:Chuxel, -author:connor4312, -author:dbaeumer, -author:deepak1556, -author:devinvalenciano, -author:digitarald, -author:eamodio, -author:egamma, -author:fiveisprime, -author:gregvanl, -author:isidorn, -author:ItalyPaleAle, -author:JacksonKearl, -author:joaomoreno, -author:jrieken, -author:kieferrm, -author:lszomoru, -author:meganrogge, -author:misolori, -author:mjbvz, -author:ornellaalt, -author:orta, -author:rebornix, -author:RMacfarlane, -author:roblourens, -author:rzhao271, -author:sana-ajani, -author:sandy081, -author:sbatten, -author:stevencl, -author:Tyriar, -author:weinand", + "value": "$REPOS $MILESTONE -$MINE is:issue is:closed -author:@me sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found", "editable": true }, { From 4095701c702325729497b077713177ac13913cd3 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru Date: Thu, 3 Dec 2020 10:40:32 +0100 Subject: [PATCH 076/200] Exclude endgame-plan issues from query --- .vscode/notebooks/my-endgame.github-issues | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/notebooks/my-endgame.github-issues b/.vscode/notebooks/my-endgame.github-issues index eb8380541ac..54ec5328eba 100644 --- a/.vscode/notebooks/my-endgame.github-issues +++ b/.vscode/notebooks/my-endgame.github-issues @@ -122,7 +122,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS $MILESTONE $MINE is:issue is:open", + "value": "$REPOS $MILESTONE $MINE is:issue is:open -label:endgame-plan", "editable": true }, { From 09a7ad2ae7f34f1cfbfb145e8b5d87fb1b752abf Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 3 Dec 2020 11:23:22 +0100 Subject: [PATCH 077/200] fix raw timers telemetry event --- .../services/timer/browser/timerService.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/services/timer/browser/timerService.ts b/src/vs/workbench/services/timer/browser/timerService.ts index 0dab9f40ed0..53ad8e85e5f 100644 --- a/src/vs/workbench/services/timer/browser/timerService.ts +++ b/src/vs/workbench/services/timer/browser/timerService.ts @@ -375,16 +375,9 @@ export abstract class AbstractTimerService implements ITimerService { this._telemetryService.publicLog('startupTimeVaried', metrics); // report raw timers as telemetry - const entries: Record = Object.create(null); - for (const entry of perf.getEntries()) { - entries[entry.name] = entry.startTime; - } - /* __GDPR__ - "startupRawTimers" : { - "entries": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } - } - */ - this._telemetryService.publicLog('startupRawTimers', { entries }); + type Durations = { entries: string; }; + type DurationsClassification = { entries: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' } }; + this._telemetryService.publicLog2('startup.timers.raw', { entries: JSON.stringify(perf.getEntries()) }); } private async _computeStartupMetrics(): Promise { From 87e43299ade57a5e2d0db24c38842c84f3cf5269 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Thu, 3 Dec 2020 12:46:02 +0100 Subject: [PATCH 078/200] update DAP to 1.43 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 4f5198a1b1f..faabdc484fd 100644 --- a/package.json +++ b/package.json @@ -176,7 +176,7 @@ "vinyl": "^2.0.0", "vinyl-fs": "^3.0.0", "vsce": "1.48.0", - "vscode-debugprotocol": "1.41.0", + "vscode-debugprotocol": "1.43.0", "vscode-nls-dev": "^3.3.1", "webpack": "^4.43.0", "webpack-cli": "^3.3.12", diff --git a/yarn.lock b/yarn.lock index 2ea65eb0188..dd5e3e4eea8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10010,10 +10010,10 @@ vsce@1.48.0: yauzl "^2.3.1" yazl "^2.2.2" -vscode-debugprotocol@1.41.0: - version "1.41.0" - resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.41.0.tgz#fc99b01dee26e9f25cbb5708318fc0081002808c" - integrity sha512-Sxp7kDDuhpEZiDaIfhM0jLF3RtMqvc6CpoESANE77t351uezsd/oDoqALLcOnmmsDzTgQ3W0sCvM4gErnjDFpA== +vscode-debugprotocol@1.43.0: + version "1.43.0" + resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.43.0.tgz#fe5bcfa7021c250e78c3cf203d392e98b5de268c" + integrity sha512-pnj+9wVS3yPYz/RXoYSN1tCv+D4139ueaY2WC7V6fUd9QZU8IE5s4r/lZUMJ9gAEGz2km/Iv4qcI7Fdlz5xS9w== vscode-nls-dev@^3.3.1: version "3.3.1" From 07333dec483e7784ebecd73739db7f08314109fc Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Thu, 3 Dec 2020 12:49:38 +0100 Subject: [PATCH 079/200] node-debug@1.44.15 --- product.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product.json b/product.json index f62018b387c..d413a31fc43 100644 --- a/product.json +++ b/product.json @@ -31,7 +31,7 @@ "builtInExtensions": [ { "name": "ms-vscode.node-debug", - "version": "1.44.14", + "version": "1.44.15", "repo": "https://github.com/microsoft/vscode-node-debug", "metadata": { "id": "b6ded8fb-a0a0-4c1c-acbd-ab2a3bc995a6", From 79fb30f5b6d33cdbc5886accfa7a69afa15d237a Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 3 Dec 2020 14:45:27 +0100 Subject: [PATCH 080/200] Fix resolveTreeItem called twice Fixes #111749 --- src/vs/base/browser/ui/iconLabel/iconLabel.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vs/base/browser/ui/iconLabel/iconLabel.ts b/src/vs/base/browser/ui/iconLabel/iconLabel.ts index 9f87da0c342..44c56834ff0 100644 --- a/src/vs/base/browser/ui/iconLabel/iconLabel.ts +++ b/src/vs/base/browser/ui/iconLabel/iconLabel.ts @@ -206,16 +206,23 @@ export class IconLabel extends Disposable { const hoverDelay = isMacintosh ? 1500 : 500; let hoverOptions: IHoverDelegateOptions | undefined; let mouseX: number | undefined; + let isHovering = false; function mouseOver(this: HTMLElement, e: MouseEvent): any { - let isHovering = true; - function mouseMove(this: HTMLElement, e: MouseEvent): any { - mouseX = e.x; + if (isHovering) { + return; } function mouseLeaveOrDown(this: HTMLElement, e: MouseEvent): any { isHovering = false; + mouseLeaveDisposable.dispose(); + mouseDownDisposable.dispose(); } const mouseLeaveDisposable = domEvent(htmlElement, dom.EventType.MOUSE_LEAVE, true)(mouseLeaveOrDown.bind(htmlElement)); const mouseDownDisposable = domEvent(htmlElement, dom.EventType.MOUSE_DOWN, true)(mouseLeaveOrDown.bind(htmlElement)); + isHovering = true; + + function mouseMove(this: HTMLElement, e: MouseEvent): any { + mouseX = e.x; + } const mouseMoveDisposable = domEvent(htmlElement, dom.EventType.MOUSE_MOVE, true)(mouseMove.bind(htmlElement)); setTimeout(async () => { if (isHovering && tooltip) { @@ -234,7 +241,8 @@ export class IconLabel extends Disposable { }; } } - if (hoverOptions) { + // awaiting the tooltip could take a while. Make sure we're still hovering. + if (hoverOptions && isHovering) { if (mouseX !== undefined) { (hoverOptions.target).x = mouseX + 10; } @@ -242,8 +250,6 @@ export class IconLabel extends Disposable { } } mouseMoveDisposable.dispose(); - mouseLeaveDisposable.dispose(); - mouseDownDisposable.dispose(); }, hoverDelay); } const mouseOverDisposable = this._register(domEvent(htmlElement, dom.EventType.MOUSE_OVER, true)(mouseOver.bind(htmlElement))); From 044741569781be2f5842ae01bb5ceba4b26f1cc3 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 3 Dec 2020 15:18:59 +0100 Subject: [PATCH 081/200] Hide the editor's cursor when doing composition (fixes #106663) --- .../browser/controller/textAreaHandler.ts | 2 ++ .../viewParts/viewCursors/viewCursors.ts | 17 ++++++++++++++++- src/vs/editor/common/view/viewEvents.ts | 16 +++++++++++++++- .../common/viewModel/viewEventHandler.ts | 19 ++++++++++++++++++- src/vs/editor/common/viewModel/viewModel.ts | 2 ++ .../editor/common/viewModel/viewModelImpl.ts | 8 ++++++++ 6 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/browser/controller/textAreaHandler.ts b/src/vs/editor/browser/controller/textAreaHandler.ts index 07eadee8415..2f26618aa4b 100644 --- a/src/vs/editor/browser/controller/textAreaHandler.ts +++ b/src/vs/editor/browser/controller/textAreaHandler.ts @@ -276,6 +276,7 @@ export class TextAreaHandler extends ViewPart { this.textArea.setClassName(`inputarea ${MOUSE_CURSOR_TEXT_CSS_CLASS_NAME} ime-input`); this._viewController.compositionStart(); + this._context.model.onCompositionStart(); })); this._register(this._textAreaInput.onCompositionUpdate((e: ICompositionData) => { @@ -297,6 +298,7 @@ export class TextAreaHandler extends ViewPart { this.textArea.setClassName(`inputarea ${MOUSE_CURSOR_TEXT_CSS_CLASS_NAME}`); this._viewController.compositionEnd(); + this._context.model.onCompositionEnd(); })); this._register(this._textAreaInput.onFocus(() => { diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index ef3f6e301b4..ec5077ea0c7 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -25,6 +25,7 @@ export class ViewCursors extends ViewPart { private _cursorStyle: TextEditorCursorStyle; private _cursorSmoothCaretAnimation: boolean; private _selectionIsEmpty: boolean; + private _isComposingInput: boolean; private _isVisible: boolean; @@ -49,6 +50,7 @@ export class ViewCursors extends ViewPart { this._cursorStyle = options.get(EditorOption.cursorStyle); this._cursorSmoothCaretAnimation = options.get(EditorOption.cursorSmoothCaretAnimation); this._selectionIsEmpty = true; + this._isComposingInput = false; this._isVisible = false; @@ -83,7 +85,16 @@ export class ViewCursors extends ViewPart { } // --- begin event handlers - + public onCompositionStart(e: viewEvents.ViewCompositionStartEvent): boolean { + this._isComposingInput = true; + this._updateBlinking(); + return true; + } + public onCompositionEnd(e: viewEvents.ViewCompositionEndEvent): boolean { + this._isComposingInput = false; + this._updateBlinking(); + return true; + } public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { const options = this._context.configuration.options; @@ -195,6 +206,10 @@ export class ViewCursors extends ViewPart { // ---- blinking logic private _getCursorBlinking(): TextEditorCursorBlinkingStyle { + if (this._isComposingInput) { + // avoid double cursors + return TextEditorCursorBlinkingStyle.Hidden; + } if (!this._editorHasFocus) { return TextEditorCursorBlinkingStyle.Hidden; } diff --git a/src/vs/editor/common/view/viewEvents.ts b/src/vs/editor/common/view/viewEvents.ts index 804d1b977f5..bcdc69bb34f 100644 --- a/src/vs/editor/common/view/viewEvents.ts +++ b/src/vs/editor/common/view/viewEvents.ts @@ -11,6 +11,8 @@ import { ScrollType } from 'vs/editor/common/editorCommon'; import { IModelDecorationsChangedEvent } from 'vs/editor/common/model/textModelEvents'; export const enum ViewEventType { + ViewCompositionStart, + ViewCompositionEnd, ViewConfigurationChanged, ViewCursorStateChanged, ViewDecorationsChanged, @@ -29,6 +31,16 @@ export const enum ViewEventType { ViewZonesChanged, } +export class ViewCompositionStartEvent { + public readonly type = ViewEventType.ViewCompositionStart; + constructor() { } +} + +export class ViewCompositionEndEvent { + public readonly type = ViewEventType.ViewCompositionEnd; + constructor() { } +} + export class ViewConfigurationChangedEvent { public readonly type = ViewEventType.ViewConfigurationChanged; @@ -285,7 +297,9 @@ export class ViewZonesChangedEvent { } export type ViewEvent = ( - ViewConfigurationChangedEvent + ViewCompositionStartEvent + | ViewCompositionEndEvent + | ViewConfigurationChangedEvent | ViewCursorStateChangedEvent | ViewDecorationsChangedEvent | ViewFlushedEvent diff --git a/src/vs/editor/common/viewModel/viewEventHandler.ts b/src/vs/editor/common/viewModel/viewEventHandler.ts index aad7a0b4957..e73ba9679b8 100644 --- a/src/vs/editor/common/viewModel/viewEventHandler.ts +++ b/src/vs/editor/common/viewModel/viewEventHandler.ts @@ -33,10 +33,15 @@ export class ViewEventHandler extends Disposable { // --- begin event handlers + public onCompositionStart(e: viewEvents.ViewCompositionStartEvent): boolean { + return false; + } + public onCompositionEnd(e: viewEvents.ViewCompositionEndEvent): boolean { + return false; + } public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { return false; } - public onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean { return false; } @@ -94,6 +99,18 @@ export class ViewEventHandler extends Disposable { switch (e.type) { + case viewEvents.ViewEventType.ViewCompositionStart: + if (this.onCompositionStart(e)) { + shouldRender = true; + } + break; + + case viewEvents.ViewEventType.ViewCompositionEnd: + if (this.onCompositionEnd(e)) { + shouldRender = true; + } + break; + case viewEvents.ViewEventType.ViewConfigurationChanged: if (this.onConfigurationChanged(e)) { shouldRender = true; diff --git a/src/vs/editor/common/viewModel/viewModel.ts b/src/vs/editor/common/viewModel/viewModel.ts index c69c16ea48c..125cb5880ae 100644 --- a/src/vs/editor/common/viewModel/viewModel.ts +++ b/src/vs/editor/common/viewModel/viewModel.ts @@ -164,6 +164,8 @@ export interface IViewModel extends ICursorSimpleModel { setViewport(startLineNumber: number, endLineNumber: number, centeredLineNumber: number): void; tokenizeViewport(): void; setHasFocus(hasFocus: boolean): void; + onCompositionStart(): void; + onCompositionEnd(): void; onDidColorThemeChange(): void; getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[]; diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index 316e4f43e1b..932f6917e55 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -183,6 +183,14 @@ export class ViewModel extends Disposable implements IViewModel { this._eventDispatcher.emitOutgoingEvent(new FocusChangedEvent(!hasFocus, hasFocus)); } + public onCompositionStart(): void { + this._eventDispatcher.emitSingleViewEvent(new viewEvents.ViewCompositionStartEvent()); + } + + public onCompositionEnd(): void { + this._eventDispatcher.emitSingleViewEvent(new viewEvents.ViewCompositionEndEvent()); + } + public onDidColorThemeChange(): void { this._eventDispatcher.emitSingleViewEvent(new viewEvents.ViewThemeChangedEvent()); } From 6d222ba7850df20ed1077596806d82b80bbb9d2b Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 3 Dec 2020 15:42:21 +0100 Subject: [PATCH 082/200] Fixes #97196: Clear out semantic tokens when there are no more providers --- src/vs/editor/common/model.ts | 7 ++++++- src/vs/editor/common/model/textModel.ts | 8 ++++++-- src/vs/editor/common/model/tokensStore.ts | 4 ++++ src/vs/editor/common/services/modelServiceImpl.ts | 4 ++++ .../viewportSemanticTokens/viewportSemanticTokens.ts | 8 +++++++- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index 98ce23d7b0e..52bd1b39fe7 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -855,7 +855,12 @@ export interface ITextModel { /** * @internal */ - hasSemanticTokens(): boolean; + hasCompleteSemanticTokens(): boolean; + + /** + * @internal + */ + hasSomeSemanticTokens(): boolean; /** * Flush all tokenization state. diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 2ba7cb4ee89..81f46885438 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -1880,12 +1880,16 @@ export class TextModel extends Disposable implements model.ITextModel { }); } - public hasSemanticTokens(): boolean { + public hasCompleteSemanticTokens(): boolean { return this._tokens2.isComplete(); } + public hasSomeSemanticTokens(): boolean { + return !this._tokens2.isEmpty(); + } + public setPartialSemanticTokens(range: Range, tokens: MultilineTokens2[]): void { - if (this.hasSemanticTokens()) { + if (this.hasCompleteSemanticTokens()) { return; } const changedRange = this._tokens2.setPartial(range, tokens); diff --git a/src/vs/editor/common/model/tokensStore.ts b/src/vs/editor/common/model/tokensStore.ts index a49ef27a71e..bbec0e36959 100644 --- a/src/vs/editor/common/model/tokensStore.ts +++ b/src/vs/editor/common/model/tokensStore.ts @@ -884,6 +884,10 @@ export class TokensStore2 { this._isComplete = false; } + public isEmpty(): boolean { + return (this._pieces.length === 0); + } + public set(pieces: MultilineTokens2[] | null, isComplete: boolean): void { this._pieces = pieces || []; this._isComplete = isComplete; diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index 7836fa5de72..8667276868a 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -790,6 +790,10 @@ class ModelSemanticColoring extends Disposable { } const provider = this._getSemanticColoringProvider(); if (!provider) { + if (this._currentDocumentResponse) { + // there are semantic tokens set + this._model.setSemanticTokens(null, false); + } return; } this._currentDocumentRequestCancellationTokenSource = new CancellationTokenSource(); diff --git a/src/vs/editor/contrib/viewportSemanticTokens/viewportSemanticTokens.ts b/src/vs/editor/contrib/viewportSemanticTokens/viewportSemanticTokens.ts index 0a317fd6f3a..44ca583901c 100644 --- a/src/vs/editor/contrib/viewportSemanticTokens/viewportSemanticTokens.ts +++ b/src/vs/editor/contrib/viewportSemanticTokens/viewportSemanticTokens.ts @@ -92,14 +92,20 @@ class ViewportSemanticTokensContribution extends Disposable implements IEditorCo return; } const model = this._editor.getModel(); - if (model.hasSemanticTokens()) { + if (model.hasCompleteSemanticTokens()) { return; } if (!isSemanticColoringEnabled(model, this._themeService, this._configurationService)) { + if (model.hasSomeSemanticTokens()) { + model.setSemanticTokens(null, false); + } return; } const provider = ViewportSemanticTokensContribution._getSemanticColoringProvider(model); if (!provider) { + if (model.hasSomeSemanticTokens()) { + model.setSemanticTokens(null, false); + } return; } const styling = this._modelService.getSemanticTokensProviderStyling(provider); From 3c4bbf6da24091e26a18175cca375950e054e53a Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 3 Dec 2020 15:42:51 +0100 Subject: [PATCH 083/200] Fix ports view listener leak Same kind of cause as https://github.com/microsoft/vscode/issues/107903 Fixes #111772 --- src/vs/workbench/contrib/remote/browser/tunnelView.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/contrib/remote/browser/tunnelView.ts b/src/vs/workbench/contrib/remote/browser/tunnelView.ts index e27ba8dc03f..033bdde9a17 100644 --- a/src/vs/workbench/contrib/remote/browser/tunnelView.ts +++ b/src/vs/workbench/contrib/remote/browser/tunnelView.ts @@ -292,6 +292,9 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer Date: Thu, 3 Dec 2020 15:53:01 +0100 Subject: [PATCH 084/200] Add paren, bracket, and brace to autoclosing pairs for make Fixes #89191 --- extensions/make/language-configuration.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/extensions/make/language-configuration.json b/extensions/make/language-configuration.json index f3c19d01120..82645b84dfb 100644 --- a/extensions/make/language-configuration.json +++ b/extensions/make/language-configuration.json @@ -17,6 +17,18 @@ ] ], "autoClosingPairs": [ + [ + "{", + "}" + ], + [ + "[", + "]" + ], + [ + "(", + ")" + ], { "open": "'", "close": "'", From 15f38fe338a791de62b1c448f0035b199ba27a04 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 3 Dec 2020 17:57:12 +0100 Subject: [PATCH 085/200] Fix ports view order in remote explorer Fixes #111830 --- src/vs/workbench/contrib/remote/browser/remote.ts | 2 +- src/vs/workbench/contrib/remote/browser/tunnelView.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/remote/browser/remote.ts b/src/vs/workbench/contrib/remote/browser/remote.ts index 2df1d1cfaf2..29ab926a392 100644 --- a/src/vs/workbench/contrib/remote/browser/remote.ts +++ b/src/vs/workbench/contrib/remote/browser/remote.ts @@ -574,7 +574,7 @@ Registry.as(Extensions.ViewContainersRegistry).register matches = /^details(@(\d+))?$/.exec(group); if (matches) { - return -500; + return -500 + Number(matches[2]); } matches = /^help(@(\d+))?$/.exec(group); diff --git a/src/vs/workbench/contrib/remote/browser/tunnelView.ts b/src/vs/workbench/contrib/remote/browser/tunnelView.ts index 033bdde9a17..7ed9fa790e0 100644 --- a/src/vs/workbench/contrib/remote/browser/tunnelView.ts +++ b/src/vs/workbench/contrib/remote/browser/tunnelView.ts @@ -729,7 +729,10 @@ export class TunnelPanelDescriptor implements IViewDescriptor { readonly canToggleVisibility = true; readonly hideByDefault = false; readonly workspace = true; + // group is not actually used for views that are not extension contributed. Use order instead. readonly group = 'details@0'; + // -500 comes from the remote explorer viewOrderDelegate + readonly order = -500; readonly remoteAuthority?: string | string[]; readonly canMoveView = true; readonly containerIcon = Codicon.plug; From ae93d489024e2dd110220adcaec5495145996e87 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 3 Dec 2020 17:58:49 +0100 Subject: [PATCH 086/200] fixes #111583 --- .../files/browser/views/explorerViewer.ts | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index f50916aee92..7110cae9482 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -1013,24 +1013,28 @@ export class FileDragAndDrop implements ITreeDragAndDrop { if (data instanceof NativeDragAndDropData) { const cts = new CancellationTokenSource(); - // Indicate progress globally - try { - if (isWeb) { - const dropPromise = this.progressService.withProgress({ - location: ProgressLocation.Window, - delay: 800, - cancellable: true, - title: localize('uploadingFiles', "Uploading") - }, async progress => { - this.handleWebExternalDrop(resolvedTarget, originalEvent, progress, cts.token); - }, () => cts.dispose(true)); - // Also indicate progress in the files view - this.progressService.withProgress({ location: VIEW_ID, delay: 500 }, () => dropPromise); - } else { + if (isWeb) { + // Indicate progress globally + const dropPromise = this.progressService.withProgress({ + location: ProgressLocation.Window, + delay: 800, + cancellable: true, + title: localize('uploadingFiles', "Uploading") + }, async progress => { + try { + await this.handleWebExternalDrop(resolvedTarget, originalEvent, progress, cts.token); + } catch (error) { + this.notificationService.warn(error); + } + }, () => cts.dispose(true)); + // Also indicate progress in the files view + this.progressService.withProgress({ location: VIEW_ID, delay: 500 }, () => dropPromise); + } else { + try { this.handleExternalDrop(resolvedTarget, originalEvent, cts.token); + } catch (error) { + this.notificationService.warn(error); } - } catch (error) { - this.notificationService.warn(error); } } // In-Explorer DND (Move/Copy file) @@ -1311,6 +1315,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { } private async addResources(target: ExplorerItem, resources: URI[], token: CancellationToken): Promise { + console.log('ADDING RESOURCE'); if (resources && resources.length > 0) { // Resolve target to check for name collisions and ask user From 95f6cfa0ae1f9b684f14c2521bd412616f77dba6 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 3 Dec 2020 10:20:14 -0800 Subject: [PATCH 087/200] =?UTF-8?q?More=20=F0=9F=92=85:=20adjust=20overall?= =?UTF-8?q?=20padding=20&=20sizing=20(refs=20#111753)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gettingStarted/browser/gettingStarted.css | 33 +++++++++++-------- .../gettingStarted/browser/gettingStarted.ts | 27 +++++++-------- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css index f41c4c53565..7c199b89de8 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css @@ -27,7 +27,6 @@ } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .header { - margin-top: 32px; display: flex; align-items: center; justify-content: center; @@ -42,10 +41,6 @@ width: 100% } -.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .category-description { - font-size: 12px; -} - .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.categories .category-progress { margin-top: 12px; font-size: 12px; @@ -67,6 +62,7 @@ .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide .getting-started-category { width: 330px; min-height: 80px; + margin: 12px; text-align: left; display: flex; } @@ -97,7 +93,7 @@ display: flex; height: 100%; justify-content: center; - padding: 30px; + padding: 44px; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task { @@ -107,6 +103,7 @@ } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task:not(.expanded) .task-description, +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task:not(.expanded) .actions, .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task:not(.expanded) button, .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task:not(.expanded) a { display: none; @@ -127,10 +124,14 @@ font-size: 13px; } +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task .actions { + margin-top: 12px; + display: flex; + align-items: center; +} + .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task .task-next { - float: right; - margin-top: 24px; - margin-right: 25px; + margin-left: auto; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task .codicon.hidden { @@ -143,8 +144,7 @@ } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail .getting-started-task-action { - margin: 20px 0 0; - padding: 4px 8px; + padding: 6px 12px; font-size: 11pt; min-width: 100px; } @@ -158,18 +158,21 @@ .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .gettingStartedSlide.detail #getting-started-detail-right { width: 66%; text-align: center; - padding: 35px; + padding-left: 44px; margin-bottom: 50px; } .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer button { border: none; - margin: 10px; color: inherit; text-align: left; padding: 16px; } +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer button:not(:first-child) { + margin-top: 12px; +} + .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer button:hover { cursor: pointer; } @@ -185,6 +188,10 @@ margin: 10px; } +.monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .prev-button:hover { + cursor: pointer; +} + .monaco-workbench .part.editor > .content .walkThroughContent .gettingStartedContainer .prev-button .codicon { position: relative; top: 2px; diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts index fbdb9a257e3..123bd38bbd9 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts @@ -292,19 +292,20 @@ export class GettingStartedPage extends Disposable { $('.task-description-container', {}, $('h3.task-title', {}, task.title), $('.task-description.description', {}, task.description), - ...( - task.button - ? [$('button.emphasis.getting-started-task-action', { 'x-dispatch': 'runTaskAction:' + task.id }, - task.button.title + this.getKeybindingLabel(task.button.command) - )] - : []), - ...( - arr[i + 1] - ? [ - $('a.task-next', - { 'x-dispatch': 'selectTask:' + arr[i + 1].id }, localize('next', "Next")), - ] : [] - ) + $('.actions', {}, + ...( + task.button + ? [$('button.emphasis.getting-started-task-action', { 'x-dispatch': 'runTaskAction:' + task.id }, + task.button.title + this.getKeybindingLabel(task.button.command) + )] + : []), + ...( + arr[i + 1] + ? [ + $('a.task-next', + { 'x-dispatch': 'selectTask:' + arr[i + 1].id }, localize('next', "Next")), + ] : [] + )) ))); const detailContainer = assertIsDefined(document.getElementById('getting-started-detail-container')); From 564ff91763a0517e13351c2bb8ae88212a2603c7 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 3 Dec 2020 19:49:42 +0100 Subject: [PATCH 088/200] fixes #111832 --- .../contrib/files/browser/explorerService.ts | 74 +++++++++++-------- .../files/browser/views/explorerViewer.ts | 1 - 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/explorerService.ts b/src/vs/workbench/contrib/files/browser/explorerService.ts index 6398736b046..a1a537578e0 100644 --- a/src/vs/workbench/contrib/files/browser/explorerService.ts +++ b/src/vs/workbench/contrib/files/browser/explorerService.ts @@ -21,13 +21,14 @@ import { UndoRedoSource } from 'vs/platform/undoRedo/common/undoRedo'; import { IExplorerView, IExplorerService } from 'vs/workbench/contrib/files/browser/files'; import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { RunOnceScheduler } from 'vs/base/common/async'; export const UNDO_REDO_SOURCE = new UndoRedoSource(); export class ExplorerService implements IExplorerService { declare readonly _serviceBrand: undefined; - private static readonly EXPLORER_FILE_CHANGES_REACT_DELAY = 500; // delay in ms to react to file changes to give our internal events a chance to react first + private static readonly EXPLORER_FILE_CHANGES_REACT_DELAY = 1000; // delay in ms to react to file changes to give our internal events a chance to react first private readonly disposables = new DisposableStore(); private editable: { stat: ExplorerItem, data: IEditableData } | undefined; @@ -35,6 +36,8 @@ export class ExplorerService implements IExplorerService { private cutItems: ExplorerItem[] | undefined; private view: IExplorerView | undefined; private model: ExplorerModel; + private onFileChangesScheduler: RunOnceScheduler; + private fileChangeEvents: FileChangesEvent[] = []; constructor( @IFileService private fileService: IFileService, @@ -51,7 +54,36 @@ export class ExplorerService implements IExplorerService { this.model = new ExplorerModel(this.contextService, this.uriIdentityService, this.fileService); this.disposables.add(this.model); this.disposables.add(this.fileService.onDidRunOperation(e => this.onDidRunOperation(e))); - this.disposables.add(this.fileService.onDidFilesChange(e => this.onDidFilesChange(e))); + + this.onFileChangesScheduler = new RunOnceScheduler(async () => { + const events = this.fileChangeEvents; + this.fileChangeEvents = []; + + // Filter to the ones we care + const types = [FileChangeType.ADDED, FileChangeType.DELETED]; + if (this._sortOrder === SortOrder.Modified) { + types.push(FileChangeType.UPDATED); + } + + let shouldRefresh = false; + this.roots.forEach(r => { + if (this.view && !shouldRefresh) { + shouldRefresh = doesFileEventAffect(r, this.view, events, types); + } + }); + + if (shouldRefresh) { + await this.refresh(false); + } + + }, ExplorerService.EXPLORER_FILE_CHANGES_REACT_DELAY); + + this.disposables.add(this.fileService.onDidFilesChange(e => { + this.fileChangeEvents.push(e); + if (!this.onFileChangesScheduler.isScheduled()) { + this.onFileChangesScheduler.schedule(); + } + })); this.disposables.add(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(this.configurationService.getValue()))); this.disposables.add(Event.any<{ scheme: string }>(this.fileService.onDidChangeFileSystemProviderRegistrations, this.fileService.onDidChangeFileSystemProviderCapabilities)(async e => { let affected = false; @@ -296,32 +328,6 @@ export class ExplorerService implements IExplorerService { } } - private onDidFilesChange(e: FileChangesEvent): void { - // Check if an explorer refresh is necessary (delayed to give internal events a chance to react first) - // Note: there is no guarantee when the internal events are fired vs real ones. Code has to deal with the fact that one might - // be fired first over the other or not at all. - setTimeout(async () => { - // Filter to the ones we care - const types = [FileChangeType.ADDED, FileChangeType.DELETED]; - if (this._sortOrder === SortOrder.Modified) { - types.push(FileChangeType.UPDATED); - } - - const allResolvedDirectories: ExplorerItem[] = []; - this.roots.forEach(r => { - allResolvedDirectories.push(r); - if (this.view) { - getAllNonFilteredDescendants(r, allResolvedDirectories, this.view); - } - }); - - const shouldRefresh = allResolvedDirectories.some(r => e.affects(r.resource, ...types)); - if (shouldRefresh) { - await this.refresh(false); - } - }, ExplorerService.EXPLORER_FILE_CHANGES_REACT_DELAY); - } - private async onConfigurationUpdated(configuration: IFilesConfiguration, event?: IConfigurationChangeEvent): Promise { const configSortOrder = configuration?.explorer?.sortOrder || 'default'; if (this._sortOrder !== configSortOrder) { @@ -338,13 +344,19 @@ export class ExplorerService implements IExplorerService { } } -function getAllNonFilteredDescendants(item: ExplorerItem, result: ExplorerItem[], view: IExplorerView): void { +function doesFileEventAffect(item: ExplorerItem, view: IExplorerView, events: FileChangesEvent[], types: FileChangeType[]): boolean { + if (events.some(e => e.affects(item.resource, ...types))) { + return true; + } for (let [_name, child] of item.children) { if (view.isItemVisible(child)) { if (child.isDirectory && child.isDirectoryResolved) { - result.push(child); - getAllNonFilteredDescendants(child, result, view); + if (doesFileEventAffect(child, view, events, types)) { + return true; + } } } } + + return false; } diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 7110cae9482..6ec1d861c37 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -1315,7 +1315,6 @@ export class FileDragAndDrop implements ITreeDragAndDrop { } private async addResources(target: ExplorerItem, resources: URI[], token: CancellationToken): Promise { - console.log('ADDING RESOURCE'); if (resources && resources.length > 0) { // Resolve target to check for name collisions and ask user From a82ae0c9b7608650c341bb016a58c94f57aa1afb Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 3 Dec 2020 20:10:44 +0100 Subject: [PATCH 089/200] Fix #108266 --- .../editor/contrib/hover/modesContentHover.ts | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index 8b1f88e7b39..ad2d6b27263 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -31,7 +31,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { IOpenerService, NullOpenerService } from 'vs/platform/opener/common/opener'; import { MarkerController, NextMarkerAction } from 'vs/editor/contrib/gotoError/gotoError'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; +import { CancelablePromise, createCancelablePromise, disposableTimeout } from 'vs/base/common/async'; import { getCodeActions, CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction'; import { QuickFixAction, QuickFixController } from 'vs/editor/contrib/codeAction/codeActionCommands'; import { CodeActionKind, CodeActionTrigger } from 'vs/editor/contrib/codeAction/types'; @@ -578,6 +578,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget { return hoverElement; } + private recentMarkerCodeActionsInfo: { marker: IMarker, hasCodeActions: boolean } | undefined = undefined; private renderMarkerStatusbar(markerHover: MarkerHover): HTMLElement { const hoverElement = $('div.hover-row.status-bar'); const disposables = new DisposableStore(); @@ -596,24 +597,28 @@ export class ModesContentHoverWidget extends ContentHoverWidget { if (!this._editor.getOption(EditorOption.readOnly)) { const quickfixPlaceholderElement = dom.append(actionsElement, $('div')); - quickfixPlaceholderElement.style.opacity = '0'; - quickfixPlaceholderElement.style.transition = 'opacity 0.2s'; - setTimeout(() => quickfixPlaceholderElement.style.opacity = '1', 200); - quickfixPlaceholderElement.textContent = nls.localize('checkingForQuickFixes', "Checking for quick fixes..."); - disposables.add(toDisposable(() => quickfixPlaceholderElement.remove())); - + if (this.recentMarkerCodeActionsInfo) { + if (IMarkerData.makeKey(this.recentMarkerCodeActionsInfo.marker) === IMarkerData.makeKey(markerHover.marker)) { + if (!this.recentMarkerCodeActionsInfo.hasCodeActions) { + quickfixPlaceholderElement.textContent = nls.localize('noQuickFixes', "No quick fixes available"); + } + } else { + this.recentMarkerCodeActionsInfo = undefined; + } + } + const updatePlaceholderDisposable = disposables.add(disposableTimeout(() => quickfixPlaceholderElement.textContent = nls.localize('checkingForQuickFixes', "Checking for quick fixes..."), 64)); const codeActionsPromise = this.getCodeActions(markerHover.marker); disposables.add(toDisposable(() => codeActionsPromise.cancel())); codeActionsPromise.then(actions => { - quickfixPlaceholderElement.style.transition = ''; - quickfixPlaceholderElement.style.opacity = '1'; + updatePlaceholderDisposable.dispose(); + this.recentMarkerCodeActionsInfo = { marker: markerHover.marker, hasCodeActions: actions.validActions.length > 0 }; - if (!actions.validActions.length) { + if (!this.recentMarkerCodeActionsInfo.hasCodeActions) { actions.dispose(); quickfixPlaceholderElement.textContent = nls.localize('noQuickFixes', "No quick fixes available"); return; } - quickfixPlaceholderElement.remove(); + quickfixPlaceholderElement.style.display = 'none'; let showing = false; disposables.add(toDisposable(() => { From 061e84830d7865f53d61731333830dae4229f3d6 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 3 Dec 2020 20:13:34 +0100 Subject: [PATCH 090/200] fixes #110775 --- src/vs/platform/actions/browser/menuEntryActionViewItem.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts index 9268e3d4ca4..1344ea90093 100644 --- a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts +++ b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts @@ -20,7 +20,8 @@ import { isWindows, isLinux } from 'vs/base/common/platform'; export function createAndFillInContextMenuActions(menu: IMenu, options: IMenuActionOptions | undefined, target: IAction[] | { primary: IAction[]; secondary: IAction[]; }, isPrimaryGroup?: (group: string) => boolean): IDisposable { const groups = menu.getActions(options); - const useAlternativeActions = ModifierKeyEmitter.getInstance().keyStatus.altKey; + const modifierKeyEmitter = ModifierKeyEmitter.getInstance(); + const useAlternativeActions = modifierKeyEmitter.keyStatus.altKey || ((isWindows || isLinux) && modifierKeyEmitter.keyStatus.shiftKey); fillInActions(groups, target, useAlternativeActions, isPrimaryGroup); return asDisposable(groups); } From 2964a69479ba7f9f6af695d3e65f7dadc299d7d6 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 3 Dec 2020 11:15:18 -0800 Subject: [PATCH 091/200] Fix #111798: Getting Started: capitalized "Editor" looks weird --- .../services/gettingStarted/common/gettingStartedContent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts b/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts index 64e01b6746b..3869a6cea3e 100644 --- a/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts +++ b/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts @@ -33,7 +33,7 @@ export const content: GettingStartedContent = [ id: 'Beginner', title: localize('gettingStarted.beginner.title', "Get Started"), codicon: 'lightbulb', - description: localize('gettingStarted.beginner.description', "Get to know your new Editor"), + description: localize('gettingStarted.beginner.description', "Get to know your new editor"), content: { type: 'items', items: [ From 450ae69a335c3b9b005e4c26aa444fc0c9659d74 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 3 Dec 2020 20:15:48 +0100 Subject: [PATCH 092/200] Fix #111835 --- .../workbench/contrib/extensions/browser/extensionsActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 0aa7ddd1b10..36dbf7c75ba 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -150,7 +150,7 @@ class PromptExtensionInstallFailureAction extends Action { }) }); } - const checkLogsMessage = localize('check logs', "Please check [logs]({0}) for more details.", `command:${Constants.showWindowLogActionId}`); + const checkLogsMessage = localize('check logs', "Please check the [log]({0}) for more details.", `command:${Constants.showWindowLogActionId}`); this.notificationService.prompt(Severity.Error, `${operationMessage} ${checkLogsMessage}`, promptChoices); } } From 7ecce71a487455c782eef943fb22af450ba07267 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 3 Dec 2020 20:39:33 +0100 Subject: [PATCH 093/200] Fixes #110376 --- .../common/controller/cursorMoveCommands.ts | 12 +++++-- .../test/browser/controller/cursor.test.ts | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/common/controller/cursorMoveCommands.ts b/src/vs/editor/common/controller/cursorMoveCommands.ts index bc9bbb1c390..909a2255d4d 100644 --- a/src/vs/editor/common/controller/cursorMoveCommands.ts +++ b/src/vs/editor/common/controller/cursorMoveCommands.ts @@ -412,7 +412,11 @@ export class CursorMoveCommands { const skipWrappingPointStop = hasMultipleCursors || !cursor.viewState.hasSelection(); let newViewState = MoveOperations.moveLeft(viewModel.cursorConfig, viewModel, cursor.viewState, inSelectionMode, noOfColumns); - if (skipWrappingPointStop && noOfColumns === 1 && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber) { + if (skipWrappingPointStop + && noOfColumns === 1 + && cursor.viewState.position.column === viewModel.getLineMinColumn(cursor.viewState.position.lineNumber) + && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber + ) { // moved over to the previous view line const newViewModelPosition = viewModel.coordinatesConverter.convertViewPositionToModelPosition(newViewState.position); if (newViewModelPosition.lineNumber === cursor.modelState.position.lineNumber) { @@ -445,7 +449,11 @@ export class CursorMoveCommands { const skipWrappingPointStop = hasMultipleCursors || !cursor.viewState.hasSelection(); let newViewState = MoveOperations.moveRight(viewModel.cursorConfig, viewModel, cursor.viewState, inSelectionMode, noOfColumns); - if (skipWrappingPointStop && noOfColumns === 1 && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber) { + if (skipWrappingPointStop + && noOfColumns === 1 + && cursor.viewState.position.column === viewModel.getLineMaxColumn(cursor.viewState.position.lineNumber) + && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber + ) { // moved over to the next view line const newViewModelPosition = viewModel.coordinatesConverter.convertViewPositionToModelPosition(newViewState.position); if (newViewModelPosition.lineNumber === cursor.modelState.position.lineNumber) { diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index ac2fa484062..cb202a3f872 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -2208,6 +2208,42 @@ suite('Editor Controller - Regression tests', () => { }); }); + test('issue #110376: multiple selections with wordwrap behave differently', () => { + // a single model line => 4 view lines + withTestCodeEditor([ + [ + 'just a sentence. just a ', + 'sentence. just a sentence.', + ].join('') + ], { wordWrap: 'wordWrapColumn', wordWrapColumn: 25 }, (editor, viewModel) => { + viewModel.setSelections('test', [ + new Selection(1, 1, 1, 16), + new Selection(1, 18, 1, 33), + new Selection(1, 35, 1, 50), + ]); + + moveLeft(editor, viewModel); + assertCursor(viewModel, [ + new Selection(1, 1, 1, 1), + new Selection(1, 18, 1, 18), + new Selection(1, 35, 1, 35), + ]); + + viewModel.setSelections('test', [ + new Selection(1, 1, 1, 16), + new Selection(1, 18, 1, 33), + new Selection(1, 35, 1, 50), + ]); + + moveRight(editor, viewModel); + assertCursor(viewModel, [ + new Selection(1, 16, 1, 16), + new Selection(1, 33, 1, 33), + new Selection(1, 50, 1, 50), + ]); + }); + }); + test('issue #98320: Multi-Cursor, Wrap lines and cursorSelectRight ==> cursors out of sync', () => { // a single model line => 4 view lines withTestCodeEditor([ From 7b1154d4479b5ced0d2f72cac4789d2cbc4e6ca9 Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 3 Dec 2020 11:50:21 -0800 Subject: [PATCH 094/200] update resolve time stats even if they are the same. --- .../contrib/notebook/common/notebookEditorModel.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts index fd79380d7c9..b66fc62a1f0 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts @@ -17,6 +17,7 @@ import { Schemas } from 'vs/base/common/network'; import { IFileStatWithMetadata, IFileService } from 'vs/platform/files/common/files'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { ILabelService } from 'vs/platform/label/common/label'; +import { ILogService } from 'vs/platform/log/common/log'; export interface INotebookLoadOptions { @@ -51,6 +52,7 @@ export class NotebookEditorModel extends EditorModel implements INotebookEditorM @IBackupFileService private readonly _backupFileService: IBackupFileService, @IFileService private readonly _fileService: IFileService, @INotificationService private readonly _notificationService: INotificationService, + @ILogService private readonly _logService: ILogService, @ILabelService labelService: ILabelService, ) { super(); @@ -199,6 +201,11 @@ export class NotebookEditorModel extends EditorModel implements INotebookEditorM private async _assertStat() { const stats = await this._resolveStats(this.resource); if (this._lastResolvedFileStat && stats && stats.mtime > this._lastResolvedFileStat.mtime) { + this._logService.debug(`noteboook file on disk is newer: +LastResolvedStat: ${this._lastResolvedFileStat ? JSON.stringify(this._lastResolvedFileStat) : undefined}. +Current stat: ${JSON.stringify(stats)} +`); + this._lastResolvedFileStat = stats; return new Promise<'overwrite' | 'revert' | 'none'>(resolve => { const handle = this._notificationService.prompt( Severity.Info, @@ -221,6 +228,9 @@ export class NotebookEditorModel extends EditorModel implements INotebookEditorM resolve('none'); }); }); + } else if (!this._lastResolvedFileStat && stats) { + // finally get a stats + this._lastResolvedFileStat = stats; } return 'overwrite'; @@ -271,7 +281,9 @@ export class NotebookEditorModel extends EditorModel implements INotebookEditorM } try { + this._logService.debug(`start checking stats for ${resource.toString()}`); const newStats = await this._fileService.resolve(this.resource, { resolveMetadata: true }); + this._logService.debug(`${resource.toString()} latest file stats: ${JSON.stringify(newStats)}`); return newStats; } catch (e) { return undefined; From 41eb987d0915f985c617b3ce35601ae56e982270 Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 3 Dec 2020 11:53:47 -0800 Subject: [PATCH 095/200] add log for save/saveas --- .../workbench/contrib/notebook/common/notebookEditorModel.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts index b66fc62a1f0..c0746dbc1e5 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts @@ -199,6 +199,7 @@ export class NotebookEditorModel extends EditorModel implements INotebookEditorM } private async _assertStat() { + this._logService.debug('start assert stat'); const stats = await this._resolveStats(this.resource); if (this._lastResolvedFileStat && stats && stats.mtime > this._lastResolvedFileStat.mtime) { this._logService.debug(`noteboook file on disk is newer: @@ -237,6 +238,7 @@ Current stat: ${JSON.stringify(stats)} } async save(): Promise { + this._logService.debug(`start saving notebook ${this.resource.toString()}`); const result = await this._assertStat(); if (result === 'none') { return false; @@ -249,6 +251,7 @@ Current stat: ${JSON.stringify(stats)} const tokenSource = new CancellationTokenSource(); await this._notebookService.save(this.notebook.viewType, this.notebook.uri, tokenSource.token); + this._logService.debug(`notebook ${this.resource.toString()} saved. update file stats`); const newStats = await this._resolveStats(this.resource); this._lastResolvedFileStat = newStats; this.setDirty(false); @@ -256,6 +259,7 @@ Current stat: ${JSON.stringify(stats)} } async saveAs(targetResource: URI): Promise { + this._logService.debug(`start saving notebook ${this.resource.toString()}`); const result = await this._assertStat(); if (result === 'none') { @@ -269,6 +273,7 @@ Current stat: ${JSON.stringify(stats)} const tokenSource = new CancellationTokenSource(); await this._notebookService.saveAs(this.notebook.viewType, this.notebook.uri, targetResource, tokenSource.token); + this._logService.debug(`notebook ${this.resource.toString()} saved. update file stats`); const newStats = await this._resolveStats(this.resource); this._lastResolvedFileStat = newStats; this.setDirty(false); From 370e092880953d3092b2a8de4bd2fc5b28a966ea Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 3 Dec 2020 12:13:41 -0800 Subject: [PATCH 096/200] extJupyter --- .github/commands.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/commands.json b/.github/commands.json index 7a1220f7d43..980b2906bf5 100644 --- a/.github/commands.json +++ b/.github/commands.json @@ -202,6 +202,19 @@ "addLabel": "*caused-by-extension", "comment": "It looks like this is caused by the Python extension. Please file it with the repository [here](https://github.com/microsoft/vscode-python). Make sure to check their issue reporting template and provide them relevant information such as the extension version you're using. See also our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines for more information.\n\nHappy Coding!" }, + { + "type": "comment", + "name": "extJupyter", + "allowUsers": [ + "cleidigh", + "usernamehw", + "gjsjohnmurray", + "IllusionMH" + ], + "action": "close", + "addLabel": "*caused-by-extension", + "comment": "It looks like this is caused by the Jupyter extension. Please file it with the repository [here](https://github.com/microsoft/vscode-jupyter). Make sure to check their issue reporting template and provide them relevant information such as the extension version you're using. See also our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines for more information.\n\nHappy Coding!" + }, { "type": "comment", "name": "extC", From 62b119aa2234571d4e46a83961e48b43ba5ba048 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Thu, 3 Dec 2020 15:27:18 -0500 Subject: [PATCH 097/200] Fixes bad has implementation Since a node could still exist, because it has a left or right --- src/vs/base/common/map.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index 37e3c3bc570..0e08876e537 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -377,7 +377,8 @@ export class TernarySearchTree { } has(key: K): boolean { - return !!this._getNode(key); + const node = this._getNode(key); + return !(node?.value === undefined && node?.mid === undefined); } delete(key: K): void { From 39fb92c6c529b5f12465e2820324a8448b3bb613 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 3 Dec 2020 12:32:11 -0800 Subject: [PATCH 098/200] Remove redundant when clauses --- .../browser/searchEditor.contribution.ts | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts index ebcd6ca4eb1..cc6faa97d74 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts @@ -234,7 +234,6 @@ registerAction2(class extends Action2 { title: { value: localize('searchEditor.deleteResultBlock', "Delete File Results"), original: 'Delete File Results' }, keybinding: { weight: KeybindingWeight.EditorContrib, - when: SearchEditorConstants.InSearchEditor, primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Backspace, }, precondition: SearchEditorConstants.InSearchEditor, @@ -361,13 +360,10 @@ registerAction2(class extends Action2 { id: FocusQueryEditorWidgetCommandId, title: { value: localize('search.action.focusQueryEditorWidget', "Focus Search Editor Input"), original: 'Focus Search Editor Input' }, category, - menu: { - id: MenuId.CommandPalette, - when: ActiveEditorContext.isEqualTo(SearchEditorConstants.SearchEditorID) - }, + f1: true, + precondition: SearchEditorConstants.InSearchEditor, keybinding: { primary: KeyCode.Escape, - when: SearchEditorConstants.InSearchEditor, weight: KeybindingWeight.EditorContrib } }); @@ -388,10 +384,10 @@ registerAction2(class extends Action2 { title: { value: localize('searchEditor.action.toggleSearchEditorCaseSensitive', "Toggle Match Case"), original: 'Toggle Match Case' }, category, f1: true, - precondition: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), + precondition: SearchEditorConstants.InSearchEditor, keybinding: Object.assign({ weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor, SearchConstants.SearchInputBoxFocusedKey), + when: SearchConstants.SearchInputBoxFocusedKey, }, ToggleCaseSensitiveKeybinding) }); } @@ -407,10 +403,10 @@ registerAction2(class extends Action2 { title: { value: localize('searchEditor.action.toggleSearchEditorWholeWord', "Toggle Match Whole Word"), original: 'Toggle Match Whole Word' }, category, f1: true, - precondition: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), + precondition: SearchEditorConstants.InSearchEditor, keybinding: Object.assign({ weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor, SearchConstants.SearchInputBoxFocusedKey), + when: SearchConstants.SearchInputBoxFocusedKey, }, ToggleWholeWordKeybinding) }); } @@ -426,10 +422,10 @@ registerAction2(class extends Action2 { title: { value: localize('searchEditor.action.toggleSearchEditorRegex', "Toggle Use Regular Expression"), original: 'Toggle Use Regular Expression"' }, category, f1: true, - precondition: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), + precondition: SearchEditorConstants.InSearchEditor, keybinding: Object.assign({ weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor, SearchConstants.SearchInputBoxFocusedKey), + when: SearchConstants.SearchInputBoxFocusedKey, }, ToggleRegexKeybinding) }); } @@ -445,10 +441,9 @@ registerAction2(class extends Action2 { title: { value: localize('searchEditor.action.toggleSearchEditorContextLines', "Toggle Context Lines"), original: 'Toggle Context Lines"' }, category, f1: true, - precondition: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), + precondition: SearchEditorConstants.InSearchEditor, keybinding: { weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), primary: KeyMod.Alt | KeyCode.KEY_L, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_L } } @@ -466,10 +461,9 @@ registerAction2(class extends Action2 { title: { original: 'Increase Context Lines', value: localize('searchEditor.action.increaseSearchEditorContextLines', "Increase Context Lines") }, category, f1: true, - precondition: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), + precondition: SearchEditorConstants.InSearchEditor, keybinding: { weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), primary: KeyMod.Alt | KeyCode.US_EQUAL } }); @@ -484,10 +478,9 @@ registerAction2(class extends Action2 { title: { original: 'Decrease Context Lines', value: localize('searchEditor.action.decreaseSearchEditorContextLines', "Decrease Context Lines") }, category, f1: true, - precondition: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), + precondition: SearchEditorConstants.InSearchEditor, keybinding: { weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), primary: KeyMod.Alt | KeyCode.US_MINUS } }); @@ -502,10 +495,9 @@ registerAction2(class extends Action2 { title: { original: 'Select All Matches', value: localize('searchEditor.action.selectAllSearchEditorMatches', "Select All Matches") }, category, f1: true, - precondition: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), + precondition: SearchEditorConstants.InSearchEditor, keybinding: { weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(SearchEditorConstants.InSearchEditor), primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_L, } }); From 1c1c59fd0fb1acab24181222907bc6bab78038da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 3 Dec 2020 12:45:01 -0800 Subject: [PATCH 099/200] Kill code processes after each integration test suite run (#111844) * bring back linux integration tests * no empty functions * hmm --- .../linux/product-build-linux.yml | 56 ++++++++++--------- package.json | 4 +- scripts/test-integration.sh | 25 +++++++++ 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 58bb954d35c..1f7884a1c83 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -130,35 +130,37 @@ steps: displayName: Run unit tests (Browser) condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - # - script: | - # # Figure out the full absolute path of the product we just built - # # including the remote server and configure the integration tests - # # to run with these builds instead of running out of sources. - # set -e - # APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - # APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") - # INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ - # VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ - # DISPLAY=:10 ./scripts/test-integration.sh --build --tfs "Integration Tests" - # displayName: Run integration tests (Electron) - # condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + - script: | + # Figure out the full absolute path of the product we just built + # including the remote server and configure the integration tests + # to run with these builds instead of running out of sources. + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) + APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") + INTEGRATION_TEST_APP_NAME="$APP_NAME" \ + INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ + DISPLAY=:10 ./scripts/test-integration.sh --build --tfs "Integration Tests" + displayName: Run integration tests (Electron) + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - # - script: | - # set -e - # VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH)" \ - # DISPLAY=:10 ./resources/server/test/test-web-integration.sh --browser chromium - # displayName: Run integration tests (Browser) - # condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + - script: | + set -e + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH)" \ + DISPLAY=:10 ./resources/server/test/test-web-integration.sh --browser chromium + displayName: Run integration tests (Browser) + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - # - script: | - # set -e - # APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - # APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") - # INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ - # VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ - # DISPLAY=:10 ./resources/server/test/test-remote-integration.sh - # displayName: Run remote integration tests (Electron) - # condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + - script: | + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) + APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") + INTEGRATION_TEST_APP_NAME="$APP_NAME" \ + INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ + DISPLAY=:10 ./resources/server/test/test-remote-integration.sh + displayName: Run remote integration tests (Electron) + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - task: PublishPipelineArtifact@0 inputs: diff --git a/package.json b/package.json index faabdc484fd..f4c487c9076 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.52.0", - "distro": "525b7677232e7f810dd09678a784247f93df7845", + "distro": "11fd6f1230738827638f000f641d01b2b178db20", "author": { "name": "Microsoft Corporation" }, @@ -197,4 +197,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index b302ce28db9..b82dbec1137 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -46,21 +46,46 @@ else echo "Running integration tests with '$INTEGRATION_TEST_ELECTRON_PATH' as build." fi +if [ -z "$INTEGRATION_TEST_APP_NAME" ]; then + after_suite() { true; } +else + after_suite() { killall $INTEGRATION_TEST_APP_NAME || true; } +fi + # Integration tests in AMD ./scripts/test.sh --runGlob **/*.integrationTest.js "$@" +after_suite # Tests in the extension host "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $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 --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR +after_suite + "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR +after_suite + "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR +after_suite + "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/markdown-language-features/test-workspace --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR +after_suite + #"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/typescript-language-features/test-workspace --extensionDevelopmentPath=$ROOT/extensions/typescript-language-features --extensionTestsPath=$ROOT/extensions/typescript-language-features/out/test --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR +# after_suite + "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/emmet/out/test/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR +after_suite + "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $(mktemp -d 2>/dev/null) --enable-proposed-api=vscode.git --extensionDevelopmentPath=$ROOT/extensions/git --extensionTestsPath=$ROOT/extensions/git/out/test --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR +after_suite + "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-notebook-tests/test --enable-proposed-api=vscode.vscode-notebook-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-notebook-tests --extensionTestsPath=$ROOT/extensions/vscode-notebook-tests/out/ --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR +after_suite # Tests in commonJS (CSS, HTML) cd $ROOT/extensions/css-language-features/server && $ROOT/scripts/node-electron.sh test/index.js +after_suite + cd $ROOT/extensions/html-language-features/server && $ROOT/scripts/node-electron.sh test/index.js +after_suite rm -rf $VSCODEUSERDATADIR From 53eac52308c4611000a171cc7bf1214293473c78 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 3 Dec 2020 21:57:22 +0100 Subject: [PATCH 100/200] Fixes #111499 --- src/vs/editor/browser/viewParts/minimap/minimap.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index 6001fb4f7c2..7ca33211a3c 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -237,6 +237,7 @@ class MinimapLayout { options: MinimapOptions, viewportStartLineNumber: number, viewportEndLineNumber: number, + viewportStartLineNumberVerticalOffset: number, viewportHeight: number, viewportContainsWhitespaceGaps: boolean, lineCount: number, @@ -331,7 +332,8 @@ class MinimapLayout { } const endLineNumber = Math.min(lineCount, startLineNumber + minimapLinesFitting - 1); - const sliderTopAligned = (scrollTop / lineHeight - startLineNumber + 1) * minimapLineHeight / pixelRatio; + const partialLine = (scrollTop - viewportStartLineNumberVerticalOffset) / lineHeight; + const sliderTopAligned = (viewportStartLineNumber - startLineNumber + partialLine) * minimapLineHeight / pixelRatio; return new MinimapLayout(scrollTop, scrollHeight, true, computedSliderRatio, sliderTopAligned, sliderHeight, startLineNumber, endLineNumber); } @@ -505,6 +507,7 @@ interface IMinimapRenderingContext { readonly viewportStartLineNumber: number; readonly viewportEndLineNumber: number; + readonly viewportStartLineNumberVerticalOffset: number; readonly scrollTop: number; readonly scrollLeft: number; @@ -891,6 +894,7 @@ export class Minimap extends ViewPart implements IMinimapModel { viewportStartLineNumber: viewportStartLineNumber, viewportEndLineNumber: viewportEndLineNumber, + viewportStartLineNumberVerticalOffset: ctx.getVerticalOffsetForLineNumber(viewportStartLineNumber), scrollTop: ctx.scrollTop, scrollLeft: ctx.scrollLeft, @@ -1344,6 +1348,7 @@ class InnerMinimap extends Disposable { this._model.options, renderingCtx.viewportStartLineNumber, renderingCtx.viewportEndLineNumber, + renderingCtx.viewportStartLineNumberVerticalOffset, renderingCtx.viewportHeight, renderingCtx.viewportContainsWhitespaceGaps, this._model.getLineCount(), From 9d5c351c71e48b97e7f4ca69e1ff46f92feb0c09 Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 3 Dec 2020 15:11:42 -0800 Subject: [PATCH 101/200] notebook list view scrollbar should be below cell toolbar --- src/vs/workbench/contrib/notebook/browser/media/notebook.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/notebook/browser/media/notebook.css b/src/vs/workbench/contrib/notebook/browser/media/notebook.css index 3547b989dd4..c2b2830c4c9 100644 --- a/src/vs/workbench/contrib/notebook/browser/media/notebook.css +++ b/src/vs/workbench/contrib/notebook/browser/media/notebook.css @@ -536,7 +536,7 @@ } .monaco-workbench .notebookOverlay.notebook-editor-editable > .cell-list-container > .monaco-list > .monaco-scrollable-element > .scrollbar.visible { - z-index: 50; + z-index: 25; cursor: default; } From 1aa26c377587c862f74f298937604631b854884d Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 4 Dec 2020 00:02:52 +0100 Subject: [PATCH 102/200] Fixes #105808 --- src/vs/editor/browser/editorBrowser.ts | 7 ++++++- .../editor/browser/widget/codeEditorWidget.ts | 12 ++++++++++++ src/vs/editor/common/model.ts | 15 ++++++++++----- src/vs/editor/common/model/editStack.ts | 17 +++++++++++++++++ src/vs/editor/common/model/textModel.ts | 4 ++++ .../editor/contrib/indentation/indentation.ts | 10 ++++++---- .../contrib/linkedEditing/linkedEditing.ts | 1 + src/vs/monaco.d.ts | 16 ++++++++++++---- 8 files changed, 68 insertions(+), 14 deletions(-) diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index 13552a60ec0..43305c283eb 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -684,10 +684,15 @@ export interface ICodeEditor extends editorCommon.IEditor { executeCommand(source: string | null | undefined, command: editorCommon.ICommand): void; /** - * Push an "undo stop" in the undo-redo stack. + * Create an "undo stop" in the undo-redo stack. */ pushUndoStop(): boolean; + /** + * Remove the "undo stop" in the undo-redo stack. + */ + popUndoStop(): boolean; + /** * Execute edits on the editor. * The edits will land on the undo-redo stack, but no "undo stop" will be pushed. diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index e39d4773399..4c87ce2bb2d 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1122,6 +1122,18 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE return true; } + public popUndoStop(): boolean { + if (!this._modelData) { + return false; + } + if (this._configuration.options.get(EditorOption.readOnly)) { + // read only editor => sorry! + return false; + } + this._modelData.model.popStackElement(); + return true; + } + public executeEdits(source: string | null | undefined, edits: IIdentifiedSingleEditOperation[], endCursorState?: ICursorStateComputer | Selection[]): boolean { if (!this._modelData) { return false; diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index 52bd1b39fe7..8f4d53a8447 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -1099,12 +1099,17 @@ export interface ITextModel { detectIndentation(defaultInsertSpaces: boolean, defaultTabSize: number): void; /** - * Push a stack element onto the undo stack. This acts as an undo/redo point. - * The idea is to use `pushEditOperations` to edit the model and then to - * `pushStackElement` to create an undo/redo stop point. + * Close the current undo-redo element. + * This offers a way to create an undo/redo stop point. */ pushStackElement(): void; + /** + * Open the current undo-redo element. + * This offers a way to remove the current undo/redo stop point. + */ + popStackElement(): void; + /** * Push edit operations, basically editing the model. This is the preferred way * of editing the model. The edit operations will land on the undo stack. @@ -1148,7 +1153,7 @@ export interface ITextModel { _applyRedo(changes: TextChange[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; /** - * Undo edit operations until the first previous stop point created by `pushStackElement`. + * Undo edit operations until the previous undo/redo point. * The inverse edit operations will be pushed on the redo stack. * @internal */ @@ -1161,7 +1166,7 @@ export interface ITextModel { canUndo(): boolean; /** - * Redo edit operations until the next stop point created by `pushStackElement`. + * Redo edit operations until the next undo/redo point. * The inverse edit operations will be pushed on the undo stack. * @internal */ diff --git a/src/vs/editor/common/model/editStack.ts b/src/vs/editor/common/model/editStack.ts index 0928d7d0e9b..d06f447b05e 100644 --- a/src/vs/editor/common/model/editStack.ts +++ b/src/vs/editor/common/model/editStack.ts @@ -199,6 +199,12 @@ export class SingleModelEditStackElement implements IResourceUndoRedoElement { } } + public open(): void { + if (!(this._data instanceof SingleModelEditStackData)) { + this._data = SingleModelEditStackData.deserialize(this._data); + } + } + public undo(): void { if (URI.isUri(this.model)) { // don't have a model @@ -315,6 +321,10 @@ export class MultiModelEditStackElement implements IWorkspaceUndoRedoElement { this._isOpen = false; } + public open(): void { + // cannot reopen + } + public undo(): void { this._isOpen = false; @@ -386,6 +396,13 @@ export class EditStack { } } + public popStackElement(): void { + const lastElement = this._undoRedoService.getLastElement(this._model.uri); + if (isEditStackElement(lastElement)) { + lastElement.open(); + } + } + public clear(): void { this._undoRedoService.removeElements(this._model.uri); } diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 81f46885438..35dd466403a 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -1225,6 +1225,10 @@ export class TextModel extends Disposable implements model.ITextModel { this._commandManager.pushStackElement(); } + public popStackElement(): void { + this._commandManager.popStackElement(); + } + public pushEOL(eol: model.EndOfLineSequence): void { const currentEOL = (this.getEOL() === '\n' ? model.EndOfLineSequence.LF : model.EndOfLineSequence.CRLF); if (currentEOL === eol) { diff --git a/src/vs/editor/contrib/indentation/indentation.ts b/src/vs/editor/contrib/indentation/indentation.ts index dcdcadea52b..720c8e76916 100644 --- a/src/vs/editor/contrib/indentation/indentation.ts +++ b/src/vs/editor/contrib/indentation/indentation.ts @@ -472,7 +472,6 @@ export class AutoIndentOnPaste implements IEditorContribution { } const autoIndent = this.editor.getOption(EditorOption.autoIndent); const { tabSize, indentSize, insertSpaces } = model.getOptions(); - this.editor.pushUndoStop(); let textEdits: TextEdit[] = []; let indentConverter = { @@ -583,9 +582,12 @@ export class AutoIndentOnPaste implements IEditorContribution { } } - let cmd = new AutoIndentOnPasteCommand(textEdits, this.editor.getSelection()!); - this.editor.executeCommand('autoIndentOnPaste', cmd); - this.editor.pushUndoStop(); + if (textEdits.length > 0) { + this.editor.pushUndoStop(); + let cmd = new AutoIndentOnPasteCommand(textEdits, this.editor.getSelection()!); + this.editor.executeCommand('autoIndentOnPaste', cmd); + this.editor.pushUndoStop(); + } } private shouldIgnoreLine(model: ITextModel, lineNumber: number): boolean { diff --git a/src/vs/editor/contrib/linkedEditing/linkedEditing.ts b/src/vs/editor/contrib/linkedEditing/linkedEditing.ts index 9c984b987b7..441460812f4 100644 --- a/src/vs/editor/contrib/linkedEditing/linkedEditing.ts +++ b/src/vs/editor/contrib/linkedEditing/linkedEditing.ts @@ -220,6 +220,7 @@ export class LinkedEditingContribution extends Disposable implements IEditorCont } try { + this._editor.popUndoStop(); this._ignoreChangeEvent = true; const prevEditOperationType = this._editor._getViewModel().getPrevEditOperationType(); this._editor.executeEdits('linkedEditing', edits); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 012344fa2da..2cb6913f72a 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1890,11 +1890,15 @@ declare namespace monaco.editor { */ detectIndentation(defaultInsertSpaces: boolean, defaultTabSize: number): void; /** - * Push a stack element onto the undo stack. This acts as an undo/redo point. - * The idea is to use `pushEditOperations` to edit the model and then to - * `pushStackElement` to create an undo/redo stop point. + * Close the current undo-redo element. + * This offers a way to create an undo/redo stop point. */ pushStackElement(): void; + /** + * Open the current undo-redo element. + * This offers a way to remove the current undo/redo stop point. + */ + popStackElement(): void; /** * Push edit operations, basically editing the model. This is the preferred way * of editing the model. The edit operations will land on the undo stack. @@ -4740,9 +4744,13 @@ declare namespace monaco.editor { */ executeCommand(source: string | null | undefined, command: ICommand): void; /** - * Push an "undo stop" in the undo-redo stack. + * Create an "undo stop" in the undo-redo stack. */ pushUndoStop(): boolean; + /** + * Remove the "undo stop" in the undo-redo stack. + */ + popUndoStop(): boolean; /** * Execute edits on the editor. * The edits will land on the undo-redo stack, but no "undo stop" will be pushed. From b617b725a06169c39dcae398ee7c21d44bebe6b2 Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 3 Dec 2020 16:18:51 -0800 Subject: [PATCH 103/200] update notebook execute kb shortcut tooltip for windows. --- .../contrib/notebook/browser/view/renderers/cellWidgets.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets.ts index 5560bbeb119..6be1604eea1 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets.ts @@ -12,6 +12,7 @@ import { toErrorMessage } from 'vs/base/common/errorMessage'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { isWindows } from 'vs/base/common/platform'; import { extUri } from 'vs/base/common/resources'; import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver'; import { IDimension } from 'vs/editor/common/editorCommon'; @@ -352,8 +353,8 @@ export function getExecuteCellPlaceholder(viewCell: BaseCellViewModel) { command: undefined, // text: `${keybinding?.getLabel() || 'Ctrl + Enter'} to run`, // tooltip: `${keybinding?.getLabel() || 'Ctrl + Enter'} to run`, - text: 'Ctrl + Enter to run', - tooltip: 'Ctrl + Enter to run', + text: isWindows ? 'Ctrl + Alt + Enter' : 'Ctrl + Enter to run', + tooltip: isWindows ? 'Ctrl + Alt + Enter' : 'Ctrl + Enter to run', visible: true, opacity: '0.7' }; From ff824f2776bad21c65c96cb9b7a13c7269c6f8b5 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 3 Dec 2020 16:32:45 -0800 Subject: [PATCH 104/200] Bump actions --- .github/workflows/author-verified.yml | 2 +- .github/workflows/commands.yml | 2 +- .github/workflows/deep-classifier-monitor.yml | 2 +- .github/workflows/deep-classifier-runner.yml | 2 +- .github/workflows/deep-classifier-scraper.yml | 2 +- .github/workflows/english-please.yml | 2 +- .github/workflows/feature-request.yml | 2 +- .github/workflows/latest-release-monitor.yml | 2 +- .github/workflows/locker.yml | 2 +- .github/workflows/needs-more-info-closer.yml | 2 +- .github/workflows/on-label.yml | 2 +- .github/workflows/on-open.yml | 2 +- .github/workflows/release-pipeline-labeler.yml | 2 +- .github/workflows/test-plan-item-validator.yml | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/author-verified.yml b/.github/workflows/author-verified.yml index a066c194d99..6924d9650af 100644 --- a/.github/workflows/author-verified.yml +++ b/.github/workflows/author-verified.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@v2 with: repository: "microsoft/vscode-github-triage-actions" - ref: v40 + ref: v41 path: ./actions - name: Install Actions if: github.event_name != 'issues' || contains(github.event.issue.labels.*.name, 'author-verification-requested') diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml index bda1b25092d..c2b8f95e0e6 100644 --- a/.github/workflows/commands.yml +++ b/.github/workflows/commands.yml @@ -13,7 +13,7 @@ jobs: with: repository: "microsoft/vscode-github-triage-actions" path: ./actions - ref: v40 + ref: v41 - name: Install Actions run: npm install --production --prefix ./actions - name: Run Commands diff --git a/.github/workflows/deep-classifier-monitor.yml b/.github/workflows/deep-classifier-monitor.yml index 439d2f2a46b..2734f6b7892 100644 --- a/.github/workflows/deep-classifier-monitor.yml +++ b/.github/workflows/deep-classifier-monitor.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v2 with: repository: "microsoft/vscode-github-triage-actions" - ref: v40 + ref: v41 path: ./actions - name: Install Actions run: npm install --production --prefix ./actions diff --git a/.github/workflows/deep-classifier-runner.yml b/.github/workflows/deep-classifier-runner.yml index ffa11badc9c..1aaf05a875d 100644 --- a/.github/workflows/deep-classifier-runner.yml +++ b/.github/workflows/deep-classifier-runner.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v2 with: repository: "microsoft/vscode-github-triage-actions" - ref: v40 + ref: v41 path: ./actions - name: Install Actions run: npm install --production --prefix ./actions diff --git a/.github/workflows/deep-classifier-scraper.yml b/.github/workflows/deep-classifier-scraper.yml index 1ce6faed4b2..42b5f1b6335 100644 --- a/.github/workflows/deep-classifier-scraper.yml +++ b/.github/workflows/deep-classifier-scraper.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v2 with: repository: "microsoft/vscode-github-triage-actions" - ref: v40 + ref: v41 path: ./actions - name: Install Actions run: npm install --production --prefix ./actions diff --git a/.github/workflows/english-please.yml b/.github/workflows/english-please.yml index 7336c429df1..5253fb73dc8 100644 --- a/.github/workflows/english-please.yml +++ b/.github/workflows/english-please.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v2 with: repository: "microsoft/vscode-github-triage-actions" - ref: v40 + ref: v41 path: ./actions - name: Install Actions if: contains(github.event.issue.labels.*.name, '*english-please') diff --git a/.github/workflows/feature-request.yml b/.github/workflows/feature-request.yml index 4a3c30065f7..ec3bbb5e101 100644 --- a/.github/workflows/feature-request.yml +++ b/.github/workflows/feature-request.yml @@ -18,7 +18,7 @@ jobs: with: repository: "microsoft/vscode-github-triage-actions" path: ./actions - ref: v40 + ref: v41 - name: Install Actions if: github.event_name != 'issues' || contains(github.event.issue.labels.*.name, 'feature-request') run: npm install --production --prefix ./actions diff --git a/.github/workflows/latest-release-monitor.yml b/.github/workflows/latest-release-monitor.yml index 190da52ba32..b27d79fda4a 100644 --- a/.github/workflows/latest-release-monitor.yml +++ b/.github/workflows/latest-release-monitor.yml @@ -14,7 +14,7 @@ jobs: with: repository: "microsoft/vscode-github-triage-actions" path: ./actions - ref: v40 + ref: v41 - name: Install Actions run: npm install --production --prefix ./actions - name: Install Storage Module diff --git a/.github/workflows/locker.yml b/.github/workflows/locker.yml index abfce92748b..dca0f5be6f6 100644 --- a/.github/workflows/locker.yml +++ b/.github/workflows/locker.yml @@ -14,7 +14,7 @@ jobs: with: repository: "microsoft/vscode-github-triage-actions" path: ./actions - ref: v40 + ref: v41 - name: Install Actions run: npm install --production --prefix ./actions - name: Run Locker diff --git a/.github/workflows/needs-more-info-closer.yml b/.github/workflows/needs-more-info-closer.yml index 3475b3ae878..75b7af42393 100644 --- a/.github/workflows/needs-more-info-closer.yml +++ b/.github/workflows/needs-more-info-closer.yml @@ -14,7 +14,7 @@ jobs: with: repository: "microsoft/vscode-github-triage-actions" path: ./actions - ref: v40 + ref: v41 - name: Install Actions run: npm install --production --prefix ./actions - name: Run Needs More Info Closer diff --git a/.github/workflows/on-label.yml b/.github/workflows/on-label.yml index f06ba0f4ea0..67b8ec94ced 100644 --- a/.github/workflows/on-label.yml +++ b/.github/workflows/on-label.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v2 with: repository: "microsoft/vscode-github-triage-actions" - ref: v40 + ref: v41 path: ./actions - name: Install Actions run: npm install --production --prefix ./actions diff --git a/.github/workflows/on-open.yml b/.github/workflows/on-open.yml index 9e9076c11fa..ebfa1cb3445 100644 --- a/.github/workflows/on-open.yml +++ b/.github/workflows/on-open.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v2 with: repository: "microsoft/vscode-github-triage-actions" - ref: v40 + ref: v41 path: ./actions - name: Install Actions run: npm install --production --prefix ./actions diff --git a/.github/workflows/release-pipeline-labeler.yml b/.github/workflows/release-pipeline-labeler.yml index b4a4f355fb5..e5ea1a26b81 100644 --- a/.github/workflows/release-pipeline-labeler.yml +++ b/.github/workflows/release-pipeline-labeler.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v2 with: repository: "microsoft/vscode-github-triage-actions" - ref: v40 + ref: v41 path: ./actions - name: Checkout Repo if: github.event_name != 'issues' diff --git a/.github/workflows/test-plan-item-validator.yml b/.github/workflows/test-plan-item-validator.yml index 57fcaa53165..6c2752107bc 100644 --- a/.github/workflows/test-plan-item-validator.yml +++ b/.github/workflows/test-plan-item-validator.yml @@ -14,7 +14,7 @@ jobs: with: repository: "microsoft/vscode-github-triage-actions" path: ./actions - ref: v40 + ref: v41 - name: Install Actions if: contains(github.event.issue.labels.*.name, 'testplan-item') || contains(github.event.issue.labels.*.name, 'invalid-testplan-item') run: npm install --production --prefix ./actions From ff66544ada8e87a5ec75271b0d606c0c1b425afc Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 3 Dec 2020 16:48:39 -0800 Subject: [PATCH 105/200] Allow using upper case hex characters for color --- src/vs/editor/contrib/suggest/suggestWidgetRenderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/suggest/suggestWidgetRenderer.ts b/src/vs/editor/contrib/suggest/suggestWidgetRenderer.ts index 4acc3c1326a..26cdc77ae04 100644 --- a/src/vs/editor/contrib/suggest/suggestWidgetRenderer.ts +++ b/src/vs/editor/contrib/suggest/suggestWidgetRenderer.ts @@ -33,7 +33,7 @@ export const suggestMoreInfoIcon = registerIcon('suggest-more-info', Codicon.che const _completionItemColor = new class ColorExtractor { - private static _regexRelaxed = /(#([\da-f]{3}){1,2}|(rgb|hsl)a\(\s*(\d{1,3}%?\s*,\s*){3}(1|0?\.\d+)\)|(rgb|hsl)\(\s*\d{1,3}%?(\s*,\s*\d{1,3}%?){2}\s*\))/; + private static _regexRelaxed = /(#([\da-fA-F]{3}){1,2}|(rgb|hsl)a\(\s*(\d{1,3}%?\s*,\s*){3}(1|0?\.\d+)\)|(rgb|hsl)\(\s*\d{1,3}%?(\s*,\s*\d{1,3}%?){2}\s*\))/; private static _regexStrict = new RegExp(`^${ColorExtractor._regexRelaxed.source}$`, 'i'); extract(item: CompletionItem, out: string[]): boolean { From c70d984fa2488cd589810d67f6695eafad87b137 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 1 Dec 2020 10:07:44 -0800 Subject: [PATCH 106/200] debug: bump js-debug --- product.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product.json b/product.json index d413a31fc43..ee6e68b480e 100644 --- a/product.json +++ b/product.json @@ -91,7 +91,7 @@ }, { "name": "ms-vscode.js-debug", - "version": "1.51.0", + "version": "1.52.1", "repo": "https://github.com/microsoft/vscode-js-debug", "metadata": { "id": "25629058-ddac-4e17-abba-74678e126c5d", From 63137db51ca56394a27bedd1f315fac73a9e29cd Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 3 Dec 2020 22:07:19 -0800 Subject: [PATCH 107/200] debug: fix auto attach not turning on if reselecting current state Fixes https://github.com/microsoft/vscode/issues/111021 --- extensions/debug-auto-launch/src/extension.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/extensions/debug-auto-launch/src/extension.ts b/extensions/debug-auto-launch/src/extension.ts index 440b3296e57..b47641f2db2 100644 --- a/extensions/debug-auto-launch/src/extension.ts +++ b/extensions/debug-auto-launch/src/extension.ts @@ -156,7 +156,7 @@ async function toggleAutoAttachSetting(context: vscode.ExtensionContext, scope?: quickPick.show(); - const result = await new Promise(resolve => { + let result = await new Promise(resolve => { quickPick.onDidAccept(() => resolve(quickPick.selectedItems[0])); quickPick.onDidHide(() => resolve(undefined)); quickPick.onDidTriggerButton(() => { @@ -179,7 +179,11 @@ async function toggleAutoAttachSetting(context: vscode.ExtensionContext, scope?: } if ('state' in result) { - section.update(SETTING_STATE, result.state, scope); + if (result.state !== current) { + section.update(SETTING_STATE, result.state, scope); + } else if (isTemporarilyDisabled) { + result = { setTempDisabled: false }; + } } if ('setTempDisabled' in result) { From c2f68baa78d90f135cc6800cfa7e7140d6d09933 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 3 Dec 2020 22:44:41 -0800 Subject: [PATCH 108/200] search: fix handle empty results from ripgrep https://github.com/microsoft/vscode/issues/100569 --- .../search/node/ripgrepTextSearchEngine.ts | 12 +++++++++ .../test/node/ripgrepTextSearchEngine.test.ts | 27 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts b/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts index 53c6ae8fd67..074d3528f29 100644 --- a/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts +++ b/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts @@ -283,6 +283,18 @@ export class RipgrepParser extends EventEmitter { let prevMatchEnd = 0; let prevMatchEndCol = 0; let prevMatchEndLine = lineNumber; + + // it looks like certain regexes can match a line, but cause rg to not + // emit any specific submatches for that line. + // https://github.com/microsoft/vscode/issues/100569#issuecomment-738496991 + if (data.submatches.length === 0) { + data.submatches.push( + fullText.length + ? { start: 0, end: 1, match: { text: fullText[0] } } + : { start: 0, end: 0, match: { text: '' } } + ); + } + const ranges = coalesce(data.submatches.map((match, i) => { if (this.hitLimit) { return null; diff --git a/src/vs/workbench/services/search/test/node/ripgrepTextSearchEngine.test.ts b/src/vs/workbench/services/search/test/node/ripgrepTextSearchEngine.test.ts index 9e15c6dc9bb..3815dee816b 100644 --- a/src/vs/workbench/services/search/test/node/ripgrepTextSearchEngine.test.ts +++ b/src/vs/workbench/services/search/test/node/ripgrepTextSearchEngine.test.ts @@ -226,5 +226,32 @@ suite('RipgrepTextSearchEngine', () => { } ]); }); + + + test('empty result (#100569)', () => { + testParser( + [ + makeRgMatch('file1.js', 'foobar', 4, []), + makeRgMatch('file1.js', '', 5, []), + ], + [ + { + preview: { + text: 'foobar', + matches: [new Range(0, 0, 0, 1)] + }, + uri: joinPath(TEST_FOLDER, 'file1.js'), + ranges: [new Range(3, 0, 3, 1)] + }, + { + preview: { + text: '', + matches: [new Range(0, 0, 0, 0)] + }, + uri: joinPath(TEST_FOLDER, 'file1.js'), + ranges: [new Range(4, 0, 4, 0)] + } + ]); + }); }); }); From 6a58335d0278f34281bb75351d832e8d551d3a73 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 4 Dec 2020 09:15:16 +0100 Subject: [PATCH 109/200] explorerViewer drop await --- .../workbench/contrib/files/browser/views/explorerViewer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 6ec1d861c37..9e8330b3dd8 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -982,7 +982,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { } } - drop(data: IDragAndDropData, target: ExplorerItem | undefined, targetIndex: number | undefined, originalEvent: DragEvent): void { + async drop(data: IDragAndDropData, target: ExplorerItem | undefined, targetIndex: number | undefined, originalEvent: DragEvent): Promise { this.compressedDropTargetDisposable.dispose(); // Find compressed target @@ -1031,7 +1031,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { this.progressService.withProgress({ location: VIEW_ID, delay: 500 }, () => dropPromise); } else { try { - this.handleExternalDrop(resolvedTarget, originalEvent, cts.token); + await this.handleExternalDrop(resolvedTarget, originalEvent, cts.token); } catch (error) { this.notificationService.warn(error); } From 7256c3ab262940e62fc755ad25758ba7c1875a52 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 4 Dec 2020 10:32:26 +0100 Subject: [PATCH 110/200] :lipstick: code lens font --- src/vs/editor/contrib/codelens/codelensController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/codelens/codelensController.ts b/src/vs/editor/contrib/codelens/codelensController.ts index 9b3102c61b0..c2ec93d9f7c 100644 --- a/src/vs/editor/contrib/codelens/codelensController.ts +++ b/src/vs/editor/contrib/codelens/codelensController.ts @@ -103,7 +103,7 @@ export class CodeLensContribution implements IEditorContribution { .monaco-editor .codelens-decoration.${this._styleClassName} span.codicon { line-height: ${codeLensHeight}px; font-size: ${fontSize}px; } `; if (fontFamily) { - newStyle += `.monaco-editor .codelens-decoration.${this._styleClassName} { font-family: ${fontFamily}}`; + newStyle += `.monaco-editor .codelens-decoration.${this._styleClassName} { font-family: '${fontFamily}}'`; } this._styleElement.textContent = newStyle; From 5e350b1b79675cecdff224eb00f7bf62ae8789fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 4 Dec 2020 10:36:27 +0100 Subject: [PATCH 111/200] build: create asset should still try to add asset --- build/azure-pipelines/common/createAsset.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/build/azure-pipelines/common/createAsset.ts b/build/azure-pipelines/common/createAsset.ts index d7e62629cb8..127993e6230 100644 --- a/build/azure-pipelines/common/createAsset.ts +++ b/build/azure-pipelines/common/createAsset.ts @@ -93,16 +93,12 @@ async function main(): Promise { const blobExists = await doesAssetExist(blobService, quality, blobName); if (blobExists) { - console.log(`Blob ${quality}, ${blobName} already exists, not publishing again.`); - return; + console.log(`Blob ${quality}, ${blobName} already exists, not uploading again.`); + } else { + await uploadBlob(blobService, quality, blobName, filePath, fileName); + console.log('Blobs successfully uploaded.'); } - console.log('Uploading blobs to Azure storage...'); - - await uploadBlob(blobService, quality, blobName, filePath, fileName); - - console.log('Blobs successfully uploaded.'); - const asset: Asset = { platform, type, From 60bf040b98f966dcc7b25380c587abd9ab13dc06 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 4 Dec 2020 10:47:46 +0100 Subject: [PATCH 112/200] workaround for https://github.com/microsoft/vscode/issues/111871, fixes https://github.com/microsoft/vscode/issues/111666 --- .../services/extensionManagement/browser/extensionBisect.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts b/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts index 9498ec70955..7a93a52904d 100644 --- a/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts +++ b/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts @@ -21,6 +21,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue'; +import { timeout } from 'vs/base/common/async'; // --- bisect service @@ -288,7 +289,8 @@ registerAction2(class extends Action2 { await extensionEnablementService.disableExtension({ id: done.id }, undefined); } if (res.choice === 0) { - await issueService.openReporter({ extensionId: done.id }); + issueService.openReporter({ extensionId: done.id }); + await timeout(750); // workaround for https://github.com/microsoft/vscode/issues/111871 } } await bisectService.reset(); From 6a1ad5b9b8fd6260ad98c613101fdff9c55c7400 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 4 Dec 2020 10:53:13 +0100 Subject: [PATCH 113/200] :lipstick: code lens font fix --- src/vs/editor/contrib/codelens/codelensController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/codelens/codelensController.ts b/src/vs/editor/contrib/codelens/codelensController.ts index c2ec93d9f7c..3fddfdff3c1 100644 --- a/src/vs/editor/contrib/codelens/codelensController.ts +++ b/src/vs/editor/contrib/codelens/codelensController.ts @@ -103,7 +103,7 @@ export class CodeLensContribution implements IEditorContribution { .monaco-editor .codelens-decoration.${this._styleClassName} span.codicon { line-height: ${codeLensHeight}px; font-size: ${fontSize}px; } `; if (fontFamily) { - newStyle += `.monaco-editor .codelens-decoration.${this._styleClassName} { font-family: '${fontFamily}}'`; + newStyle += `.monaco-editor .codelens-decoration.${this._styleClassName} { font-family: '${fontFamily}'}`; } this._styleElement.textContent = newStyle; From 0c947cb4ee4a35f04aa6c5117a9727be35b3c828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 4 Dec 2020 11:43:10 +0100 Subject: [PATCH 114/200] fixes #96264 --- extensions/git/src/commands.ts | 6 +++--- extensions/git/src/repository.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index f3b830a6b04..2c24d9095b4 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -54,7 +54,7 @@ class CheckoutRemoteHeadItem extends CheckoutItem { return localize('remote branch at', "Remote branch at {0}", this.shortCommit); } - async run(repository: Repository): Promise { + async run(repository: Repository, opts?: { detached?: boolean }): Promise { if (!this.ref.name) { return; } @@ -62,9 +62,9 @@ class CheckoutRemoteHeadItem extends CheckoutItem { const branches = await repository.findTrackingBranches(this.ref.name); if (branches.length > 0) { - await repository.checkout(branches[0].name!); + await repository.checkout(branches[0].name!, opts); } else { - await repository.checkoutTracking(this.ref.name); + await repository.checkoutTracking(this.ref.name, opts); } } } diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index f7948563a01..87f24395d6d 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -1264,8 +1264,8 @@ export class Repository implements Disposable { await this.run(Operation.Checkout, () => this.repository.checkout(treeish, [], opts)); } - async checkoutTracking(treeish: string): Promise { - await this.run(Operation.CheckoutTracking, () => this.repository.checkout(treeish, [], { track: true })); + async checkoutTracking(treeish: string, opts: { detached?: boolean } = {}): Promise { + await this.run(Operation.CheckoutTracking, () => this.repository.checkout(treeish, [], { ...opts, track: true })); } async findTrackingBranches(upstreamRef: string): Promise { From 6ed64df49277a45dcb87dade020b6c43c8c26684 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 4 Dec 2020 11:51:35 +0100 Subject: [PATCH 115/200] repl: font family --- src/vs/workbench/contrib/debug/browser/repl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 16593506851..74467fa8078 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -305,7 +305,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { if (this.styleElement) { const debugConsole = this.configurationService.getValue('debug').console; const fontSize = debugConsole.fontSize; - const fontFamily = debugConsole.fontFamily === 'default' ? 'var(--monaco-monospace-font)' : debugConsole.fontFamily; + const fontFamily = debugConsole.fontFamily === 'default' ? 'var(--monaco-monospace-font)' : `'${debugConsole.fontFamily}'`; const lineHeight = debugConsole.lineHeight ? `${debugConsole.lineHeight}px` : '1.4em'; const backgroundColor = this.themeService.getColorTheme().getColor(this.getBackgroundColor()); From 8f410da37f1bddb0462a790f59a3f1dda19f7bab Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 4 Dec 2020 11:57:07 +0100 Subject: [PATCH 116/200] Revert "fixes #110353" This reverts commit f27d73be72368973bb8970015f417332c4d79b83. --- .../files/electron-sandbox/fileActions.contribution.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts b/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts index 8fdd7c5b600..e4716da51f5 100644 --- a/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts @@ -14,6 +14,8 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { getMultiSelectedResources } from 'vs/workbench/contrib/files/browser/files'; +import { IListService } from 'vs/platform/list/browser/listService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { revealResourcesInOS } from 'vs/workbench/contrib/files/electron-sandbox/fileCommands'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; @@ -35,9 +37,8 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ win: { primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_R }, - handler: (accessor: ServicesAccessor, _resource: URI | object) => { - const explorerService = accessor.get(IExplorerService); - const resources = explorerService.getContext(false).map(item => item.resource); + handler: (accessor: ServicesAccessor, resource: URI | object) => { + const resources = getMultiSelectedResources(resource, accessor.get(IListService), accessor.get(IEditorService), accessor.get(IExplorerService)); revealResourcesInOS(resources, accessor.get(INativeHostService), accessor.get(INotificationService), accessor.get(IWorkspaceContextService)); } }); From de3dd1383ca5528ede42e01b9c6b77579f8e62fd Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 4 Dec 2020 12:03:39 +0100 Subject: [PATCH 117/200] Active indent lines do not render in High Contrast theme. Fixes #111137 --- .../theme-defaults/themes/hc_black_defaults.json | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/extensions/theme-defaults/themes/hc_black_defaults.json b/extensions/theme-defaults/themes/hc_black_defaults.json index d0382cec294..ea03fb3fa41 100644 --- a/extensions/theme-defaults/themes/hc_black_defaults.json +++ b/extensions/theme-defaults/themes/hc_black_defaults.json @@ -9,21 +9,14 @@ "statusBarItem.remoteBackground": "#00000000", "sideBarTitle.foreground": "#FFFFFF" }, - "settings": [ - { - "settings": { - "foreground": "#FFFFFF", - "background": "#000000" - } - }, + "tokenColors": [ { "scope": [ "meta.embedded", "source.groovy.embedded" ], "settings": { - "foreground": "#FFFFFF", - "background": "#000000" + "foreground": "#FFFFFF" } }, { From 2e3236827e58c58c91917cffd17d3ab88e772ee7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 4 Dec 2020 12:47:27 +0100 Subject: [PATCH 118/200] suppress refactor preview from onWill-handler, workaround for https://github.com/microsoft/vscode/issues/111873 --- src/vs/editor/browser/services/bulkEditService.ts | 1 + src/vs/workbench/api/browser/mainThreadBulkEdits.ts | 8 +++++++- .../workbench/contrib/bulkEdit/browser/bulkEditService.ts | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/browser/services/bulkEditService.ts b/src/vs/editor/browser/services/bulkEditService.ts index 6b0867d496c..a9e8b99dc6f 100644 --- a/src/vs/editor/browser/services/bulkEditService.ts +++ b/src/vs/editor/browser/services/bulkEditService.ts @@ -69,6 +69,7 @@ export interface IBulkEditOptions { progress?: IProgress; token?: CancellationToken; showPreview?: boolean; + suppressPreview?: boolean; label?: string; quotableLabel?: string; undoRedoSource?: UndoRedoSource; diff --git a/src/vs/workbench/api/browser/mainThreadBulkEdits.ts b/src/vs/workbench/api/browser/mainThreadBulkEdits.ts index 5e1331caaad..70fb045d7aa 100644 --- a/src/vs/workbench/api/browser/mainThreadBulkEdits.ts +++ b/src/vs/workbench/api/browser/mainThreadBulkEdits.ts @@ -39,6 +39,12 @@ export class MainThreadBulkEdits implements MainThreadBulkEditsShape { $tryApplyWorkspaceEdit(dto: IWorkspaceEditDto, undoRedoGroupId?: number): Promise { const edits = reviveWorkspaceEditDto2(dto); - return this._bulkEditService.apply(edits, { undoRedoGroupId }).then(() => true, _err => false); + return this._bulkEditService.apply(edits, { + // having a undoRedoGroupId means that this is a nested workspace edit, + // e.g one from a onWill-handler and for now we need to forcefully suppress + // refactor previewing, see: https://github.com/microsoft/vscode/issues/111873#issuecomment-738739852 + undoRedoGroupId, + suppressPreview: typeof undoRedoGroupId === 'number' ? true : undefined + }).then(() => true, _err => false); } } diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts index ca55a105790..ffc54667e07 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts @@ -139,7 +139,7 @@ export class BulkEditService implements IBulkEditService { return { ariaSummary: localize('nothing', "Made no edits") }; } - if (this._previewHandler && (options?.showPreview || edits.some(value => value.metadata?.needsConfirmation))) { + if (this._previewHandler && !options?.suppressPreview && (options?.showPreview || edits.some(value => value.metadata?.needsConfirmation))) { edits = await this._previewHandler(edits, options); } From 7fcdba7fea333353783d41442cade69e7063b161 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 4 Dec 2020 14:00:36 +0100 Subject: [PATCH 119/200] Add heuristic for when to notify about forwarded port Fixes microsoft/vscode-remote-release#4133 --- .../contrib/remote/browser/remoteExplorer.ts | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts index 0c477522326..6a6252ed394 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts @@ -213,21 +213,48 @@ class ForwardedPortNotifier extends Disposable { this.lastNotifyTime.setFullYear(this.lastNotifyTime.getFullYear() - 1); } - public notify(tunnels: RemoteTunnel[]) { - if (Date.now() - this.lastNotifyTime.getTime() > ForwardedPortNotifier.COOL_DOWN) { - this.showNotification(tunnels); + public async notify(tunnels: RemoteTunnel[]) { + const tunnel = await this.portNumberHeuristicDelay(tunnels); + if (tunnel) { + if (Date.now() - this.lastNotifyTime.getTime() > ForwardedPortNotifier.COOL_DOWN) { + this.showNotification(tunnel); + } } } - private showNotification(tunnels: RemoteTunnel[]) { + private newerTunnel: RemoteTunnel | undefined; + private async portNumberHeuristicDelay(tunnels: RemoteTunnel[]): Promise { if (tunnels.length === 0) { return; } tunnels = tunnels.sort((a, b) => a.tunnelRemotePort - b.tunnelRemotePort); const firstTunnel = tunnels.shift()!; - const address = makeAddress(firstTunnel.tunnelRemoteHost, firstTunnel.tunnelRemotePort); + // Heuristic. + if (firstTunnel.tunnelRemotePort % 1000 === 0) { + this.newerTunnel = firstTunnel; + return firstTunnel; + // 9229 is the node inspect port + } else if (firstTunnel.tunnelRemotePort < 10000 && firstTunnel.tunnelRemotePort !== 9229) { + this.newerTunnel = firstTunnel; + return firstTunnel; + } + + this.newerTunnel = undefined; + return new Promise(resolve => { + setTimeout(() => { + if (this.newerTunnel) { + resolve(undefined); + } else { + resolve(firstTunnel); + } + }, 3000); + }); + } + + private showNotification(tunnel: RemoteTunnel) { + const address = makeAddress(tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort); const message = nls.localize('remote.tunnelsView.automaticForward', "Your service running on port {0} is available. [See all forwarded ports](command:{1}.focus)", - firstTunnel.tunnelRemotePort, TunnelPanel.ID); + tunnel.tunnelRemotePort, TunnelPanel.ID); const browserChoice: IPromptChoice = { label: OpenPortInBrowserAction.LABEL, run: () => OpenPortInBrowserAction.run(this.remoteExplorerService.tunnelModel, this.openerService, address) From d298a8d5d68f47df222cd67a7e00d94ac5a1f193 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 4 Dec 2020 15:09:50 +0100 Subject: [PATCH 120/200] Fix timing issue with environment tunnels Fixes microsoft/vscode-remote-release#4112 --- .../contrib/remote/browser/remoteExplorer.ts | 21 +++++++----- .../remote/common/remoteExplorerService.ts | 33 ++++++++++++------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts index 6a6252ed394..3813ddcc697 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts @@ -348,24 +348,24 @@ class LinuxAutomaticPortForwarding extends Disposable { ) { super(); this.notifier = new ForwardedPortNotifier(notificationService, remoteExplorerService, openerService); - this._register(configurationService.onDidChangeConfiguration((e) => { + this._register(configurationService.onDidChangeConfiguration(async (e) => { if (e.affectsConfiguration(PORT_AUTO_FORWARD_SETTING)) { - this.startStopCandidateListener(); + await this.startStopCandidateListener(); } })); - this.contextServiceListener = this._register(this.contextKeyService.onDidChangeContext(e => { + this.contextServiceListener = this._register(this.contextKeyService.onDidChangeContext(async (e) => { if (e.affectsSome(new Set(forwardedPortsViewEnabled.keys()))) { - this.startStopCandidateListener(); + await this.startStopCandidateListener(); } })); this.startStopCandidateListener(); } - private startStopCandidateListener() { + private async startStopCandidateListener() { if (this.configurationService.getValue(PORT_AUTO_FORWARD_SETTING)) { - this.startCandidateListener(); + await this.startCandidateListener(); } else { this.stopCandidateListener(); } @@ -378,7 +378,7 @@ class LinuxAutomaticPortForwarding extends Disposable { } } - private startCandidateListener() { + private async startCandidateListener() { if (this.candidateListener || !forwardedPortsViewEnabled.getValue(this.contextKeyService)) { return; } @@ -386,9 +386,14 @@ class LinuxAutomaticPortForwarding extends Disposable { this.contextServiceListener.dispose(); } - this.candidateListener = this._register(this.remoteExplorerService.tunnelModel.onCandidatesChanged(this.handleCandidateUpdate, this)); + if (!this.remoteExplorerService.tunnelModel.environmentTunnelsSet) { + await new Promise(resolve => this.remoteExplorerService.tunnelModel.onEnvironmentTunnelsSet(() => resolve())); + } + // Capture list of starting candidates so we don't auto forward them later. this.setInitialCandidates(); + + this.candidateListener = this._register(this.remoteExplorerService.tunnelModel.onCandidatesChanged(this.handleCandidateUpdate, this)); } private setInitialCandidates() { diff --git a/src/vs/workbench/services/remote/common/remoteExplorerService.ts b/src/vs/workbench/services/remote/common/remoteExplorerService.ts index be29f38f980..ec449745fd2 100644 --- a/src/vs/workbench/services/remote/common/remoteExplorerService.ts +++ b/src/vs/workbench/services/remote/common/remoteExplorerService.ts @@ -119,6 +119,9 @@ export class TunnelModel extends Disposable { public onCandidatesChanged: Event> = this._onCandidatesChanged.event; private _candidateFilter: ((candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>) | undefined; private tunnelRestoreValue: string | undefined; + private _onEnvironmentTunnelsSet: Emitter = new Emitter(); + public onEnvironmentTunnelsSet: Event = this._onEnvironmentTunnelsSet.event; + private _environmentTunnelsSet: boolean = false; constructor( @ITunnelService private readonly tunnelService: ITunnelService, @@ -247,16 +250,24 @@ export class TunnelModel extends Disposable { return (this.forwarded.get(key) || this.detected.get(key))?.localAddress; } - addEnvironmentTunnels(tunnels: TunnelDescription[]): void { - tunnels.forEach(tunnel => { - this.detected.set(makeAddress(tunnel.remoteAddress.host, tunnel.remoteAddress.port), { - remoteHost: tunnel.remoteAddress.host, - remotePort: tunnel.remoteAddress.port, - localAddress: typeof tunnel.localAddress === 'string' ? tunnel.localAddress : makeAddress(tunnel.localAddress.host, tunnel.localAddress.port), - closeable: false, - runningProcess: mapHasAddressLocalhostOrAllInterfaces(this._candidates, tunnel.remoteAddress.host, tunnel.remoteAddress.port)?.detail + public get environmentTunnelsSet(): boolean { + return this._environmentTunnelsSet; + } + + addEnvironmentTunnels(tunnels: TunnelDescription[] | undefined): void { + if (tunnels) { + tunnels.forEach(tunnel => { + this.detected.set(makeAddress(tunnel.remoteAddress.host, tunnel.remoteAddress.port), { + remoteHost: tunnel.remoteAddress.host, + remotePort: tunnel.remoteAddress.port, + localAddress: typeof tunnel.localAddress === 'string' ? tunnel.localAddress : makeAddress(tunnel.localAddress.host, tunnel.localAddress.port), + closeable: false, + runningProcess: mapHasAddressLocalhostOrAllInterfaces(this._candidates, tunnel.remoteAddress.host, tunnel.remoteAddress.port)?.detail + }); }); - }); + } + this._environmentTunnelsSet = true; + this._onEnvironmentTunnelsSet.fire(); this._onForwardPort.fire(); } @@ -386,9 +397,7 @@ class RemoteExplorerService implements IRemoteExplorerService { } setTunnelInformation(tunnelInformation: TunnelInformation | undefined): void { - if (tunnelInformation && tunnelInformation.environmentTunnels) { - this.tunnelModel.addEnvironmentTunnels(tunnelInformation.environmentTunnels); - } + this.tunnelModel.addEnvironmentTunnels(tunnelInformation?.environmentTunnels); } setEditable(tunnelItem: ITunnelItem | undefined, data: IEditableData | null): void { From 478c7b633f1e8ce6e2649566f6f4d76c2a807ec1 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 4 Dec 2020 15:23:39 +0100 Subject: [PATCH 121/200] Make welcome buttons look better in wide pane Fixes #111744 --- src/vs/workbench/browser/parts/views/media/views.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/browser/parts/views/media/views.css b/src/vs/workbench/browser/parts/views/media/views.css index 7ff3318d576..8f2df0476e3 100644 --- a/src/vs/workbench/browser/parts/views/media/views.css +++ b/src/vs/workbench/browser/parts/views/media/views.css @@ -68,6 +68,11 @@ margin-right: auto; } +.monaco-workbench .pane > .pane-body.wide > .welcome-view .monaco-button { + margin-left: inherit; + max-width: 260px; +} + .monaco-workbench .pane > .pane-body .welcome-view-content { padding: 0 20px 0 20px; box-sizing: border-box; From 8e5a1da05eab6cad2cfb5208098154509c97e049 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 4 Dec 2020 15:48:26 +0100 Subject: [PATCH 122/200] Update doc comment for resolveTreeItem Related to #111715 --- src/vs/vscode.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 46671b11482..e1c2dd30ccb 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -8862,6 +8862,8 @@ declare module 'vscode' { * * Will only ever be called once per TreeItem. * + * onDidChangeTreeData should not be triggered from within resolveTreeItem. + * * *Note* that this function is called when tree items are already showing in the UI. * Because of that, no property that changes the presentation (label, description, command, etc.) * can be changed. From 528ca4c9ea884058308eb477572d52b7283b6218 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 4 Dec 2020 16:13:42 +0100 Subject: [PATCH 123/200] fix duplicate imports //cc @isidorn --- .../contrib/files/electron-sandbox/fileActions.contribution.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts b/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts index e4716da51f5..72211dd04ca 100644 --- a/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts @@ -14,7 +14,7 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { getMultiSelectedResources } from 'vs/workbench/contrib/files/browser/files'; +import { getMultiSelectedResources, IExplorerService } from 'vs/workbench/contrib/files/browser/files'; import { IListService } from 'vs/platform/list/browser/listService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { revealResourcesInOS } from 'vs/workbench/contrib/files/electron-sandbox/fileCommands'; @@ -23,7 +23,6 @@ import { ResourceContextKey } from 'vs/workbench/common/resources'; import { appendToCommandPalette, appendEditorTitleContextMenuItem } from 'vs/workbench/contrib/files/browser/fileActions.contribution'; import { SideBySideEditor, EditorResourceAccessor } from 'vs/workbench/common/editor'; import { ContextKeyOrExpr } from 'vs/platform/contextkey/common/contextkey'; -import { IExplorerService } from 'vs/workbench/contrib/files/browser/files'; const REVEAL_IN_OS_COMMAND_ID = 'revealFileInOS'; const REVEAL_IN_OS_LABEL = isWindows ? nls.localize('revealInWindows', "Reveal in File Explorer") : isMacintosh ? nls.localize('revealInMac', "Reveal in Finder") : nls.localize('openContainer', "Open Containing Folder"); From b8aa4141d28dfa6ba667df8a19e9d71b13858331 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 4 Dec 2020 16:45:38 +0100 Subject: [PATCH 124/200] Fixes #111128: Do not touch current line's indentation when pressing Enter --- .../editor/common/controller/cursorTypeOperations.ts | 11 ++--------- src/vs/editor/test/browser/controller/cursor.test.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 75da04850bb..0c618026dfc 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -351,13 +351,6 @@ export class TypeOperations { if (ir) { let oldEndViewColumn = CursorColumns.visibleColumnFromColumn2(config, model, range.getEndPosition()); const oldEndColumn = range.endColumn; - - let beforeText = '\n'; - if (indentation !== config.normalizeIndentation(ir.beforeEnter)) { - beforeText = config.normalizeIndentation(ir.beforeEnter) + lineText.substring(indentation.length, range.startColumn - 1) + '\n'; - range = new Range(range.startLineNumber, 1, range.endLineNumber, range.endColumn); - } - const newLineContent = model.getLineContent(range.endLineNumber); const firstNonWhitespace = strings.firstNonWhitespaceIndex(newLineContent); if (firstNonWhitespace >= 0) { @@ -367,7 +360,7 @@ export class TypeOperations { } if (keepPosition) { - return new ReplaceCommandWithoutChangingPosition(range, beforeText + config.normalizeIndentation(ir.afterEnter), true); + return new ReplaceCommandWithoutChangingPosition(range, '\n' + config.normalizeIndentation(ir.afterEnter), true); } else { let offset = 0; if (oldEndColumn <= firstNonWhitespace + 1) { @@ -376,7 +369,7 @@ export class TypeOperations { } offset = Math.min(oldEndViewColumn + 1 - config.normalizeIndentation(ir.afterEnter).length - 1, 0); } - return new ReplaceCommandWithOffsetCursorState(range, beforeText + config.normalizeIndentation(ir.afterEnter), 0, offset, true); + return new ReplaceCommandWithOffsetCursorState(range, '\n' + config.normalizeIndentation(ir.afterEnter), 0, offset, true); } } } diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index cb202a3f872..9dc368f6998 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -4169,6 +4169,18 @@ suite('Editor Controller - Indentation Rules', () => { model.dispose(); mode.dispose(); }); + + test('issue #111128: Multicursor `Enter` issue with indentation', () => { + const model = createTextModel(' let a, b, c;', { detectIndentation: false, insertSpaces: false, tabSize: 4 }, mode.getLanguageIdentifier()); + withTestCodeEditor(null, { model: model }, (editor, viewModel) => { + editor.setSelections([ + new Selection(1, 11, 1, 11), + new Selection(1, 14, 1, 14), + ]); + viewModel.type('\n', 'keyboard'); + assert.equal(model.getValue(), ' let a,\n\t b,\n\t c;'); + }); + }); }); interface ICursorOpts { From 7413cc249353cb8c645957ab96d03c55906fd047 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 4 Dec 2020 16:50:44 +0100 Subject: [PATCH 125/200] yarn gulp vscode --- build/gulpfile.vscode.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 1d02cbe067a..42a9c2b2709 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -338,7 +338,7 @@ BUILD_TARGETS.forEach(buildTarget => { const arch = buildTarget.arch; const opts = buildTarget.opts; - ['', 'min'].forEach(minified => { + const [vscode, vscodeMin] = ['', 'min'].map(minified => { const sourceFolderName = `out-vscode${dashed(minified)}`; const destinationFolderName = `VSCode${dashed(platform)}${dashed(arch)}`; @@ -355,7 +355,14 @@ BUILD_TARGETS.forEach(buildTarget => { vscodeTaskCI )); gulp.task(vscodeTask); + + return vscodeTask; }); + + if (process.platform === platform && process.arch === arch) { + gulp.task(task.define('vscode', task.series(vscode))); + gulp.task(task.define('vscode-min', task.series(vscodeMin))); + } }); // Transifex Localizations From 9254ec3b286d8b6dc31ac4c04ee1d897c839c5f0 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 4 Dec 2020 16:53:03 +0100 Subject: [PATCH 126/200] fixes #111577 --- src/vs/workbench/contrib/files/browser/fileActions.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 6261006fef3..46aacd31f37 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -1025,7 +1025,7 @@ export const cutFileHandler = async (accessor: ServicesAccessor) => { }; export const DOWNLOAD_COMMAND_ID = 'explorer.download'; -const downloadFileHandler = (accessor: ServicesAccessor) => { +const downloadFileHandler = async (accessor: ServicesAccessor) => { const logService = accessor.get(ILogService); const fileService = accessor.get(IFileService); const fileDialogService = accessor.get(IFileDialogService); @@ -1037,7 +1037,7 @@ const downloadFileHandler = (accessor: ServicesAccessor) => { const cts = new CancellationTokenSource(); - const downloadPromise = progressService.withProgress({ + await progressService.withProgress({ location: ProgressLocation.Window, delay: 800, cancellable: isWeb, @@ -1257,9 +1257,6 @@ const downloadFileHandler = (accessor: ServicesAccessor) => { } })); }, () => cts.dispose(true)); - - // Also indicate progress in the files view - progressService.withProgress({ location: VIEW_ID, delay: 800 }, () => downloadPromise); }; CommandsRegistry.registerCommand({ From acbe8f273e8555c78761fdab0e7ad17385040b12 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 4 Dec 2020 17:21:36 +0100 Subject: [PATCH 127/200] Only render `vscode-remote://` extensions as remote --- .../extensions/browser/abstractRuntimeExtensionsEditor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/abstractRuntimeExtensionsEditor.ts b/src/vs/workbench/contrib/extensions/browser/abstractRuntimeExtensionsEditor.ts index a00d0ce22bb..96c54f0a83a 100644 --- a/src/vs/workbench/contrib/extensions/browser/abstractRuntimeExtensionsEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/abstractRuntimeExtensionsEditor.ts @@ -361,7 +361,7 @@ export abstract class AbstractRuntimeExtensionsEditor extends EditorPane { data.msgContainer.appendChild(el); } - if (element.description.extensionLocation.scheme !== Schemas.file) { + if (element.description.extensionLocation.scheme === Schemas.vscodeRemote) { const el = $('span', undefined, ...renderCodicons(`$(remote) ${element.description.extensionLocation.authority}`)); data.msgContainer.appendChild(el); From 97e4af4d208fac6c4c9b59dea541f8cfe49cb741 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 4 Dec 2020 19:21:01 +0100 Subject: [PATCH 128/200] Fixes #111899: Maintain compatibility for context keys like `vim.use` --- src/vs/platform/contextkey/common/contextkey.ts | 8 ++++---- .../contextkey/test/common/contextkey.test.ts | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index d0f00ed362b..ea7c83876ff 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -167,22 +167,22 @@ export abstract class ContextKeyExpr { return ContextKeyInExpr.create(pieces[0].trim(), pieces[1].trim()); } - if (serializedOne.indexOf('>=') >= 0) { + if (/^[^<=>]+>=[^<=>]+$/.test(serializedOne)) { const pieces = serializedOne.split('>='); return ContextKeyGreaterEqualsExpr.create(pieces[0].trim(), pieces[1].trim()); } - if (serializedOne.indexOf('>') >= 0) { + if (/^[^<=>]+>[^<=>]+$/.test(serializedOne)) { const pieces = serializedOne.split('>'); return ContextKeyGreaterExpr.create(pieces[0].trim(), pieces[1].trim()); } - if (serializedOne.indexOf('<=') >= 0) { + if (/^[^<=>]+<=[^<=>]+$/.test(serializedOne)) { const pieces = serializedOne.split('<='); return ContextKeySmallerEqualsExpr.create(pieces[0].trim(), pieces[1].trim()); } - if (serializedOne.indexOf('<') >= 0) { + if (/^[^<=>]+<[^<=>]+$/.test(serializedOne)) { const pieces = serializedOne.split('<'); return ContextKeySmallerExpr.create(pieces[0].trim(), pieces[1].trim()); } diff --git a/src/vs/platform/contextkey/test/common/contextkey.test.ts b/src/vs/platform/contextkey/test/common/contextkey.test.ts index 5701b9dc86b..91a548be66c 100644 --- a/src/vs/platform/contextkey/test/common/contextkey.test.ts +++ b/src/vs/platform/contextkey/test/common/contextkey.test.ts @@ -255,4 +255,15 @@ suite('ContextKeyExpr', () => { checkNegate('a<=1.1', 'a > 1.1'); checkNegate('a<=b', 'a > b'); }); + + test('issue #111899: context keys can use `<` or `>` ', () => { + const actual = ContextKeyExpr.deserialize('editorTextFocus && vim.active && vim.use')!; + assert.ok(actual.equals( + ContextKeyExpr.and( + ContextKeyExpr.has('editorTextFocus'), + ContextKeyExpr.has('vim.active'), + ContextKeyExpr.has('vim.use'), + )! + )); + }); }); From dc8ac78031bd6828bbb5e81d96a7e1d3a95798d0 Mon Sep 17 00:00:00 2001 From: rebornix Date: Fri, 4 Dec 2020 11:44:55 -0800 Subject: [PATCH 129/200] fix #111910. Avoid notebook save race condition. --- .../notebook/common/notebookEditorModel.ts | 64 +++++++++++++------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts index c0746dbc1e5..1ad9b60a8b6 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts @@ -18,6 +18,7 @@ import { IFileStatWithMetadata, IFileService } from 'vs/platform/files/common/fi import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { ILabelService } from 'vs/platform/label/common/label'; import { ILogService } from 'vs/platform/log/common/log'; +import { TaskSequentializer } from 'vs/base/common/async'; export interface INotebookLoadOptions { @@ -41,6 +42,7 @@ export class NotebookEditorModel extends EditorModel implements INotebookEditorM private readonly _name: string; private readonly _workingCopyResource: URI; + private readonly saveSequentializer = new TaskSequentializer(); private _dirty = false; @@ -199,10 +201,10 @@ export class NotebookEditorModel extends EditorModel implements INotebookEditorM } private async _assertStat() { - this._logService.debug('start assert stat'); + this._logService.debug('[notebook editor model] start assert stat'); const stats = await this._resolveStats(this.resource); if (this._lastResolvedFileStat && stats && stats.mtime > this._lastResolvedFileStat.mtime) { - this._logService.debug(`noteboook file on disk is newer: + this._logService.debug(`[notebook editor model] noteboook file on disk is newer: LastResolvedStat: ${this._lastResolvedFileStat ? JSON.stringify(this._lastResolvedFileStat) : undefined}. Current stat: ${JSON.stringify(stats)} `); @@ -238,28 +240,48 @@ Current stat: ${JSON.stringify(stats)} } async save(): Promise { - this._logService.debug(`start saving notebook ${this.resource.toString()}`); - const result = await this._assertStat(); - if (result === 'none') { - return false; + let versionId = this._notebook.versionId; + this._logService.debug(`[notebook editor model] save(${versionId}) - enter with versionId ${versionId}`, this.resource.toString(true)); + + if (this.saveSequentializer.hasPending(versionId)) { + this._logService.debug(`[notebook editor model] save(${versionId}) - exit - found a pending save for versionId ${versionId}`, this.resource.toString(true)); + return this.saveSequentializer.pending.then(() => { + return true; + }); } - if (result === 'revert') { - await this.revert(); + if (this.saveSequentializer.hasPending()) { + return this.saveSequentializer.setNext(async () => { + await this.save(); + }).then(() => { + return true; + }); + } + + return this.saveSequentializer.setPending(versionId, (async () => { + const result = await this._assertStat(); + if (result === 'none') { + return; + } + + if (result === 'revert') { + await this.revert(); + return; + } + + const tokenSource = new CancellationTokenSource(); + await this._notebookService.save(this.notebook.viewType, this.notebook.uri, tokenSource.token); + this._logService.debug(`[notebook editor model] save(${versionId}) - document saved saved, start updating file stats`, this.resource.toString(true)); + const newStats = await this._resolveStats(this.resource); + this._lastResolvedFileStat = newStats; + this.setDirty(false); + })()).then(() => { return true; - } - - const tokenSource = new CancellationTokenSource(); - await this._notebookService.save(this.notebook.viewType, this.notebook.uri, tokenSource.token); - this._logService.debug(`notebook ${this.resource.toString()} saved. update file stats`); - const newStats = await this._resolveStats(this.resource); - this._lastResolvedFileStat = newStats; - this.setDirty(false); - return true; + }); } async saveAs(targetResource: URI): Promise { - this._logService.debug(`start saving notebook ${this.resource.toString()}`); + this._logService.debug(`[notebook editor model] saveAs - enter`, this.resource.toString(true)); const result = await this._assertStat(); if (result === 'none') { @@ -273,7 +295,7 @@ Current stat: ${JSON.stringify(stats)} const tokenSource = new CancellationTokenSource(); await this._notebookService.saveAs(this.notebook.viewType, this.notebook.uri, targetResource, tokenSource.token); - this._logService.debug(`notebook ${this.resource.toString()} saved. update file stats`); + this._logService.debug(`[notebook editor model] saveAs - document saved, start updating file stats`, this.resource.toString(true)); const newStats = await this._resolveStats(this.resource); this._lastResolvedFileStat = newStats; this.setDirty(false); @@ -286,9 +308,9 @@ Current stat: ${JSON.stringify(stats)} } try { - this._logService.debug(`start checking stats for ${resource.toString()}`); + this._logService.debug(`[notebook editor model] _resolveStats`, this.resource.toString(true)); const newStats = await this._fileService.resolve(this.resource, { resolveMetadata: true }); - this._logService.debug(`${resource.toString()} latest file stats: ${JSON.stringify(newStats)}`); + this._logService.debug(`[notebook editor model] _resolveStats - latest file stats: ${JSON.stringify(newStats)}`, this.resource.toString(true)); return newStats; } catch (e) { return undefined; From 39f33b588ad5dcb79ee075e2db8fcb36bfe59763 Mon Sep 17 00:00:00 2001 From: rebornix Date: Fri, 4 Dec 2020 13:15:05 -0800 Subject: [PATCH 130/200] wrap font faimly with quotes --- .../workbench/contrib/comments/browser/commentThreadWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts b/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts index 8f8c4ffcfde..ffab7e07c3a 100644 --- a/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts +++ b/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts @@ -951,7 +951,7 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget const fontInfo = this.editor.getOption(EditorOption.fontInfo); content.push(`.monaco-editor .review-widget .body code { - font-family: ${fontInfo.fontFamily}; + font-family: '${fontInfo.fontFamily}'; font-size: ${fontInfo.fontSize}px; font-weight: ${fontInfo.fontWeight}; }`); From 532ba43c78c82b24bdf94f9edde30cdf9b9bfa12 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Fri, 4 Dec 2020 14:14:31 -0800 Subject: [PATCH 131/200] Remove console.log --- .../contrib/welcome/gettingStarted/browser/gettingStarted.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts index 123bd38bbd9..637330e06db 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts @@ -176,7 +176,6 @@ export class GettingStartedPage extends Disposable { } this.editorInput.selectedTask = id; const taskToExpand = assertIsDefined(this.currentCategory.content.items.find(task => task.id === id)); - console.log(taskToExpand.media.path, taskToExpand.media.path.toString()); mediaElement.setAttribute('src', taskToExpand.media.path.toString()); mediaElement.setAttribute('alt', taskToExpand.media.altText); From 423bdb2e26307200b11867ff20fc09f52883a0db Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 4 Dec 2020 23:51:44 +0100 Subject: [PATCH 132/200] Fixes #104004: Only run tests if the tests belong to a known extension --- .../api/common/extHostExtensionService.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 328b9327207..2f3857ac7f3 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -35,6 +35,8 @@ import { IExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelServ import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; import { Emitter, Event } from 'vs/base/common/event'; import { IExtensionActivationHost, checkActivateWorkspaceContainsExtension } from 'vs/workbench/api/common/shared/workspaceContains'; +import { isEqualOrParent } from 'vs/base/common/extpath'; +import { isLinux } from 'vs/base/common/platform'; interface ITestRunner { /** Old test runner API, as exported from `vscode/lib/testrunner` */ @@ -537,6 +539,20 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme const extensionTestsPath = originalFSPath(extensionTestsLocationURI); + let knowsExtension = false; + for (const extension of this._registry.getAllExtensionDescriptions()) { + if (extension.extensionLocation.scheme === Schemas.file) { + const extensionPath = originalFSPath(extension.extensionLocation); + if (isEqualOrParent(extensionTestsPath, extensionPath, !isLinux)) { + knowsExtension = true; + } + } + } + + if (!knowsExtension) { + return Promise.resolve(undefined); + } + // Require the test runner via node require from the provided path let testRunner: ITestRunner | INewTestRunner | undefined; let requireError: Error | undefined; From 962bedc4f47b26e4a6ddc917ee2a4d9445531fb9 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Fri, 4 Dec 2020 17:15:30 -0800 Subject: [PATCH 133/200] Update version to 1.53.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f4c487c9076..20019343577 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "code-oss-dev", - "version": "1.52.0", + "version": "1.53.0", "distro": "11fd6f1230738827638f000f641d01b2b178db20", "author": { "name": "Microsoft Corporation" @@ -197,4 +197,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} From 94142bd7e0dbc073fe6abf130d7b7066a7beb1d6 Mon Sep 17 00:00:00 2001 From: Robo Date: Sat, 5 Dec 2020 01:54:58 -0800 Subject: [PATCH 134/200] chore: bump electron@11.0.3 (#111931) * chore: bump electron@11.0.3 This reverts commit 155691d0bec4acfac0e3bbccb362f61278a132de. * chore: bump x64 build image * chore: rebuild remote with older gcc toolchain * chore: bump electron@11.0.3 * ci: remove condition for remote step * chore: disable an integration test --- .yarnrc | 2 +- .../darwin/continuous-build-darwin.yml | 2 +- .../darwin/helper-plugin-entitlements.plist | 10 - .../darwin/product-build-darwin.yml | 4 +- build/azure-pipelines/distro-build.yml | 2 +- build/azure-pipelines/exploration-build.yml | 2 +- .../linux/continuous-build-linux.yml | 2 +- .../linux/product-build-alpine.yml | 2 +- .../linux/product-build-linux.yml | 23 ++- .../linux/snap-build-linux.yml | 2 +- build/azure-pipelines/product-build.yml | 11 +- build/azure-pipelines/product-compile.yml | 2 +- .../publish-types/publish-types.yml | 2 +- build/azure-pipelines/sync-mooncake.yml | 2 +- .../azure-pipelines/web/product-build-web.yml | 2 +- .../win32/continuous-build-win32.yml | 2 +- .../win32/product-build-win32.yml | 2 +- build/darwin/sign.ts | 10 - cgmanifest.json | 12 +- package.json | 10 +- remote/.yarnrc | 2 +- remote/package.json | 6 +- remote/yarn.lock | 26 +-- scripts/test-integration.sh | 6 +- src/vs/code/electron-main/window.ts | 6 +- .../test/node/nativeModules.test.ts | 2 +- .../platform/menubar/electron-main/menubar.ts | 6 +- .../electron-main/webviewProtocolProvider.ts | 13 +- .../services/extensions/node/proxyResolver.ts | 2 +- yarn.lock | 187 +++++++++--------- 30 files changed, 179 insertions(+), 183 deletions(-) delete mode 100644 build/azure-pipelines/darwin/helper-plugin-entitlements.plist diff --git a/.yarnrc b/.yarnrc index 264a5e3a3d6..7b0e7edfcbf 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,3 +1,3 @@ disturl "https://electronjs.org/headers" -target "9.3.5" +target "11.0.3" runtime "electron" diff --git a/build/azure-pipelines/darwin/continuous-build-darwin.yml b/build/azure-pipelines/darwin/continuous-build-darwin.yml index 55efe5f32eb..75c28106c5e 100644 --- a/build/azure-pipelines/darwin/continuous-build-darwin.yml +++ b/build/azure-pipelines/darwin/continuous-build-darwin.yml @@ -1,7 +1,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: diff --git a/build/azure-pipelines/darwin/helper-plugin-entitlements.plist b/build/azure-pipelines/darwin/helper-plugin-entitlements.plist deleted file mode 100644 index 7cd9df032bd..00000000000 --- a/build/azure-pipelines/darwin/helper-plugin-entitlements.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.cs.allow-unsigned-executable-memory - - com.apple.security.cs.disable-library-validation - - - diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 6f7dec16aca..e2107fd73c9 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -22,7 +22,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: @@ -78,7 +78,7 @@ steps: - script: | set -e - npm install -g node-gyp@7.1.0 + npm install -g node-gyp@latest node-gyp --version displayName: Update node-gyp condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) diff --git a/build/azure-pipelines/distro-build.yml b/build/azure-pipelines/distro-build.yml index 99bad6b72cd..331fbf9675e 100644 --- a/build/azure-pipelines/distro-build.yml +++ b/build/azure-pipelines/distro-build.yml @@ -8,7 +8,7 @@ pr: steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: AzureKeyVault@1 displayName: "Azure Key Vault: Get Secrets" diff --git a/build/azure-pipelines/exploration-build.yml b/build/azure-pipelines/exploration-build.yml index 4a7acf129b3..e0bb30a7e02 100644 --- a/build/azure-pipelines/exploration-build.yml +++ b/build/azure-pipelines/exploration-build.yml @@ -6,7 +6,7 @@ trigger: none steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: AzureKeyVault@1 displayName: "Azure Key Vault: Get Secrets" diff --git a/build/azure-pipelines/linux/continuous-build-linux.yml b/build/azure-pipelines/linux/continuous-build-linux.yml index e777f821d76..44cb9829472 100644 --- a/build/azure-pipelines/linux/continuous-build-linux.yml +++ b/build/azure-pipelines/linux/continuous-build-linux.yml @@ -10,7 +10,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: diff --git a/build/azure-pipelines/linux/product-build-alpine.yml b/build/azure-pipelines/linux/product-build-alpine.yml index 9a54bc2bc8a..8108ff8193d 100644 --- a/build/azure-pipelines/linux/product-build-alpine.yml +++ b/build/azure-pipelines/linux/product-build-alpine.yml @@ -22,7 +22,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 1f7884a1c83..5d7e8cdb24f 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -22,7 +22,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: @@ -69,6 +69,13 @@ steps: targetfolder: "**/node_modules, !**/node_modules/**/node_modules" vstsFeed: "npm-vscode" + - script: | + set -e + npm install -g node-gyp@latest + node-gyp --version + displayName: Update node-gyp + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + - script: | set -e export npm_config_arch=$(NPM_ARCH) @@ -97,6 +104,14 @@ steps: displayName: Run postinstall scripts condition: and(succeeded(), eq(variables['CacheRestored'], 'true')) + - script: | + set -e + export CC=$(which gcc-4.8) + export CXX=$(which g++-4.8) + cd remote + node-gyp rebuild + displayName: Rebuild remote modules with gcc-4.8 + - script: | set -e node build/azure-pipelines/mixin @@ -112,12 +127,6 @@ steps: yarn gulp vscode-reh-web-linux-$(VSCODE_ARCH)-min-ci displayName: Build - - script: | - set -e - service xvfb start - displayName: Start xvfb - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - script: | set -e DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests" diff --git a/build/azure-pipelines/linux/snap-build-linux.yml b/build/azure-pipelines/linux/snap-build-linux.yml index f08c7b3c3e6..e0f2d2c6e2a 100644 --- a/build/azure-pipelines/linux/snap-build-linux.yml +++ b/build/azure-pipelines/linux/snap-build-linux.yml @@ -1,7 +1,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index ebe2fe6abef..2b3d87d119d 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -11,8 +11,9 @@ schedules: resources: containers: - container: vscode-x64 - image: vscodehub.azurecr.io/vscode-linux-build-agent:x64 + image: vscodehub.azurecr.io/vscode-linux-build-agent:bionic-x64 endpoint: VSCodeHub + options: --user 0:0 - container: vscode-arm64 image: vscodehub.azurecr.io/vscode-linux-build-agent:stretch-arm64 endpoint: VSCodeHub @@ -27,7 +28,7 @@ stages: jobs: - job: Compile pool: - vmImage: "Ubuntu-16.04" + vmImage: "Ubuntu-18.04" container: vscode-x64 variables: VSCODE_ARCH: x64 @@ -70,7 +71,7 @@ stages: - Compile condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false')) pool: - vmImage: "Ubuntu-16.04" + vmImage: "Ubuntu-18.04" jobs: - job: Linux condition: and(succeeded(), eq(variables['VSCODE_BUILD_LINUX'], 'true')) @@ -179,7 +180,7 @@ stages: - macOSARM64 condition: and(succeededOrFailed(), eq(variables['VSCODE_COMPILE_ONLY'], 'false')) pool: - vmImage: "Ubuntu-16.04" + vmImage: "Ubuntu-18.04" jobs: - job: SyncMooncake displayName: Sync Mooncake @@ -194,7 +195,7 @@ stages: - macOSARM64 condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), or(eq(variables['VSCODE_RELEASE'], 'true'), and(or(eq(variables['VSCODE_QUALITY'], 'insider'), eq(variables['VSCODE_QUALITY'], 'exploration')), eq(variables['Build.Reason'], 'Schedule')))) pool: - vmImage: "Ubuntu-16.04" + vmImage: "Ubuntu-18.04" jobs: - job: BuildService displayName: Build Service diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index eaf0a65e8aa..66baef772c8 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -17,7 +17,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" condition: and(succeeded(), ne(variables['CacheExists-Compilation'], 'true')) - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 diff --git a/build/azure-pipelines/publish-types/publish-types.yml b/build/azure-pipelines/publish-types/publish-types.yml index 5f1cf6c28a4..0e3f4e4daa4 100644 --- a/build/azure-pipelines/publish-types/publish-types.yml +++ b/build/azure-pipelines/publish-types/publish-types.yml @@ -9,7 +9,7 @@ pr: none steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: diff --git a/build/azure-pipelines/sync-mooncake.yml b/build/azure-pipelines/sync-mooncake.yml index 109709418ff..280c9e6372d 100644 --- a/build/azure-pipelines/sync-mooncake.yml +++ b/build/azure-pipelines/sync-mooncake.yml @@ -1,7 +1,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 33282adbe46..1beae9506eb 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -22,7 +22,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: diff --git a/build/azure-pipelines/win32/continuous-build-win32.yml b/build/azure-pipelines/win32/continuous-build-win32.yml index 87b820cb009..7bd18707381 100644 --- a/build/azure-pipelines/win32/continuous-build-win32.yml +++ b/build/azure-pipelines/win32/continuous-build-win32.yml @@ -1,7 +1,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 1992ac1affb..5c8806401d5 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -22,7 +22,7 @@ steps: - task: NodeTool@0 inputs: - versionSpec: "12.14.1" + versionSpec: "12.18.3" - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: diff --git a/build/darwin/sign.ts b/build/darwin/sign.ts index 538dc97adf1..f1908b14749 100644 --- a/build/darwin/sign.ts +++ b/build/darwin/sign.ts @@ -29,7 +29,6 @@ async function main(): Promise { const appFrameworkPath = path.join(appRoot, appName, 'Contents', 'Frameworks'); const helperAppBaseName = product.nameShort; const gpuHelperAppName = helperAppBaseName + ' Helper (GPU).app'; - const pluginHelperAppName = helperAppBaseName + ' Helper (Plugin).app'; const rendererHelperAppName = helperAppBaseName + ' Helper (Renderer).app'; const defaultOpts: codesign.SignOptions = { @@ -51,7 +50,6 @@ async function main(): Promise { // TODO(deepak1556): Incorrectly declared type in electron-osx-sign ignore: (filePath: string) => { return filePath.includes(gpuHelperAppName) || - filePath.includes(pluginHelperAppName) || filePath.includes(rendererHelperAppName); } }; @@ -63,13 +61,6 @@ async function main(): Promise { 'entitlements-inherit': path.join(baseDir, 'azure-pipelines', 'darwin', 'helper-gpu-entitlements.plist'), }; - const pluginHelperOpts: codesign.SignOptions = { - ...defaultOpts, - app: path.join(appFrameworkPath, pluginHelperAppName), - entitlements: path.join(baseDir, 'azure-pipelines', 'darwin', 'helper-plugin-entitlements.plist'), - 'entitlements-inherit': path.join(baseDir, 'azure-pipelines', 'darwin', 'helper-plugin-entitlements.plist'), - }; - const rendererHelperOpts: codesign.SignOptions = { ...defaultOpts, app: path.join(appFrameworkPath, rendererHelperAppName), @@ -78,7 +69,6 @@ async function main(): Promise { }; await codesign.signAsync(gpuHelperOpts); - await codesign.signAsync(pluginHelperOpts); await codesign.signAsync(rendererHelperOpts); await codesign.signAsync(appOpts as any); } diff --git a/cgmanifest.json b/cgmanifest.json index 656e3f821bf..5575cb4b04c 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "chromium", "repositoryUrl": "https://chromium.googlesource.com/chromium/src", - "commitHash": "894fb9eb56c6cbda65e3c3ae9ada6d4cb5850cc9" + "commitHash": "0387c513f0319231a8ca6dd0a265102af3d4455e" } }, "licenseDetail": [ @@ -40,7 +40,7 @@ "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ], "isOnlyProductionDependency": true, - "version": "83.0.4103.122" + "version": "87.0.4280.67" }, { "component": { @@ -48,11 +48,11 @@ "git": { "name": "nodejs", "repositoryUrl": "https://github.com/nodejs/node", - "commitHash": "9622fed3fb2cffcea9efff6c8cb4cc2def99d75d" + "commitHash": "e3e0927bb93ed92bcdfe81e7ad9af3d78ccc74fb" } }, "isOnlyProductionDependency": true, - "version": "12.14.1" + "version": "12.18.3" }, { "component": { @@ -60,12 +60,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "415c1f9e9b35d9599b1a8ad1200476afa47a3323" + "commitHash": "b0862a6e63173c4c919bd5ed27d257235bbfe7d2" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "9.3.5" + "version": "11.0.3" }, { "component": { diff --git a/package.json b/package.json index 20019343577..6a714c44190 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "compile-web": "gulp compile-web --max_old_space_size=4095", "watch-web": "gulp watch-web --max_old_space_size=4095", "eslint": "eslint -c .eslintrc.json --rulesdir ./build/lib/eslint --ext .ts --ext .js ./src/vs ./extensions", - "electron-rebuild": "electron-rebuild --arch=arm64 --force --version=11.0.2" + "electron-rebuild": "electron-rebuild --arch=arm64 --force --version=11.0.3" }, "dependencies": { "applicationinsights": "1.0.8", @@ -60,7 +60,7 @@ "native-is-elevated": "0.4.1", "native-keymap": "2.2.1", "native-watchdog": "1.3.0", - "node-pty": "0.10.0-beta17", + "node-pty": "0.10.0-beta18", "spdlog": "^0.11.1", "sudo-prompt": "9.1.1", "tas-client-umd": "0.1.2", @@ -112,7 +112,7 @@ "css-loader": "^3.2.0", "debounce": "^1.0.0", "deemon": "^1.4.0", - "electron": "9.3.5", + "electron": "11.0.3", "electron-rebuild": "2.0.3", "eslint": "6.8.0", "eslint-plugin-jsdoc": "^19.1.0", @@ -191,10 +191,10 @@ "url": "https://github.com/microsoft/vscode/issues" }, "optionalDependencies": { - "vscode-windows-ca-certs": "0.2.0", + "vscode-windows-ca-certs": "^0.3.0", "vscode-windows-registry": "1.0.3", "windows-foreground-love": "0.2.0", "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file diff --git a/remote/.yarnrc b/remote/.yarnrc index c1a32ce532a..cd436416b56 100644 --- a/remote/.yarnrc +++ b/remote/.yarnrc @@ -1,3 +1,3 @@ disturl "http://nodejs.org/dist" -target "12.14.1" +target "12.18.3" runtime "node" diff --git a/remote/package.json b/remote/package.json index f68deac647c..57710a189ba 100644 --- a/remote/package.json +++ b/remote/package.json @@ -12,15 +12,15 @@ "jschardet": "2.2.1", "minimist": "^1.2.5", "native-watchdog": "1.3.0", - "node-pty": "0.10.0-beta17", + "node-pty": "0.10.0-beta18", "spdlog": "^0.11.1", "tas-client-umd": "0.1.2", "vscode-nsfw": "1.2.9", "vscode-oniguruma": "1.3.1", "vscode-proxy-agent": "^0.5.2", + "vscode-regexpp": "^3.1.0", "vscode-ripgrep": "^1.11.1", "vscode-textmate": "5.2.0", - "vscode-regexpp": "^3.1.0", "xterm": "4.10.0-beta.4", "xterm-addon-search": "0.8.0-beta.3", "xterm-addon-unicode11": "0.3.0-beta.3", @@ -29,7 +29,7 @@ "yazl": "^2.4.3" }, "optionalDependencies": { - "vscode-windows-ca-certs": "0.2.0", + "vscode-windows-ca-certs": "0.3.0", "vscode-windows-registry": "1.0.2" } } diff --git a/remote/yarn.lock b/remote/yarn.lock index 22d8ebe3fc5..e15eb9d9839 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -299,15 +299,15 @@ native-watchdog@1.3.0: resolved "https://registry.yarnpkg.com/native-watchdog/-/native-watchdog-1.3.0.tgz#88cee94c9dc766b85c8506eda14c8bd8c9618e27" integrity sha512-WOjGRNGkYZ5MXsntcvCYrKtSYMaewlbCFplbcUVo9bE80LPVt8TAVFHYWB8+a6fWCGYheq21+Wtt6CJrUaCJhw== -node-addon-api@1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.6.2.tgz#d8aad9781a5cfc4132cc2fecdbdd982534265217" - integrity sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA== +node-addon-api@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.0.2.tgz#04bc7b83fd845ba785bb6eae25bc857e1ef75681" + integrity sha512-+D4s2HCnxPd5PjjI0STKwncjXTUKKqm74MDMz9OPXavjsGmjkvwgLtA5yoxJUdmpj52+2u+RrXgPipahKczMKg== -node-pty@0.10.0-beta17: - version "0.10.0-beta17" - resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.10.0-beta17.tgz#962d4a3f4dc6772385e0cad529c209cef3bc79e6" - integrity sha512-tn7EANQacnAvnOQCImvgag1DL0tVmUoY/1yIZbh3u/BBpvCcGHLZJNn7TXheodRLr6hmGSUS2VbfcUr9p0gOug== +node-pty@0.10.0-beta18: + version "0.10.0-beta18" + resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.10.0-beta18.tgz#7ed2d3f4a06b2b23fe2abdf5b41655e9dffc25d5" + integrity sha512-vpK4yB3A3VzgkvdOWegL7GcPapt45jfA4b3ejUe8k4RmqdWBRvFJngew8T3qAxmLhTkfo93psaN6izTlfkc6FA== dependencies: nan "^2.14.0" @@ -438,12 +438,12 @@ vscode-textmate@5.2.0: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== -vscode-windows-ca-certs@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/vscode-windows-ca-certs/-/vscode-windows-ca-certs-0.2.0.tgz#086f0f4de57e2760a35ac6920831bff246237115" - integrity sha512-YBrJRT0zos+Yb1Qdn73GD8QZr7pa2IE96b5Y1hmmp6XeR8aYB7Iiq5gDAF/+/AxL+caSR9KPZQ6jiYWh5biD7w== +vscode-windows-ca-certs@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/vscode-windows-ca-certs/-/vscode-windows-ca-certs-0.3.0.tgz#324e1f8ba842bbf048a39e7c0ee8fe655e9adfcc" + integrity sha512-CYrpCEKmAFQJoZNReOrelNL+VKyebOVRCqL9evrBlVcpWQDliliJgU5RggGS8FPGtQ3jAKLQt9frF0qlxYYPKA== dependencies: - node-addon-api "1.6.2" + node-addon-api "^3.0.2" vscode-windows-registry@1.0.2: version "1.0.2" diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index b82dbec1137..609a2bf6121 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -60,8 +60,10 @@ after_suite "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $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 --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR after_suite -"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR -after_suite +# TODO(deepak1556): Disable workspace test temporarily +# https://github.com/microsoft/vscode/issues/111288 +#"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR +#after_suite "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-extensions --user-data-dir=$VSCODEUSERDATADIR after_suite diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index a9f47be8153..f6b98e72c98 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -9,7 +9,7 @@ import * as nls from 'vs/nls'; import * as perf from 'vs/base/common/performance'; import { Emitter } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; -import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, nativeTheme, Event, Details } from 'electron'; +import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, nativeTheme, Event, RenderProcessGoneDetails } from 'electron'; import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService'; import { ILogService } from 'vs/platform/log/common/log'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -544,8 +544,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { } private onWindowError(error: WindowError.UNRESPONSIVE): void; - private onWindowError(error: WindowError.CRASHED, details: Details): void; - private onWindowError(error: WindowError, details?: Details): void { + private onWindowError(error: WindowError.CRASHED, details: RenderProcessGoneDetails): void; + private onWindowError(error: WindowError, details?: RenderProcessGoneDetails): void { this.logService.error(error === WindowError.CRASHED ? `[VS Code]: renderer process crashed (detail: ${details?.reason})` : '[VS Code]: detected unresponsive'); // If we run extension tests from CLI, showing a dialog is not diff --git a/src/vs/platform/environment/test/node/nativeModules.test.ts b/src/vs/platform/environment/test/node/nativeModules.test.ts index b64282f626f..34617f575bb 100644 --- a/src/vs/platform/environment/test/node/nativeModules.test.ts +++ b/src/vs/platform/environment/test/node/nativeModules.test.ts @@ -90,7 +90,7 @@ suite('Native Modules (all platforms)', () => { test('vscode-windows-ca-certs', async () => { // @ts-ignore Windows only const windowsCerts = await import('vscode-windows-ca-certs'); - const store = windowsCerts(); + const store = new windowsCerts.Crypt32(); assert.ok(windowsCerts, testErrorMessage('vscode-windows-ca-certs')); let certCount = 0; try { diff --git a/src/vs/platform/menubar/electron-main/menubar.ts b/src/vs/platform/menubar/electron-main/menubar.ts index 3039b01a1cf..90fba9c3fb1 100644 --- a/src/vs/platform/menubar/electron-main/menubar.ts +++ b/src/vs/platform/menubar/electron-main/menubar.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { isMacintosh, language } from 'vs/base/common/platform'; import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService'; -import { app, Menu, MenuItem, BrowserWindow, MenuItemConstructorOptions, WebContents, Event, KeyboardEvent } from 'electron'; +import { app, Menu, MenuItem, BrowserWindow, MenuItemConstructorOptions, WebContents, KeyboardEvent } from 'electron'; import { getTitleBarStyle, INativeRunActionInWindowRequest, INativeRunKeybindingInWindowRequest, IWindowOpenable } from 'vs/platform/windows/common/windows'; import { OpenContext } from 'vs/platform/windows/node/window'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -62,7 +62,7 @@ export class Menubar { private keybindings: { [commandId: string]: IMenubarKeybinding }; - private readonly fallbackMenuHandlers: { [id: string]: (menuItem: MenuItem, browserWindow: BrowserWindow | undefined, event: Event) => void } = Object.create(null); + private readonly fallbackMenuHandlers: { [id: string]: (menuItem: MenuItem, browserWindow: BrowserWindow | undefined, event: KeyboardEvent) => void } = Object.create(null); constructor( @IUpdateService private readonly updateService: IUpdateService, @@ -639,7 +639,7 @@ export class Menubar { private createMenuItem(label: string, click: () => void, enabled?: boolean, checked?: boolean): MenuItem; private createMenuItem(arg1: string, arg2: any, arg3?: boolean, arg4?: boolean): MenuItem { const label = this.mnemonicLabel(arg1); - const click: () => void = (typeof arg2 === 'function') ? arg2 : (menuItem: MenuItem & IMenuItemWithKeybinding, win: BrowserWindow, event: Event) => { + const click: () => void = (typeof arg2 === 'function') ? arg2 : (menuItem: MenuItem & IMenuItemWithKeybinding, win: BrowserWindow, event: KeyboardEvent) => { const userSettingsLabel = menuItem ? menuItem.userSettingsLabel : null; let commandId = arg2; if (Array.isArray(arg2)) { diff --git a/src/vs/platform/webview/electron-main/webviewProtocolProvider.ts b/src/vs/platform/webview/electron-main/webviewProtocolProvider.ts index a019d267e69..ce6233924b0 100644 --- a/src/vs/platform/webview/electron-main/webviewProtocolProvider.ts +++ b/src/vs/platform/webview/electron-main/webviewProtocolProvider.ts @@ -125,7 +125,10 @@ export class WebviewProtocolProvider extends Disposable { } } - private async handleWebviewRequest(request: Electron.Request, callback: any) { + private async handleWebviewRequest( + request: Electron.ProtocolRequest, + callback: (response: string | Electron.ProtocolResponse) => void + ) { try { const uri = URI.parse(request.url); const entry = WebviewProtocolProvider.validWebviewFilePaths.get(uri.path); @@ -144,8 +147,8 @@ export class WebviewProtocolProvider extends Disposable { } private async handleWebviewResourceRequest( - request: Electron.Request, - callback: (stream?: NodeJS.ReadableStream | Electron.StreamProtocolResponse | undefined) => void + request: Electron.ProtocolRequest, + callback: (stream: NodeJS.ReadableStream | Electron.ProtocolResponse) => void ) { try { const uri = URI.parse(request.url); @@ -220,14 +223,14 @@ export class WebviewProtocolProvider extends Disposable { if (result.type === WebviewResourceResponse.Type.AccessDenied) { console.error('Webview: Cannot load resource outside of protocol root'); - return callback({ data: null, statusCode: 401 }); + return callback({ data: undefined, statusCode: 401 }); } } } catch { // noop } - return callback({ data: null, statusCode: 404 }); + return callback({ data: undefined, statusCode: 404 }); } public didLoadResource(requestId: number, content: VSBuffer | undefined) { diff --git a/src/vs/workbench/services/extensions/node/proxyResolver.ts b/src/vs/workbench/services/extensions/node/proxyResolver.ts index 3050bc6e2d6..80177b1fad9 100644 --- a/src/vs/workbench/services/extensions/node/proxyResolver.ts +++ b/src/vs/workbench/services/extensions/node/proxyResolver.ts @@ -498,7 +498,7 @@ async function readWindowsCaCertificates() { const winCA = await import('vscode-windows-ca-certs'); let ders: any[] = []; - const store = winCA(); + const store = new winCA.Crypt32(); try { let der: any; while (der = store.next()) { diff --git a/yarn.lock b/yarn.lock index dd5e3e4eea8..8adc7c55ed3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -141,15 +141,14 @@ to-fast-properties "^2.0.0" "@electron/get@^1.0.1": - version "1.12.2" - resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.12.2.tgz#6442066afb99be08cefb9a281e4b4692b33764f3" - integrity sha512-vAuHUbfvBQpYTJ5wB7uVIDq5c/Ry0fiTBMs7lnEYAo/qXXppIVcWdfBr57u6eRnKdVso7KSiH6p/LbQAG6Izrg== + version "1.7.2" + resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.7.2.tgz#286436a9fb56ff1a1fcdf0e80131fd65f4d1e0fd" + integrity sha512-LSE4LZGMjGS9TloDx0yO44D2UTbaeKRk+QjlhWLiQlikV6J4spgDCjb6z4YIcqmPAwNzlNCnWF4dubytwI+ATA== dependencies: debug "^4.1.1" env-paths "^2.2.0" fs-extra "^8.1.0" got "^9.6.0" - progress "^2.0.3" sanitize-filename "^1.6.2" sumchecker "^3.0.1" optionalDependencies: @@ -279,9 +278,9 @@ integrity sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ== "@types/node@^12.0.12": - version "12.19.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.7.tgz#cf8b6ac088dd9182ac9a1d765f787a8d12490c04" - integrity sha512-zvjOU1g4CpPilbTDUATnZCUb/6lARMRAqzT7ILwl1P3YvU2leEcZ2+fw9+Jrw/paXB1CgQyXTrN4hWDtqT9O2A== + version "12.12.24" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.24.tgz#d4606afd8cf6c609036b854360367d1b2c78931f" + integrity sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug== "@types/node@^12.11.7": version "12.12.14" @@ -1312,10 +1311,10 @@ boolbase@~1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= -boolean@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.2.tgz#df1baa18b6a2b0e70840475e1d93ec8fe75b2570" - integrity sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g== +boolean@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.0.tgz#fab78d5907dbae6216ab46d32733bb7b76b99e76" + integrity sha512-OElxJ1lUSinuoUnkpOgLmxp0DC4ytEhODEL6QJU0NpxE/mI4rUSh8h1P1Wkvfi3xQEBcxXR2gBIPNYNuaFcAbQ== boom@4.x.x: version "4.3.1" @@ -2114,7 +2113,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@^1.5.0, concat-stream@^1.6.0, concat-stream@^1.6.2: +concat-stream@1.6.2, concat-stream@^1.5.0, concat-stream@^1.6.0: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -2237,10 +2236,10 @@ copy-webpack-plugin@^4.5.2: p-limit "^1.0.0" serialize-javascript "^1.4.0" -core-js@^3.6.5: - version "3.8.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.0.tgz#0fc2d4941cadf80538b030648bb64d230b4da0ce" - integrity sha512-W2VYNB0nwQQE7tKS7HzXd7r2y/y2SVJl4ga6oH/dnaLFzM0o2lB2P3zCkWj5Wc/zyMYjtgd5Hmhk0ObkQFZOIA== +core-js@^3.4.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.1.tgz#39d5e2e346258cc01eb7d44345b1c3c014ca3f05" + integrity sha512-186WjSik2iTGfDjfdCZAxv2ormxtKgemjC3SI6PL31qOA0j5LhTDVjHChccoc7brwLvpvLPiMyRlcO88C4l1QQ== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -2476,6 +2475,13 @@ debug@2.2.0: dependencies: ms "0.7.1" +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + debug@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -2490,13 +2496,6 @@ debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "^2.1.1" -debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -2571,9 +2570,9 @@ defaults@^1.0.3: clone "^1.0.2" defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + version "1.1.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.1.tgz#88ae694b93f67b81815a2c8c769aef6574ac8f2f" + integrity sha512-J7thop4u3mRTkYRQ+Vpfwy2G5Ehoy82I14+14W4YMDLKdWloI9gSzRbV30s/NckQGVJtPkWNcW4oMAUigTdqiQ== define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" @@ -2858,10 +2857,10 @@ electron-to-chromium@^1.2.7: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz#78ecb8a399066187bb374eede35d9c70565a803d" integrity sha1-eOy4o5kGYYe7N07t412ccFZagD0= -electron@9.3.5: - version "9.3.5" - resolved "https://registry.yarnpkg.com/electron/-/electron-9.3.5.tgz#7967146b81e6d9b484773243fd4a4f671a50b884" - integrity sha512-EPmDsp7sO0UPtw7nLD1ufse/nBskP+ifXzBgUg9psCUlapkzuwYi6pmLAzKLW/bVjwgyUKwh1OKWILWfOeLGcQ== +electron@11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/electron/-/electron-11.0.3.tgz#c29eaacda38ce561890e59906ca5f507c72b3ec4" + integrity sha512-nNfbLi7Q1xfJXOEO2adck5TS6asY4Jxc332E4Te8XfQ9hcaC3GiCdeEqk9FndNCwxhJA5Lr9jfSGRTwWebFa/w== dependencies: "@electron/get" "^1.0.1" "@types/node" "^12.0.12" @@ -3042,10 +3041,10 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== eslint-plugin-jsdoc@^19.1.0: version "19.1.0" @@ -3421,14 +3420,14 @@ extglob@^2.0.4: to-regex "^3.0.1" extract-zip@^1.0.3: - version "1.7.0" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" - integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA== + version "1.6.7" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9" + integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k= dependencies: - concat-stream "^1.6.2" - debug "^2.6.9" - mkdirp "^0.5.4" - yauzl "^2.10.0" + concat-stream "1.6.2" + debug "2.6.9" + mkdirp "0.5.1" + yauzl "2.4.1" extract-zip@^2.0.1: version "2.0.1" @@ -4092,17 +4091,17 @@ glob@^7.1.4, glob@^7.1.6: path-is-absolute "^1.0.0" global-agent@^2.0.2: - version "2.1.12" - resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.1.12.tgz#e4ae3812b731a9e81cbf825f9377ef450a8e4195" - integrity sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg== + version "2.1.7" + resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.1.7.tgz#12d7bc2b07cd862d0fa76b0f1b2c48cd5ffcf150" + integrity sha512-ooK7eqGYZku+LgnbfH/Iv0RJ74XfhrBZDlke1QSzcBt0bw1PmJcnRADPAQuFE+R45pKKDTynAr25SBasY2kvow== dependencies: - boolean "^3.0.1" - core-js "^3.6.5" + boolean "^3.0.0" + core-js "^3.4.1" es6-error "^4.1.1" - matcher "^3.0.0" - roarr "^2.15.3" - semver "^7.3.2" - serialize-error "^7.0.1" + matcher "^2.0.0" + roarr "^2.14.5" + semver "^6.3.0" + serialize-error "^5.0.0" global-modules@^1.0.0: version "1.0.0" @@ -4167,7 +4166,7 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" -globalthis@^1.0.1: +globalthis@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.1.tgz#40116f5d9c071f9e8fb0037654df1ab3a83b7ef9" integrity sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw== @@ -4683,9 +4682,9 @@ html-escaper@^2.0.0: readable-stream "^2.0.2" http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + version "4.0.3" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz#495704773277eeef6e43f9ab2c2c7d259dda25c5" + integrity sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew== http-proxy-agent@^2.1.0: version "2.1.0" @@ -5942,12 +5941,12 @@ matchdep@^2.0.0: resolve "^1.4.0" stack-trace "0.0.10" -matcher@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca" - integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng== +matcher@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-2.1.0.tgz#64e1041c15b993e23b786f93320a7474bf833c28" + integrity sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ== dependencies: - escape-string-regexp "^4.0.0" + escape-string-regexp "^2.0.0" math-expression-evaluator@^1.2.14: version "1.2.17" @@ -6110,7 +6109,12 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-response@^1.0.0, mimic-response@^1.0.1: +mimic-response@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" + integrity sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4= + +mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== @@ -6252,7 +6256,7 @@ mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkd dependencies: minimist "0.0.8" -mkdirp@^0.5.3, mkdirp@^0.5.4: +mkdirp@^0.5.3: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -6431,12 +6435,7 @@ node-abi@^2.19.1, node-abi@^2.7.0: dependencies: semver "^5.4.1" -node-addon-api@1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.6.2.tgz#d8aad9781a5cfc4132cc2fecdbdd982534265217" - integrity sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA== - -node-addon-api@^3.0.0: +node-addon-api@^3.0.0, node-addon-api@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.0.2.tgz#04bc7b83fd845ba785bb6eae25bc857e1ef75681" integrity sha512-+D4s2HCnxPd5PjjI0STKwncjXTUKKqm74MDMz9OPXavjsGmjkvwgLtA5yoxJUdmpj52+2u+RrXgPipahKczMKg== @@ -6502,10 +6501,10 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -node-pty@0.10.0-beta17: - version "0.10.0-beta17" - resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.10.0-beta17.tgz#962d4a3f4dc6772385e0cad529c209cef3bc79e6" - integrity sha512-tn7EANQacnAvnOQCImvgag1DL0tVmUoY/1yIZbh3u/BBpvCcGHLZJNn7TXheodRLr6hmGSUS2VbfcUr9p0gOug== +node-pty@0.10.0-beta18: + version "0.10.0-beta18" + resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.10.0-beta18.tgz#7ed2d3f4a06b2b23fe2abdf5b41655e9dffc25d5" + integrity sha512-vpK4yB3A3VzgkvdOWegL7GcPapt45jfA4b3ejUe8k4RmqdWBRvFJngew8T3qAxmLhTkfo93psaN6izTlfkc6FA== dependencies: nan "^2.14.0" @@ -8368,14 +8367,14 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -roarr@^2.15.3: - version "2.15.4" - resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd" - integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A== +roarr@^2.14.5: + version "2.14.6" + resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.14.6.tgz#cebe8ad7ecbfd15bfa37b02dacf00809dd633912" + integrity sha512-qjbw0BEesKA+3XFBPt+KVe1PC/Z6ShfJ4wPlx2XifqH5h2Lj8/KQT5XJTsy3n1Es5kai+BwKALaECW3F70B1cg== dependencies: - boolean "^3.0.1" + boolean "^3.0.0" detect-node "^2.0.4" - globalthis "^1.0.1" + globalthis "^1.0.0" json-stringify-safe "^5.0.1" semver-compare "^1.0.0" sprintf-js "^1.1.2" @@ -8528,12 +8527,12 @@ semver@^7.3.2: resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== -serialize-error@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18" - integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw== +serialize-error@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-5.0.0.tgz#a7ebbcdb03a5d71a6ed8461ffe0fc1a1afed62ac" + integrity sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA== dependencies: - type-fest "^0.13.1" + type-fest "^0.8.0" serialize-javascript@^1.4.0: version "1.5.0" @@ -9573,12 +9572,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-fest@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" - integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== - -type-fest@^0.8.1: +type-fest@^0.8.0, type-fest@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== @@ -10083,12 +10077,12 @@ vscode-textmate@5.2.0: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== -vscode-windows-ca-certs@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/vscode-windows-ca-certs/-/vscode-windows-ca-certs-0.2.0.tgz#086f0f4de57e2760a35ac6920831bff246237115" - integrity sha512-YBrJRT0zos+Yb1Qdn73GD8QZr7pa2IE96b5Y1hmmp6XeR8aYB7Iiq5gDAF/+/AxL+caSR9KPZQ6jiYWh5biD7w== +vscode-windows-ca-certs@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/vscode-windows-ca-certs/-/vscode-windows-ca-certs-0.3.0.tgz#324e1f8ba842bbf048a39e7c0ee8fe655e9adfcc" + integrity sha512-CYrpCEKmAFQJoZNReOrelNL+VKyebOVRCqL9evrBlVcpWQDliliJgU5RggGS8FPGtQ3jAKLQt9frF0qlxYYPKA== dependencies: - node-addon-api "1.6.2" + node-addon-api "^3.0.2" vscode-windows-registry@1.0.3: version "1.0.3" @@ -10558,6 +10552,13 @@ yaserver@^0.2.0: resolved "https://registry.yarnpkg.com/yaserver/-/yaserver-0.2.0.tgz#56393027dc13f3c1bb89d20e0bd17269aa927802" integrity sha512-onsELrl7Y42M4P3T9R0N/ZJNJRu4cGwzhDyOWIFRMJvPUIrGKInYGh+DJBefrbr1qoyDu7DSCLl9BL5hSSVfDA== +yauzl@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" + integrity sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU= + dependencies: + fd-slicer "~1.0.1" + yauzl@^2.10.0, yauzl@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" From b0d4a08e3e047f98141a5bfbc4660cd60a362c29 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Sat, 5 Dec 2020 02:01:28 -0800 Subject: [PATCH 135/200] chore: bump distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6a714c44190..973e06910a8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.53.0", - "distro": "11fd6f1230738827638f000f641d01b2b178db20", + "distro": "94d3db103b67147ef00f22eee17c18f9250abe21", "author": { "name": "Microsoft Corporation" }, @@ -197,4 +197,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} From 7a7d27397a32b8d03b4cca85e02a3e0e89edca70 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Sat, 5 Dec 2020 07:03:28 -0800 Subject: [PATCH 136/200] chore: fix cache condition for native modules --- build/.cachesalt | 2 +- build/azure-pipelines/darwin/product-build-darwin.yml | 1 - build/azure-pipelines/linux/product-build-linux.yml | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/build/.cachesalt b/build/.cachesalt index a7a4d508274..661e359818e 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2020-11-30T16:21:34.566Z +2020-12-05T15:02:48.675Z diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index e2107fd73c9..28da2b70ee0 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -81,7 +81,6 @@ steps: npm install -g node-gyp@latest node-gyp --version displayName: Update node-gyp - condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) - script: | set -e diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 5d7e8cdb24f..489842b3b39 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -74,7 +74,6 @@ steps: npm install -g node-gyp@latest node-gyp --version displayName: Update node-gyp - condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) - script: | set -e @@ -108,8 +107,9 @@ steps: set -e export CC=$(which gcc-4.8) export CXX=$(which g++-4.8) - cd remote - node-gyp rebuild + export npm_config_node_gyp=$(which node-gyp) + cd remote && rm -rf node_modules/ + yarn displayName: Rebuild remote modules with gcc-4.8 - script: | From 86d779284b6a817f6b071e946df0ec98c3cec534 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Sat, 5 Dec 2020 13:26:12 -0800 Subject: [PATCH 137/200] ci: fix condition for linux builds --- build/azure-pipelines/linux/product-build-linux.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 489842b3b39..6e56d99bf7d 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -74,9 +74,12 @@ steps: npm install -g node-gyp@latest node-gyp --version displayName: Update node-gyp + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) - script: | set -e + export CC=$(which gcc-5) + export CXX=$(which g++-5) export npm_config_arch=$(NPM_ARCH) export CHILD_CONCURRENCY="1" for i in {1..3}; do # try 3 times, for Terrapin @@ -111,6 +114,7 @@ steps: cd remote && rm -rf node_modules/ yarn displayName: Rebuild remote modules with gcc-4.8 + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) - script: | set -e From eb189c703c711e327bac94d45a46b153601a6d73 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sun, 6 Dec 2020 18:52:57 +0100 Subject: [PATCH 138/200] Fix #111946 --- resources/web/code-web.js | 4 +- .../userDataSync/common/extensionsSync.ts | 38 +++++++++++-------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/resources/web/code-web.js b/resources/web/code-web.js index 9be3bc2d811..5646d658ae5 100644 --- a/resources/web/code-web.js +++ b/resources/web/code-web.js @@ -380,7 +380,9 @@ async function handleRoot(req, res) { const webConfigJSON = { folderUri: folderUri, staticExtensions, - enableSyncByDefault: args['enable-sync'], + settingsSyncOptions: { + enabled: args['enable-sync'] + }, webWorkerExtensionHostIframeSrc: `${SCHEME}://${HOST}:${SECONDARY_PORT}/static/out/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html` }; if (args['wrap-iframe']) { diff --git a/src/vs/platform/userDataSync/common/extensionsSync.ts b/src/vs/platform/userDataSync/common/extensionsSync.ts index e716e1355f4..2158147262b 100644 --- a/src/vs/platform/userDataSync/common/extensionsSync.ts +++ b/src/vs/platform/userDataSync/common/extensionsSync.ts @@ -528,10 +528,32 @@ export class ExtensionsInitializer extends AbstractInitializer { } else { toInstall.names.push(extension.identifier.id); } + if (extension.disabled) { + toDisable.push(extension.identifier); + } } } } + // 1. Initialise already installed extensions state + for (const extensionToSync of installedExtensionsToSync) { + if (extensionToSync.state) { + const extensionState = JSON.parse(this.storageService.get(extensionToSync.identifier.id, StorageScope.GLOBAL) || '{}'); + forEach(extensionToSync.state, ({ key, value }) => extensionState[key] = value); + this.storageService.store(extensionToSync.identifier.id, JSON.stringify(extensionState), StorageScope.GLOBAL, StorageTarget.MACHINE); + } + } + + // 2. Initialise extensions enablement + if (toDisable.length) { + for (const identifier of toDisable) { + this.logService.trace(`Disabling extension...`, identifier.id); + await this.extensionEnablementService.disableExtension(identifier); + this.logService.info(`Disabling extension`, identifier.id); + } + } + + // 3. Install extensions if (toInstall.names.length || toInstall.uuids.length) { const galleryExtensions = (await this.galleryService.query({ ids: toInstall.uuids, names: toInstall.names, pageSize: toInstall.uuids.length + toInstall.names.length }, CancellationToken.None)).firstPage; for (const galleryExtension of galleryExtensions) { @@ -552,22 +574,6 @@ export class ExtensionsInitializer extends AbstractInitializer { } } - if (toDisable.length) { - for (const identifier of toDisable) { - this.logService.trace(`Enabling extension...`, identifier.id); - await this.extensionEnablementService.disableExtension(identifier); - this.logService.info(`Enabled extension`, identifier.id); - } - } - - for (const extensionToSync of installedExtensionsToSync) { - if (extensionToSync.state) { - const extensionState = JSON.parse(this.storageService.get(extensionToSync.identifier.id, StorageScope.GLOBAL) || '{}'); - forEach(extensionToSync.state, ({ key, value }) => extensionState[key] = value); - this.storageService.store(extensionToSync.identifier.id, JSON.stringify(extensionState), StorageScope.GLOBAL, StorageTarget.MACHINE); - } - } - return newlyEnabledExtensions; } From eeed0fd5692cfdf9d1d43795086d0a479f3269fd Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sun, 6 Dec 2020 18:56:35 +0100 Subject: [PATCH 139/200] update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 973e06910a8..13c521e2dec 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.53.0", - "distro": "94d3db103b67147ef00f22eee17c18f9250abe21", + "distro": "1aaf2adfd4fd7c35c133724c4d97e103f2fa331f", "author": { "name": "Microsoft Corporation" }, @@ -197,4 +197,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file From fc9ff5d569b34222dcff2ca0bfdc62de86dbd112 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Sat, 5 Dec 2020 17:18:36 -0800 Subject: [PATCH 140/200] ci: avoid overwriting CC variables for arm arch --- build/azure-pipelines/linux/product-build-linux.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 6e56d99bf7d..6c9d24da74f 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -78,8 +78,11 @@ steps: - script: | set -e - export CC=$(which gcc-5) - export CXX=$(which g++-5) + if [ -z "$CC" || -z "$CXX" ] + then + export CC=$(which gcc-5) + export CXX=$(which g++-5) + fi export npm_config_arch=$(NPM_ARCH) export CHILD_CONCURRENCY="1" for i in {1..3}; do # try 3 times, for Terrapin From f5da8e346fcf7c4820c85da1f9e253360c7699a4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 7 Dec 2020 11:37:17 +0100 Subject: [PATCH 141/200] :lipsticky: async --- src/vs/base/node/pfs.ts | 6 ++-- .../quickinput/browser/quickInputList.ts | 3 +- src/vs/base/parts/storage/common/storage.ts | 22 +++++++------- src/vs/platform/files/common/files.ts | 4 +-- src/vs/platform/storage/node/storageIpc.ts | 4 +-- .../workspacesMainService.test.ts | 2 +- .../contrib/outline/browser/outlinePane.ts | 3 +- .../common/notificationService.ts | 4 +-- .../test/browser/workbenchTestServices.ts | 30 +++++++++---------- 9 files changed, 36 insertions(+), 42 deletions(-) diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index 3a17bd3fc78..fa07dcb9b7e 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -459,13 +459,13 @@ export function whenDeleted(path: string): Promise { export async function move(source: string, target: string): Promise { if (source === target) { - return Promise.resolve(); + return; } async function updateMtime(path: string): Promise { const stat = await lstat(path); if (stat.isDirectory() || stat.isSymbolicLink()) { - return Promise.resolve(); // only for files + return; // only for files } const fd = await promisify(fs.open)(path, 'a'); @@ -510,7 +510,7 @@ export async function copy(source: string, target: string, copiedSourcesIn?: { [ } if (copiedSources[source]) { - return Promise.resolve(); // escape when there are cycles (can happen with symlinks) + return; // escape when there are cycles (can happen with symlinks) } copiedSources[source] = true; // remember as copied diff --git a/src/vs/base/parts/quickinput/browser/quickInputList.ts b/src/vs/base/parts/quickinput/browser/quickInputList.ts index ba8bbd0239f..0973f0c1446 100644 --- a/src/vs/base/parts/quickinput/browser/quickInputList.ts +++ b/src/vs/base/parts/quickinput/browser/quickInputList.ts @@ -190,12 +190,11 @@ class ListElementRenderer implements IListRenderer { + const action = new Action(`id-${index}`, '', cssClasses, true, async () => { element.fireButtonTriggered({ button, item: element.item }); - return Promise.resolve(); }); action.tooltip = button.tooltip || ''; return action; diff --git a/src/vs/base/parts/storage/common/storage.ts b/src/vs/base/parts/storage/common/storage.ts index 8b55819cc54..c2f5ff5a5cd 100644 --- a/src/vs/base/parts/storage/common/storage.ts +++ b/src/vs/base/parts/storage/common/storage.ts @@ -200,9 +200,9 @@ export class Storage extends Disposable implements IStorage { return parseInt(value, 10); } - set(key: string, value: string | boolean | number | null | undefined): Promise { + async set(key: string, value: string | boolean | number | null | undefined): Promise { if (this.state === StorageState.Closed) { - return Promise.resolve(); // Return early if we are already closed + return; // Return early if we are already closed } // We remove the key for undefined/null values @@ -216,7 +216,7 @@ export class Storage extends Disposable implements IStorage { // Return early if value already set const currentValue = this.cache.get(key); if (currentValue === valueStr) { - return Promise.resolve(); + return; } // Update in cache and pending @@ -231,15 +231,15 @@ export class Storage extends Disposable implements IStorage { return this.flushDelayer.trigger(() => this.flushPending()); } - delete(key: string): Promise { + async delete(key: string): Promise { if (this.state === StorageState.Closed) { - return Promise.resolve(); // Return early if we are already closed + return; // Return early if we are already closed } // Remove from cache and add to pending const wasDeleted = this.cache.delete(key); if (!wasDeleted) { - return Promise.resolve(); // Return early if value already deleted + return; // Return early if value already deleted } if (!this.pendingDeletes.has(key)) { @@ -257,7 +257,7 @@ export class Storage extends Disposable implements IStorage { async close(): Promise { if (this.state === StorageState.Closed) { - return Promise.resolve(); // return if already closed + return; // return if already closed } // Update state @@ -282,9 +282,9 @@ export class Storage extends Disposable implements IStorage { return this.pendingInserts.size > 0 || this.pendingDeletes.size > 0; } - private flushPending(): Promise { + private async flushPending(): Promise { if (!this.hasPending) { - return Promise.resolve(); // return early if nothing to do + return; // return early if nothing to do } // Get pending data @@ -305,9 +305,9 @@ export class Storage extends Disposable implements IStorage { }); } - whenFlushed(): Promise { + async whenFlushed(): Promise { if (!this.hasPending) { - return Promise.resolve(); // return early if nothing to do + return; // return early if nothing to do } return new Promise(resolve => this.whenFlushedCallbacks.push(resolve)); diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index 4ae15434563..784bd056d94 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -947,9 +947,9 @@ export function etag(stat: { mtime: number | undefined, size: number | undefined return stat.mtime.toString(29) + stat.size.toString(31); } -export function whenProviderRegistered(file: URI, fileService: IFileService): Promise { +export async function whenProviderRegistered(file: URI, fileService: IFileService): Promise { if (fileService.canHandleResource(URI.from({ scheme: file.scheme }))) { - return Promise.resolve(); + return; } return new Promise(resolve => { diff --git a/src/vs/platform/storage/node/storageIpc.ts b/src/vs/platform/storage/node/storageIpc.ts index 8645255d9e7..67195995c28 100644 --- a/src/vs/platform/storage/node/storageIpc.ts +++ b/src/vs/platform/storage/node/storageIpc.ts @@ -200,12 +200,10 @@ export class GlobalStorageDatabaseChannelClient extends Disposable implements IS return this.channel.call('updateItems', serializableRequest); } - close(): Promise { + async close(): Promise { // when we are about to close, we start to ignore main-side changes since we close anyway dispose(this.onDidChangeItemsOnMainListener); - - return Promise.resolve(); // global storage is closed on the main side } dispose(): void { diff --git a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts index 07304aa32b0..59454446692 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -389,7 +389,7 @@ suite('WorkspacesMainService', () => { test.skip('rewriteWorkspaceFileForNewLocation (unc paths)', async () => { if (!isWindows) { - return Promise.resolve(); + return; } const workspaceLocation = path.join(os.tmpdir(), 'wsloc'); diff --git a/src/vs/workbench/contrib/outline/browser/outlinePane.ts b/src/vs/workbench/contrib/outline/browser/outlinePane.ts index ab48b16b7ca..3062e937dce 100644 --- a/src/vs/workbench/contrib/outline/browser/outlinePane.ts +++ b/src/vs/workbench/contrib/outline/browser/outlinePane.ts @@ -149,10 +149,9 @@ class SimpleToggleAction extends Action { private readonly _listener: IDisposable; constructor(state: OutlineViewState, label: string, isChecked: () => boolean, callback: (action: SimpleToggleAction) => any, className?: string) { - super(`simple` + defaultGenerator.nextId(), label, className, true, () => { + super(`simple` + defaultGenerator.nextId(), label, className, true, async () => { this.checked = !this.checked; callback(this); - return Promise.resolve(); }); this.checked = isChecked(); this._listener = state.onDidChange(() => this.checked = isChecked()); diff --git a/src/vs/workbench/services/notification/common/notificationService.ts b/src/vs/workbench/services/notification/common/notificationService.ts index 70b48e53088..2c52dc75ffe 100644 --- a/src/vs/workbench/services/notification/common/notificationService.ts +++ b/src/vs/workbench/services/notification/common/notificationService.ts @@ -76,15 +76,13 @@ export class NotificationService extends Disposable implements INotificationServ const neverShowAgainAction = toDispose.add(new Action( 'workbench.notification.neverShowAgain', nls.localize('neverShowAgain', "Don't Show Again"), - undefined, true, () => { + undefined, true, async () => { // Close notification handle.close(); // Remember choice this.storageService.store(id, true, scope, StorageTarget.USER); - - return Promise.resolve(); })); // Insert as primary or secondary action diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 83f8f0d0e05..d3b078b1f08 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -446,16 +446,16 @@ export class TestLayoutService implements IWorkbenchLayoutService { isActivityBarHidden(): boolean { return false; } setActivityBarHidden(_hidden: boolean): void { } isSideBarHidden(): boolean { return false; } - setEditorHidden(_hidden: boolean): Promise { return Promise.resolve(); } - setSideBarHidden(_hidden: boolean): Promise { return Promise.resolve(); } + async setEditorHidden(_hidden: boolean): Promise { } + async setSideBarHidden(_hidden: boolean): Promise { } isPanelHidden(): boolean { return false; } - setPanelHidden(_hidden: boolean): Promise { return Promise.resolve(); } + async setPanelHidden(_hidden: boolean): Promise { } toggleMaximizedPanel(): void { } isPanelMaximized(): boolean { return false; } getMenubarVisibility(): MenuBarVisibility { throw new Error('not implemented'); } getSideBarPosition() { return 0; } getPanelPosition() { return 0; } - setPanelPosition(_position: PartPosition): Promise { return Promise.resolve(); } + async setPanelPosition(_position: PartPosition): Promise { } addClass(_clazz: string): void { } removeClass(_clazz: string): void { } getMaximumEditorDimensions(): Dimension { throw new Error('not implemented'); } @@ -631,10 +631,10 @@ export class TestEditorGroupView implements IEditorGroupView { isActive(_editor: IEditorInput): boolean { return false; } moveEditor(_editor: IEditorInput, _target: IEditorGroup, _options?: IMoveEditorOptions): void { } copyEditor(_editor: IEditorInput, _target: IEditorGroup, _options?: ICopyEditorOptions): void { } - closeEditor(_editor?: IEditorInput, options?: ICloseEditorOptions): Promise { return Promise.resolve(); } - closeEditors(_editors: IEditorInput[] | ICloseEditorsFilter, options?: ICloseEditorOptions): Promise { return Promise.resolve(); } - closeAllEditors(options?: ICloseAllEditorsOptions): Promise { return Promise.resolve(); } - replaceEditors(_editors: IEditorReplacement[]): Promise { return Promise.resolve(); } + async closeEditor(_editor?: IEditorInput, options?: ICloseEditorOptions): Promise { } + async closeEditors(_editors: IEditorInput[] | ICloseEditorsFilter, options?: ICloseEditorOptions): Promise { } + async closeAllEditors(options?: ICloseAllEditorsOptions): Promise { } + async replaceEditors(_editors: IEditorReplacement[]): Promise { } pinEditor(_editor?: IEditorInput): void { } stickEditor(editor?: IEditorInput | undefined): void { } unstickEditor(editor?: IEditorInput | undefined): void { } @@ -870,7 +870,7 @@ export class TestFileService implements IFileService { return false; } - del(_resource: URI, _options?: { useTrash?: boolean, recursive?: boolean }): Promise { return Promise.resolve(); } + async del(_resource: URI, _options?: { useTrash?: boolean, recursive?: boolean }): Promise { } readonly watches: URI[] = []; watch(_resource: URI): IDisposable { @@ -894,13 +894,13 @@ export class TestBackupFileService implements IBackupFileService { hasBackups(): Promise { return Promise.resolve(false); } hasBackup(_resource: URI): Promise { return Promise.resolve(false); } hasBackupSync(resource: URI, versionId?: number): boolean { return false; } - registerResourceForBackup(_resource: URI): Promise { return Promise.resolve(); } - deregisterResourceForBackup(_resource: URI): Promise { return Promise.resolve(); } - backup(_resource: URI, _content?: ITextSnapshot, versionId?: number, meta?: T): Promise { return Promise.resolve(); } + async registerResourceForBackup(_resource: URI): Promise { } + async deregisterResourceForBackup(_resource: URI): Promise { } + async backup(_resource: URI, _content?: ITextSnapshot, versionId?: number, meta?: T): Promise { } getBackups(): Promise { return Promise.resolve([]); } resolve(_backup: URI): Promise | undefined> { return Promise.resolve(undefined); } - discardBackup(_resource: URI): Promise { return Promise.resolve(); } - discardBackups(): Promise { return Promise.resolve(); } + async discardBackup(_resource: URI): Promise { } + async discardBackups(): Promise { } parseBackupContent(textBufferFactory: ITextBufferFactory): string { const textBuffer = textBufferFactory.create(DefaultEndOfLine.LF); const lineCount = textBuffer.getLineCount(); @@ -925,7 +925,7 @@ export class TestLifecycleService implements ILifecycleService { private readonly _onShutdown = new Emitter(); get onShutdown(): Event { return this._onShutdown.event; } - when(): Promise { return Promise.resolve(); } + async when(): Promise { } fireShutdown(reason = ShutdownReason.QUIT): void { this._onWillShutdown.fire({ From 428d5b1d302e6bb3cdf5509a0258d09bb5b67f50 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 7 Dec 2020 11:38:44 +0100 Subject: [PATCH 142/200] proxy - remove old proxy auth dialog //cc @joaomoreno --- build/gulpfile.vscode.js | 1 - src/vs/code/electron-main/app.ts | 9 +- src/vs/code/electron-main/auth.ts | 102 ------------------ src/vs/code/electron-sandbox/proxy/auth.html | 83 -------------- src/vs/code/electron-sandbox/proxy/auth.js | 48 --------- src/vs/platform/windows/common/windows.ts | 1 - .../browser/relauncher.contribution.ts | 7 -- .../electron-sandbox/desktop.contribution.ts | 6 -- 8 files changed, 2 insertions(+), 255 deletions(-) delete mode 100644 src/vs/code/electron-main/auth.ts delete mode 100644 src/vs/code/electron-sandbox/proxy/auth.html delete mode 100644 src/vs/code/electron-sandbox/proxy/auth.js diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 42a9c2b2709..bb8b2454a9b 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -80,7 +80,6 @@ const vscodeResources = [ 'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js', 'out-build/vs/code/electron-sandbox/issue/issueReporter.js', 'out-build/vs/code/electron-sandbox/processExplorer/processExplorer.js', - 'out-build/vs/code/electron-sandbox/proxy/auth.js', '!**/test/**' ]; diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 759c85bc747..4ac339bce4b 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -33,7 +33,6 @@ import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties'; import { getDelayedChannel, StaticRouter, createChannelReceiver, createChannelSender } from 'vs/base/parts/ipc/common/ipc'; import product from 'vs/platform/product/common/product'; -import { ProxyAuthHandler } from 'vs/code/electron-main/auth'; import { ProxyAuthHandler2 } from 'vs/code/electron-main/auth2'; import { FileProtocolHandler } from 'vs/code/electron-main/protocol'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -454,12 +453,8 @@ export class CodeApplication extends Disposable { this._register(server); } - // Setup Auth Handler (TODO@ben remove old auth handler eventually) - if (this.configurationService.getValue('window.enableExperimentalProxyLoginDialog') === false) { - this._register(new ProxyAuthHandler()); - } else { - this._register(appInstantiationService.createInstance(ProxyAuthHandler2)); - } + // Setup Auth Handler + this._register(appInstantiationService.createInstance(ProxyAuthHandler2)); // Open Windows const windows = appInstantiationService.invokeFunction(accessor => this.openFirstWindow(accessor, electronIpcServer, sharedProcessClient, fileProtocolHandler)); diff --git a/src/vs/code/electron-main/auth.ts b/src/vs/code/electron-main/auth.ts deleted file mode 100644 index b4096018623..00000000000 --- a/src/vs/code/electron-main/auth.ts +++ /dev/null @@ -1,102 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize } from 'vs/nls'; -import { Disposable } from 'vs/base/common/lifecycle'; -import { Event } from 'vs/base/common/event'; -import { FileAccess } from 'vs/base/common/network'; -import { BrowserWindow, BrowserWindowConstructorOptions, app, AuthInfo, WebContents, Event as ElectronEvent } from 'electron'; - -type LoginEvent = { - event: ElectronEvent; - webContents: WebContents; - req: Request; - authInfo: AuthInfo; - cb: (username: string, password: string) => void; -}; - -type Credentials = { - username: string; - password: string; -}; - -export class ProxyAuthHandler extends Disposable { - - declare readonly _serviceBrand: undefined; - - private retryCount = 0; - - constructor() { - super(); - - this.registerListeners(); - } - - private registerListeners(): void { - const onLogin = Event.fromNodeEventEmitter(app, 'login', (event, webContents, req, authInfo, cb) => ({ event, webContents, req, authInfo, cb })); - this._register(onLogin(this.onLogin, this)); - } - - private onLogin({ event, authInfo, cb }: LoginEvent): void { - if (!authInfo.isProxy) { - return; - } - - if (this.retryCount++ > 1) { - return; - } - - event.preventDefault(); - - const opts: BrowserWindowConstructorOptions = { - alwaysOnTop: true, - skipTaskbar: true, - resizable: false, - width: 450, - height: 225, - show: true, - title: 'VS Code', - webPreferences: { - preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-browser/preload.js', require).fsPath, - sandbox: true, - contextIsolation: true, - enableWebSQL: false, - enableRemoteModule: false, - spellcheck: false, - devTools: false - } - }; - - const focusedWindow = BrowserWindow.getFocusedWindow(); - if (focusedWindow) { - opts.parent = focusedWindow; - opts.modal = true; - } - - const win = new BrowserWindow(opts); - const windowUrl = FileAccess.asBrowserUri('vs/code/electron-sandbox/proxy/auth.html', require); - const proxyUrl = `${authInfo.host}:${authInfo.port}`; - const title = localize('authRequire', "Proxy Authentication Required"); - const message = localize('proxyauth', "The proxy {0} requires authentication.", proxyUrl); - - const onWindowClose = () => cb('', ''); - win.on('close', onWindowClose); - - win.setMenu(null); - win.webContents.on('did-finish-load', () => { - const data = { title, message }; - win.webContents.send('vscode:openProxyAuthDialog', data); - }); - win.webContents.on('ipc-message', (event, channel, credentials: Credentials) => { - if (channel === 'vscode:proxyAuthResponse') { - const { username, password } = credentials; - cb(username, password); - win.removeListener('close', onWindowClose); - win.close(); - } - }); - win.loadURL(windowUrl.toString(true)); - } -} diff --git a/src/vs/code/electron-sandbox/proxy/auth.html b/src/vs/code/electron-sandbox/proxy/auth.html deleted file mode 100644 index 788b68fce72..00000000000 --- a/src/vs/code/electron-sandbox/proxy/auth.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - -

-
-

-
-

-

-

- - -

-
-
- - - - - diff --git a/src/vs/code/electron-sandbox/proxy/auth.js b/src/vs/code/electron-sandbox/proxy/auth.js deleted file mode 100644 index 5e0db3c2dc7..00000000000 --- a/src/vs/code/electron-sandbox/proxy/auth.js +++ /dev/null @@ -1,48 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -'use strict'; - -const { ipcRenderer } = window.vscode; - -function promptForCredentials(data) { - return new Promise((c, e) => { - const $title = document.getElementById('title'); - const $username = document.getElementById('username'); - const $password = document.getElementById('password'); - const $form = document.getElementById('form'); - const $cancel = document.getElementById('cancel'); - const $message = document.getElementById('message'); - - function submit() { - c({ username: $username.value, password: $password.value }); - return false; - } - - function cancel() { - c({ username: '', password: '' }); - return false; - } - - $form.addEventListener('submit', submit); - $cancel.addEventListener('click', cancel); - - document.body.addEventListener('keydown', function (e) { - switch (e.keyCode) { - case 27: e.preventDefault(); e.stopPropagation(); return cancel(); - case 13: e.preventDefault(); e.stopPropagation(); return submit(); - } - }); - - $title.textContent = data.title; - $message.textContent = data.message; - $username.focus(); - }); -} - -ipcRenderer.on('vscode:openProxyAuthDialog', async (event, data) => { - const response = await promptForCredentials(data); - ipcRenderer.send('vscode:proxyAuthResponse', response); -}); diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 40c952136ec..ca3e63d96ed 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -115,7 +115,6 @@ export interface IWindowSettings { enableMenuBarMnemonics: boolean; closeWhenEmpty: boolean; clickThroughInactive: boolean; - enableExperimentalProxyLoginDialog: boolean; } export function getTitleBarStyle(configurationService: IConfigurationService): 'native' | 'custom' { diff --git a/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts b/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts index c5a10561fec..9f8bede88ca 100644 --- a/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts +++ b/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts @@ -36,7 +36,6 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo private updateMode: string | undefined; private debugConsoleWordWrap: boolean | undefined; private accessibilitySupport: 'on' | 'off' | 'auto' | undefined; - private enableExperimentalProxyLoginDialog = true; // default constructor( @IHostService private readonly hostService: IHostService, @@ -98,12 +97,6 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo changed = true; } } - - // Experimental proxy login dialog - if (typeof config.window?.enableExperimentalProxyLoginDialog === 'boolean' && config.window.enableExperimentalProxyLoginDialog !== this.enableExperimentalProxyLoginDialog) { - this.enableExperimentalProxyLoginDialog = config.window.enableExperimentalProxyLoginDialog; - changed = true; - } } // Notify only when changed and we are the focused window (avoids notification spam across windows) diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts index 63bc327faa9..9dd8fb5be0c 100644 --- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts +++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts @@ -293,12 +293,6 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema'; 'scope': ConfigurationScope.APPLICATION, 'description': nls.localize('window.clickThroughInactive', "If enabled, clicking on an inactive window will both activate the window and trigger the element under the mouse if it is clickable. If disabled, clicking anywhere on an inactive window will activate it only and a second click is required on the element."), 'included': isMacintosh - }, - 'window.enableExperimentalProxyLoginDialog': { - 'type': 'boolean', - 'default': true, - 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('window.enableExperimentalProxyLoginDialog', "Enables a new login dialog for proxy authentication. Requires a restart to take effect."), } } }); From 25cbe382515cd2ca5911662429e08e0c922ebdec Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 7 Dec 2020 11:39:39 +0100 Subject: [PATCH 143/200] proxy - rename proxy2 to proxy --- src/vs/code/electron-main/app.ts | 4 ++-- src/vs/code/electron-main/{auth2.ts => auth.ts} | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) rename src/vs/code/electron-main/{auth2.ts => auth.ts} (96%) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 4ac339bce4b..0ab687799f9 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -33,7 +33,7 @@ import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties'; import { getDelayedChannel, StaticRouter, createChannelReceiver, createChannelSender } from 'vs/base/parts/ipc/common/ipc'; import product from 'vs/platform/product/common/product'; -import { ProxyAuthHandler2 } from 'vs/code/electron-main/auth2'; +import { ProxyAuthHandler } from 'vs/code/electron-main/auth'; import { FileProtocolHandler } from 'vs/code/electron-main/protocol'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows'; @@ -454,7 +454,7 @@ export class CodeApplication extends Disposable { } // Setup Auth Handler - this._register(appInstantiationService.createInstance(ProxyAuthHandler2)); + this._register(appInstantiationService.createInstance(ProxyAuthHandler)); // Open Windows const windows = appInstantiationService.invokeFunction(accessor => this.openFirstWindow(accessor, electronIpcServer, sharedProcessClient, fileProtocolHandler)); diff --git a/src/vs/code/electron-main/auth2.ts b/src/vs/code/electron-main/auth.ts similarity index 96% rename from src/vs/code/electron-main/auth2.ts rename to src/vs/code/electron-main/auth.ts index 1b84d4bc4d9..b9669f983c7 100644 --- a/src/vs/code/electron-main/auth2.ts +++ b/src/vs/code/electron-main/auth.ts @@ -54,7 +54,7 @@ enum ProxyAuthState { LoginDialogShown } -export class ProxyAuthHandler2 extends Disposable { +export class ProxyAuthHandler extends Disposable { private static PROXY_CREDENTIALS_SERVICE_KEY = `${product.urlProtocol}.proxy-credentials`; @@ -153,7 +153,7 @@ export class ProxyAuthHandler2 extends Disposable { let storedUsername: string | undefined = undefined; let storedPassword: string | undefined = undefined; try { - const encryptedSerializedProxyCredentials = await this.nativeHostMainService.getPassword(undefined, ProxyAuthHandler2.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash); + const encryptedSerializedProxyCredentials = await this.nativeHostMainService.getPassword(undefined, ProxyAuthHandler.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash); if (encryptedSerializedProxyCredentials) { const credentials: Credentials = JSON.parse(await this.encryptionMainService.decrypt(encryptedSerializedProxyCredentials)); @@ -211,9 +211,9 @@ export class ProxyAuthHandler2 extends Disposable { try { if (reply.remember) { const encryptedSerializedCredentials = await this.encryptionMainService.encrypt(JSON.stringify(credentials)); - await this.nativeHostMainService.setPassword(undefined, ProxyAuthHandler2.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash, encryptedSerializedCredentials); + await this.nativeHostMainService.setPassword(undefined, ProxyAuthHandler.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash, encryptedSerializedCredentials); } else { - await this.nativeHostMainService.deletePassword(undefined, ProxyAuthHandler2.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash); + await this.nativeHostMainService.deletePassword(undefined, ProxyAuthHandler.PROXY_CREDENTIALS_SERVICE_KEY, authInfoHash); } } catch (error) { this.logService.error(error); // handle gracefully From 878bf135043770f5e2270378b2376bc5e3f8deac Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 7 Dec 2020 11:42:17 +0100 Subject: [PATCH 144/200] debt - shuffle some electron-main code to better layers --- src/vs/code/electron-main/app.ts | 21 +++++++--------- src/vs/code/electron-main/main.ts | 6 ++--- src/vs/code/electron-main/sharedProcess.ts | 11 ++++---- src/vs/code/electron-main/window.ts | 3 ++- .../electron-main/extensionHostDebugIpc.ts | 2 +- .../{dialogs.ts => dialogMainService.ts} | 0 .../issue/electron-main/issueMainService.ts | 2 +- .../launch/electron-main/launchMainService.ts | 25 +++++++++---------- .../platform/menubar/electron-main/menubar.ts | 2 +- .../electron-main/nativeHostMainService.ts | 4 +-- .../windows/{node => electron-main}/window.ts | 0 .../platform/windows/electron-main/windows.ts | 2 +- .../electron-main/windowsMainService.ts | 4 +-- .../{node => electron-main}/window.test.ts | 2 +- .../electron-main/windowsStateStorage.test.ts | 2 -- .../electron-main/workspacesMainService.ts | 4 +-- .../workspacesMainService.test.ts | 2 +- 17 files changed, 44 insertions(+), 48 deletions(-) rename src/vs/platform/dialogs/electron-main/{dialogs.ts => dialogMainService.ts} (100%) rename src/vs/platform/windows/{node => electron-main}/window.ts (100%) rename src/vs/platform/windows/test/{node => electron-main}/window.test.ts (98%) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 0ab687799f9..6eb685b7926 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -7,7 +7,7 @@ import { app, ipcMain, systemPreferences, contentTracing, protocol, BrowserWindo import { IProcessEnvironment, isWindows, isMacintosh, isLinux } from 'vs/base/common/platform'; import { WindowsMainService } from 'vs/platform/windows/electron-main/windowsMainService'; import { IWindowOpenable } from 'vs/platform/windows/common/windows'; -import { OpenContext } from 'vs/platform/windows/node/window'; +import { OpenContext } from 'vs/platform/windows/electron-main/window'; import { ILifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService'; import { resolveShellEnv } from 'vs/code/node/shellEnv'; import { IUpdateService } from 'vs/platform/update/common/update'; @@ -70,7 +70,7 @@ import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/ext import { ElectronExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/electron-main/extensionHostDebugIpc'; import { INativeHostMainService, NativeHostMainService } from 'vs/platform/native/electron-main/nativeHostMainService'; import { ISharedProcessMainService, SharedProcessMainService } from 'vs/platform/ipc/electron-main/sharedProcessMainService'; -import { IDialogMainService, DialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; +import { IDialogMainService, DialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService'; import { withNullAsUndefined } from 'vs/base/common/types'; import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels'; import { WebviewMainService } from 'vs/platform/webview/electron-main/webviewMainService'; @@ -897,7 +897,12 @@ export class CodeApplication extends Disposable { this.lifecycleMainService.phase = LifecycleMainPhase.AfterWindowOpen; // Remote Authorities - this.handleRemoteAuthorities(); + protocol.registerHttpProtocol(Schemas.vscodeRemoteResource, (request, callback) => { + callback({ + url: request.url.replace(/^vscode-remote-resource:/, 'http:'), + method: request.method + }); + }); // Initialize update service const updateService = accessor.get(IUpdateService); @@ -929,19 +934,11 @@ export class CodeApplication extends Disposable { '}' ]; const newArgvString = argvString.substring(0, argvString.length - 2).concat(',\n', additionalArgvContent.join('\n')); + await this.fileService.writeFile(this.environmentService.argvResource, VSBuffer.fromString(newArgvString)); } } catch (error) { this.logService.error(error); } } - - private handleRemoteAuthorities(): void { - protocol.registerHttpProtocol(Schemas.vscodeRemoteResource, (request, callback) => { - callback({ - url: request.url.replace(/^vscode-remote-resource:/, 'http:'), - method: request.method - }); - }); - } } diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 783ac6fb565..38464e58e5c 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -5,7 +5,8 @@ import 'vs/platform/update/common/update.config.contribution'; import { app, dialog } from 'electron'; -import * as fs from 'fs'; +import { unlinkSync } from 'fs'; +import { localize } from 'vs/nls'; import { isWindows, IProcessEnvironment, isMacintosh } from 'vs/base/common/platform'; import product from 'vs/platform/product/common/product'; import { parseMainProcessArgv, addArg } from 'vs/platform/environment/node/argvHelper'; @@ -29,7 +30,6 @@ import { ConfigurationService } from 'vs/platform/configuration/common/configura import { IRequestService } from 'vs/platform/request/common/request'; import { RequestMainService } from 'vs/platform/request/electron-main/requestMainService'; import { CodeApplication } from 'vs/code/electron-main/app'; -import { localize } from 'vs/nls'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; import { BufferLogService } from 'vs/platform/log/common/bufferLog'; @@ -256,7 +256,7 @@ class CodeMain { // let's delete it, since we can't connect to it and then // retry the whole thing try { - fs.unlinkSync(environmentService.mainIPCHandle); + unlinkSync(environmentService.mainIPCHandle); } catch (error) { logService.warn('Could not delete obsolete instance handle', error); diff --git a/src/vs/code/electron-main/sharedProcess.ts b/src/vs/code/electron-main/sharedProcess.ts index dd721db92ad..1329bd72590 100644 --- a/src/vs/code/electron-main/sharedProcess.ts +++ b/src/vs/code/electron-main/sharedProcess.ts @@ -17,12 +17,11 @@ import { FileAccess } from 'vs/base/common/network'; export class SharedProcess implements ISharedProcess { - private barrier = new Barrier(); + private readonly barrier = new Barrier(); + private readonly _whenReady: Promise; private window: BrowserWindow | null = null; - private readonly _whenReady: Promise; - constructor( private readonly machineId: string, private userEnv: NodeJS.ProcessEnv, @@ -52,6 +51,7 @@ export class SharedProcess implements ISharedProcess { disableBlinkFeatures: 'Auxclick' // do NOT change, allows us to identify this window as shared-process in the process explorer } }); + const config = { appRoot: this.environmentService.appRoot, machineId: this.machineId, @@ -110,7 +110,8 @@ export class SharedProcess implements ISharedProcess { }, 0); }); - return new Promise(c => { + return new Promise(resolve => { + // send payload once shared process is ready to receive it disposables.add(Event.once(Event.fromNodeEventEmitter(ipcMain, 'vscode:shared-process->electron-main=ready-for-payload', ({ sender }: { sender: WebContents }) => sender))(sender => { sender.send('vscode:electron-main->shared-process=payload', { @@ -125,7 +126,7 @@ export class SharedProcess implements ISharedProcess { disposables.add(toDisposable(() => sender.send('vscode:electron-main->shared-process=exit'))); // complete IPC-ready promise when shared process signals this to us - ipcMain.once('vscode:shared-process->electron-main=ipc-ready', () => c(undefined)); + ipcMain.once('vscode:shared-process->electron-main=ipc-ready', () => resolve(undefined)); })); }); } diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index f6b98e72c98..e09fb03efd2 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -28,7 +28,7 @@ import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/commo import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService'; import { RunOnceScheduler } from 'vs/base/common/async'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; +import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService'; @@ -648,6 +648,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { this.currentMenuBarVisibility = newMenuBarVisibility; this.setMenuBarVisibility(newMenuBarVisibility); } + // Do not set to empty configuration at startup if setting is empty to not override configuration through CLI options: const env = process.env; let newHttpProxy = (this.configurationService.getValue('http.proxy') || '').trim() diff --git a/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts b/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts index d05bd7ca0c4..7cc40f9086d 100644 --- a/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts +++ b/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts @@ -9,7 +9,7 @@ import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv'; import { createServer, AddressInfo } from 'net'; import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc'; import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; -import { OpenContext } from 'vs/platform/windows/node/window'; +import { OpenContext } from 'vs/platform/windows/electron-main/window'; export class ElectronExtensionHostDebugBroadcastChannel extends ExtensionHostDebugBroadcastChannel { diff --git a/src/vs/platform/dialogs/electron-main/dialogs.ts b/src/vs/platform/dialogs/electron-main/dialogMainService.ts similarity index 100% rename from src/vs/platform/dialogs/electron-main/dialogs.ts rename to src/vs/platform/dialogs/electron-main/dialogMainService.ts diff --git a/src/vs/platform/issue/electron-main/issueMainService.ts b/src/vs/platform/issue/electron-main/issueMainService.ts index da98e2f94f6..1279430a182 100644 --- a/src/vs/platform/issue/electron-main/issueMainService.ts +++ b/src/vs/platform/issue/electron-main/issueMainService.ts @@ -17,7 +17,7 @@ import { isMacintosh, IProcessEnvironment } from 'vs/base/common/platform'; import { ILogService } from 'vs/platform/log/common/log'; import { IWindowState } from 'vs/platform/windows/electron-main/windows'; import { listProcesses } from 'vs/base/node/ps'; -import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; +import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { zoomLevelToZoomFactor } from 'vs/platform/windows/common/windows'; import { FileAccess } from 'vs/base/common/network'; diff --git a/src/vs/platform/launch/electron-main/launchMainService.ts b/src/vs/platform/launch/electron-main/launchMainService.ts index 9b3d6566394..61e66f0fd6a 100644 --- a/src/vs/platform/launch/electron-main/launchMainService.ts +++ b/src/vs/platform/launch/electron-main/launchMainService.ts @@ -9,7 +9,7 @@ import { IProcessEnvironment, isMacintosh } from 'vs/base/common/platform'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IWindowSettings } from 'vs/platform/windows/common/windows'; -import { OpenContext } from 'vs/platform/windows/node/window'; +import { OpenContext } from 'vs/platform/windows/electron-main/window'; import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows'; import { whenDeleted } from 'vs/base/node/pfs'; import { IWorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService'; @@ -113,7 +113,7 @@ export class LaunchMainService implements ILaunchMainService { } } - private startOpenWindow(args: NativeParsedArgs, userEnv: IProcessEnvironment): Promise { + private async startOpenWindow(args: NativeParsedArgs, userEnv: IProcessEnvironment): Promise { const context = isLaunchedFromCli(userEnv) ? OpenContext.CLI : OpenContext.DESKTOP; let usedWindows: ICodeWindow[] = []; @@ -205,17 +205,15 @@ export class LaunchMainService implements ILaunchMainService { whenDeleted(waitMarkerFileURI.fsPath) ]).then(() => undefined, () => undefined); } - - return Promise.resolve(undefined); } - getMainProcessId(): Promise { + async getMainProcessId(): Promise { this.logService.trace('Received request for process ID from other instance.'); - return Promise.resolve(process.pid); + return process.pid; } - getMainProcessInfo(): Promise { + async getMainProcessInfo(): Promise { this.logService.trace('Received request for main process info from other instance.'); const windows: IWindowInfo[] = []; @@ -228,18 +226,18 @@ export class LaunchMainService implements ILaunchMainService { } }); - return Promise.resolve({ + return { mainPID: process.pid, mainArguments: process.argv.slice(1), windows, screenReader: !!app.accessibilitySupportEnabled, gpuFeatureStatus: app.getGPUFeatureStatus() - }); + }; } - getRemoteDiagnostics(options: IRemoteDiagnosticOptions): Promise<(IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]> { + async getRemoteDiagnostics(options: IRemoteDiagnosticOptions): Promise<(IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]> { const windows = this.windowsMainService.getWindows(); - const promises: Promise[] = windows.map(window => { + const diagnostics: Array = await Promise.all(windows.map(window => { return new Promise((resolve) => { const remoteAuthority = window.remoteAuthority; if (remoteAuthority) { @@ -267,9 +265,9 @@ export class LaunchMainService implements ILaunchMainService { resolve(undefined); } }); - }); + })); - return Promise.all(promises).then(diagnostics => diagnostics.filter((x): x is IRemoteDiagnosticInfo | IRemoteDiagnosticError => !!x)); + return diagnostics.filter((x): x is IRemoteDiagnosticInfo | IRemoteDiagnosticError => !!x); } private getFolderURIs(window: ICodeWindow): URI[] { @@ -296,6 +294,7 @@ export class LaunchMainService implements ILaunchMainService { private codeWindowToInfo(window: ICodeWindow): IWindowInfo { const folderURIs = this.getFolderURIs(window); + return this.browserWindowToInfo(window.win, folderURIs, window.remoteAuthority); } diff --git a/src/vs/platform/menubar/electron-main/menubar.ts b/src/vs/platform/menubar/electron-main/menubar.ts index 90fba9c3fb1..215be10e210 100644 --- a/src/vs/platform/menubar/electron-main/menubar.ts +++ b/src/vs/platform/menubar/electron-main/menubar.ts @@ -8,7 +8,7 @@ import { isMacintosh, language } from 'vs/base/common/platform'; import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService'; import { app, Menu, MenuItem, BrowserWindow, MenuItemConstructorOptions, WebContents, KeyboardEvent } from 'electron'; import { getTitleBarStyle, INativeRunActionInWindowRequest, INativeRunKeybindingInWindowRequest, IWindowOpenable } from 'vs/platform/windows/common/windows'; -import { OpenContext } from 'vs/platform/windows/node/window'; +import { OpenContext } from 'vs/platform/windows/electron-main/window'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IUpdateService, StateType } from 'vs/platform/update/common/update'; diff --git a/src/vs/platform/native/electron-main/nativeHostMainService.ts b/src/vs/platform/native/electron-main/nativeHostMainService.ts index e24efa83cf1..57b2a5c8822 100644 --- a/src/vs/platform/native/electron-main/nativeHostMainService.ts +++ b/src/vs/platform/native/electron-main/nativeHostMainService.ts @@ -6,7 +6,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows'; import { MessageBoxOptions, MessageBoxReturnValue, shell, OpenDevToolsOptions, SaveDialogOptions, SaveDialogReturnValue, OpenDialogOptions, OpenDialogReturnValue, Menu, BrowserWindow, app, clipboard, powerMonitor, nativeTheme } from 'electron'; -import { OpenContext } from 'vs/platform/windows/node/window'; +import { OpenContext } from 'vs/platform/windows/electron-main/window'; import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService'; import { IOpenedWindow, IOpenWindowOptions, IWindowOpenable, IOpenEmptyWindowOptions, IColorScheme } from 'vs/platform/windows/common/windows'; import { INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs'; @@ -15,7 +15,7 @@ import { ICommonNativeHostService, IOSProperties, IOSStatistics } from 'vs/platf import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService'; import { AddFirstParameterToFunctions } from 'vs/base/common/types'; -import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; +import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService'; import { dirExists } from 'vs/base/node/pfs'; import { URI } from 'vs/base/common/uri'; import { ITelemetryData, ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; diff --git a/src/vs/platform/windows/node/window.ts b/src/vs/platform/windows/electron-main/window.ts similarity index 100% rename from src/vs/platform/windows/node/window.ts rename to src/vs/platform/windows/electron-main/window.ts diff --git a/src/vs/platform/windows/electron-main/windows.ts b/src/vs/platform/windows/electron-main/windows.ts index 83eccca73c4..e77f247e08a 100644 --- a/src/vs/platform/windows/electron-main/windows.ts +++ b/src/vs/platform/windows/electron-main/windows.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IWindowOpenable, IOpenEmptyWindowOptions, INativeWindowConfiguration } from 'vs/platform/windows/common/windows'; -import { OpenContext } from 'vs/platform/windows/node/window'; +import { OpenContext } from 'vs/platform/windows/electron-main/window'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import { Event } from 'vs/base/common/event'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index 6bcedb5c761..0fe8e924f00 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -18,7 +18,7 @@ import { ILifecycleMainService, UnloadReason, LifecycleMainService, LifecycleMai import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService } from 'vs/platform/log/common/log'; import { IWindowSettings, IPath, isFileToOpen, isWorkspaceToOpen, isFolderToOpen, IWindowOpenable, IOpenEmptyWindowOptions, IAddFoldersRequest, IPathsToWaitFor, INativeWindowConfiguration } from 'vs/platform/windows/common/windows'; -import { getLastActiveWindow, findBestWindowOrFolderForFile, findWindowOnWorkspace, findWindowOnExtensionDevelopmentPath, findWindowOnWorkspaceOrFolderUri, OpenContext } from 'vs/platform/windows/node/window'; +import { getLastActiveWindow, findBestWindowOrFolderForFile, findWindowOnWorkspace, findWindowOnExtensionDevelopmentPath, findWindowOnWorkspaceOrFolderUri, OpenContext } from 'vs/platform/windows/electron-main/window'; import { Emitter } from 'vs/base/common/event'; import product from 'vs/platform/product/common/product'; import { IWindowsMainService, IOpenConfiguration, IWindowsCountChangedEvent, ICodeWindow, IWindowState as ISingleWindowState, WindowMode, IOpenEmptyConfiguration } from 'vs/platform/windows/electron-main/windows'; @@ -34,7 +34,7 @@ import { restoreWindowsState, WindowsStateStorageData, getWindowsStateStoreData import { getWorkspaceIdentifier, IWorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService'; import { once } from 'vs/base/common/functional'; import { Disposable } from 'vs/base/common/lifecycle'; -import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; +import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService'; import { withNullAsUndefined } from 'vs/base/common/types'; import { isWindowsDriveLetter, toSlashes, parseLineAndColumnAware } from 'vs/base/common/extpath'; import { CharCode } from 'vs/base/common/charCode'; diff --git a/src/vs/platform/windows/test/node/window.test.ts b/src/vs/platform/windows/test/electron-main/window.test.ts similarity index 98% rename from src/vs/platform/windows/test/node/window.test.ts rename to src/vs/platform/windows/test/electron-main/window.test.ts index 576d30d134a..b8135be8b42 100644 --- a/src/vs/platform/windows/test/node/window.test.ts +++ b/src/vs/platform/windows/test/electron-main/window.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as path from 'vs/base/common/path'; -import { IBestWindowOrFolderOptions, IWindowContext, findBestWindowOrFolderForFile, OpenContext } from 'vs/platform/windows/node/window'; +import { IBestWindowOrFolderOptions, IWindowContext, findBestWindowOrFolderForFile, OpenContext } from 'vs/platform/windows/electron-main/window'; import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; import { URI } from 'vs/base/common/uri'; diff --git a/src/vs/platform/windows/test/electron-main/windowsStateStorage.test.ts b/src/vs/platform/windows/test/electron-main/windowsStateStorage.test.ts index 419caee0d71..e776f85c227 100644 --- a/src/vs/platform/windows/test/electron-main/windowsStateStorage.test.ts +++ b/src/vs/platform/windows/test/electron-main/windowsStateStorage.test.ts @@ -286,7 +286,5 @@ suite('Windows State Storing', () => { } }; assertEqualWindowsState(expected, windowsState, 'v1_32_empty_window'); - }); - }); diff --git a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts index f4fa065fbb5..d5ff4b46d4b 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts @@ -25,8 +25,8 @@ import product from 'vs/platform/product/common/product'; import { MessageBoxOptions, BrowserWindow } from 'electron'; import { withNullAsUndefined } from 'vs/base/common/types'; import { IBackupMainService } from 'vs/platform/backup/electron-main/backup'; -import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; -import { findWindowOnWorkspace } from 'vs/platform/windows/node/window'; +import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService'; +import { findWindowOnWorkspace } from 'vs/platform/windows/electron-main/window'; export const IWorkspacesMainService = createDecorator('workspacesMainService'); diff --git a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts index 59454446692..e8510db9a24 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -18,7 +18,7 @@ import { getRandomTestPath } from 'vs/base/test/node/testUtils'; import { isWindows } from 'vs/base/common/platform'; import { normalizeDriveLetter } from 'vs/base/common/labels'; import { dirname, joinPath } from 'vs/base/common/resources'; -import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; +import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService'; import { INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs'; import { IBackupMainService, IWorkspaceBackupInfo } from 'vs/platform/backup/electron-main/backup'; import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup'; From 04b9a571b84c58cc57c7f40ec2478495d22e3fe2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 7 Dec 2020 11:42:49 +0100 Subject: [PATCH 145/200] fix #111898 on master --- src/vs/workbench/browser/actions/workspaceCommands.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/actions/workspaceCommands.ts b/src/vs/workbench/browser/actions/workspaceCommands.ts index 92794740270..7f43e0fb0e5 100644 --- a/src/vs/workbench/browser/actions/workspaceCommands.ts +++ b/src/vs/workbench/browser/actions/workspaceCommands.ts @@ -131,7 +131,7 @@ interface IOpenFolderAPICommandOptions { CommandsRegistry.registerCommand({ id: 'vscode.openFolder', - handler: (accessor: ServicesAccessor, uri?: URI, arg: boolean | IOpenFolderAPICommandOptions = {}) => { + handler: (accessor: ServicesAccessor, uri?: URI, arg?: boolean | IOpenFolderAPICommandOptions) => { const commandService = accessor.get(ICommandService); // Be compatible to previous args by converting to options @@ -141,15 +141,15 @@ CommandsRegistry.registerCommand({ // Without URI, ask to pick a folder or workpsace to open if (!uri) { - return commandService.executeCommand('_files.pickFolderAndOpen', { forceNewWindow: arg.forceNewWindow }); + return commandService.executeCommand('_files.pickFolderAndOpen', { forceNewWindow: arg?.forceNewWindow }); } uri = URI.revive(uri); const options: IOpenWindowOptions = { - forceNewWindow: arg.forceNewWindow, - forceReuseWindow: arg.forceReuseWindow, - noRecentEntry: arg.noRecentEntry + forceNewWindow: arg?.forceNewWindow, + forceReuseWindow: arg?.forceReuseWindow, + noRecentEntry: arg?.noRecentEntry }; const uriToOpen: IWindowOpenable = (hasWorkspaceFileExtension(uri) || uri.scheme === Schemas.untitled) ? { workspaceUri: uri } : { folderUri: uri }; From 267188e90de303bccb6fa031ff0c0e8f724dab39 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 7 Dec 2020 11:45:32 +0100 Subject: [PATCH 146/200] highlightModifiedTabs and pinned tabs issue (fix #111641) --- .../parts/editor/media/tabstitlecontrol.css | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css index a9158b796e4..637279fe48c 100644 --- a/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/tabstitlecontrol.css @@ -3,6 +3,37 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +/* + ################################### z-index explainer ################################### + + Tabs have various levels of z-index depending on state, typically: + - scrollbar should be above all + - sticky (compact, shrink) tabs need to be above non-sticky tabs for scroll under effect + including non-sticky tabs-top borders, otherwise these borders would not scroll under + (https://github.com/microsoft/vscode/issues/111641) + - bottom-border needs to be above tabs bottom border to win but also support sticky tabs + (https://github.com/microsoft/vscode/issues/99084) <- this currently cannot be done and + is still broken. putting sticky-tabs above tabs bottom border would not render this + border at all for sticky tabs. + + On top of that there is 2 borders with a z-index for a general border below tabs + - tabs bottom border + - editor title bottom border (when breadcrumbs are disabled, this border will appear + same as tabs bottom border) + + The following tabls shows the current stacking order: + + [z-index] [kind] + 7 scrollbar + 6 active-tab border-bottom + 5 tabs, title border bottom + 4 sticky-tab + 2 active/dirty-tab border top + 0 tab + + ########################################################################################## +*/ + /* Title Container */ .monaco-workbench .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container { @@ -30,7 +61,7 @@ } .monaco-workbench .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container > .monaco-scrollable-element .scrollbar { - z-index: 3; /* on top of tabs */ + z-index: 7; cursor: default; } @@ -89,7 +120,7 @@ /** Sticky compact/shrink tabs do not scroll in case of overflow and are always above unsticky tabs which scroll under */ position: sticky; - z-index: 1; + z-index: 4; /** Sticky compact/shrink tabs are even and never grow */ flex-basis: 0; @@ -167,24 +198,26 @@ display: block; position: absolute; left: 0; - z-index: 6; /* over possible title border */ pointer-events: none; width: 100%; } .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active.tab-border-top > .tab-border-top-container { + z-index: 2; top: 0; height: 1px; background-color: var(--tab-border-top-color); } .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active.tab-border-bottom > .tab-border-bottom-container { + z-index: 6; bottom: 0; height: 1px; background-color: var(--tab-border-bottom-color); } .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty-border-top > .tab-border-top-container { + z-index: 2; top: 0; height: 2px; background-color: var(--tab-dirty-border-top-color); From ea0b7fd29af51136688960c9ded4209964e3fe99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 7 Dec 2020 11:57:52 +0100 Subject: [PATCH 147/200] Revert "build: create asset should still try to add asset" This reverts commit 5e350b1b79675cecdff224eb00f7bf62ae8789fc. --- build/azure-pipelines/common/createAsset.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/build/azure-pipelines/common/createAsset.ts b/build/azure-pipelines/common/createAsset.ts index 127993e6230..d7e62629cb8 100644 --- a/build/azure-pipelines/common/createAsset.ts +++ b/build/azure-pipelines/common/createAsset.ts @@ -93,12 +93,16 @@ async function main(): Promise { const blobExists = await doesAssetExist(blobService, quality, blobName); if (blobExists) { - console.log(`Blob ${quality}, ${blobName} already exists, not uploading again.`); - } else { - await uploadBlob(blobService, quality, blobName, filePath, fileName); - console.log('Blobs successfully uploaded.'); + console.log(`Blob ${quality}, ${blobName} already exists, not publishing again.`); + return; } + console.log('Uploading blobs to Azure storage...'); + + await uploadBlob(blobService, quality, blobName, filePath, fileName); + + console.log('Blobs successfully uploaded.'); + const asset: Asset = { platform, type, From 64f63a3dd708a8da72905a1126aa44b26d293a81 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 7 Dec 2020 12:20:59 +0100 Subject: [PATCH 148/200] Fix #108266 --- src/vs/editor/contrib/hover/modesContentHover.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index ad2d6b27263..57f95fe179f 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -8,7 +8,7 @@ import * as dom from 'vs/base/browser/dom'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Color, RGBA } from 'vs/base/common/color'; import { IMarkdownString, MarkdownString, isEmptyMarkdownString, markedStringsEquals } from 'vs/base/common/htmlContent'; -import { IDisposable, toDisposable, DisposableStore, combinedDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, toDisposable, DisposableStore, combinedDisposable, MutableDisposable, Disposable } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; @@ -606,7 +606,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget { this.recentMarkerCodeActionsInfo = undefined; } } - const updatePlaceholderDisposable = disposables.add(disposableTimeout(() => quickfixPlaceholderElement.textContent = nls.localize('checkingForQuickFixes', "Checking for quick fixes..."), 64)); + const updatePlaceholderDisposable = this.recentMarkerCodeActionsInfo && !this.recentMarkerCodeActionsInfo.hasCodeActions ? Disposable.None : disposables.add(disposableTimeout(() => quickfixPlaceholderElement.textContent = nls.localize('checkingForQuickFixes', "Checking for quick fixes..."), 200)); const codeActionsPromise = this.getCodeActions(markerHover.marker); disposables.add(toDisposable(() => codeActionsPromise.cancel())); codeActionsPromise.then(actions => { From 3835563e123aefda53337fce7b215cc81a535047 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 7 Dec 2020 13:47:20 +0100 Subject: [PATCH 149/200] Fix #112012 --- src/vs/workbench/browser/web.main.ts | 6 ++--- .../electron-browser/desktop.main.ts | 4 ++-- .../electron-sandbox/desktop.main.ts | 4 ++-- .../sandbox.simpleservices.ts | 5 +++- .../configuration/browser/configuration.ts | 4 ++++ .../browser/configurationService.ts | 23 +++++++++++++++---- .../configuration/common/configuration.ts | 11 +++++++++ 7 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index e7d260b00ce..20df4472969 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -24,7 +24,7 @@ import { IFileService, IFileSystemProvider } from 'vs/platform/files/common/file import { FileService } from 'vs/platform/files/common/fileService'; import { Schemas } from 'vs/base/common/network'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { onUnexpectedError } from 'vs/base/common/errors'; import { setFullscreen } from 'vs/base/browser/browser'; import { isIOS, isMacintosh } from 'vs/base/common/platform'; @@ -158,7 +158,7 @@ class BrowserMain extends Disposable { }, undefined, isMacintosh ? 2000 /* adjust for macOS animation */ : 800 /* can be throttled */)); } - private async initServices(): Promise<{ serviceCollection: ServiceCollection, configurationService: IConfigurationService, logService: ILogService, storageService: BrowserStorageService }> { + private async initServices(): Promise<{ serviceCollection: ServiceCollection, configurationService: IWorkbenchConfigurationService, logService: ILogService, storageService: BrowserStorageService }> { const serviceCollection = new ServiceCollection(); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -212,7 +212,7 @@ class BrowserMain extends Disposable { serviceCollection.set(IWorkspaceContextService, service); // Configuration - serviceCollection.set(IConfigurationService, service); + serviceCollection.set(IWorkbenchConfigurationService, service); return service; }), diff --git a/src/vs/workbench/electron-browser/desktop.main.ts b/src/vs/workbench/electron-browser/desktop.main.ts index 5f159a168dc..fdcd679f8b8 100644 --- a/src/vs/workbench/electron-browser/desktop.main.ts +++ b/src/vs/workbench/electron-browser/desktop.main.ts @@ -28,7 +28,7 @@ import { Schemas } from 'vs/base/common/network'; import { sanitizeFilePath } from 'vs/base/common/extpath'; import { GlobalStorageDatabaseChannelClient } from 'vs/platform/storage/node/storageIpc'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { Disposable } from 'vs/base/common/lifecycle'; import { registerWindowDriver } from 'vs/platform/driver/electron-browser/driver'; @@ -270,7 +270,7 @@ class DesktopMain extends Disposable { serviceCollection.set(IWorkspaceContextService, service); // Configuration - serviceCollection.set(IConfigurationService, service); + serviceCollection.set(IWorkbenchConfigurationService, service); return service; }), diff --git a/src/vs/workbench/electron-sandbox/desktop.main.ts b/src/vs/workbench/electron-sandbox/desktop.main.ts index eddd5ab64aa..dc8f60572cc 100644 --- a/src/vs/workbench/electron-sandbox/desktop.main.ts +++ b/src/vs/workbench/electron-sandbox/desktop.main.ts @@ -16,7 +16,7 @@ import { reviveWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspa import { ILogService } from 'vs/platform/log/common/log'; import { Schemas } from 'vs/base/common/network'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { Disposable } from 'vs/base/common/lifecycle'; import { IMainProcessService, MainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService'; @@ -239,7 +239,7 @@ class DesktopMain extends Disposable { serviceCollection.set(IWorkspaceContextService, service); // Configuration - serviceCollection.set(IConfigurationService, new SimpleConfigurationService()); + serviceCollection.set(IWorkbenchConfigurationService, new SimpleConfigurationService()); return service; }), diff --git a/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts b/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts index ada7a23fa4d..f7112d49068 100644 --- a/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts +++ b/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts @@ -56,6 +56,7 @@ import { Schemas } from 'vs/base/common/network'; import { BrowserKeyboardLayoutService } from 'vs/workbench/services/keybinding/browser/keyboardLayoutService'; import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminalInstanceService'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; //#region Environment @@ -191,7 +192,9 @@ export class SimpleStorageService extends InMemoryStorageService { } //#region Configuration -export class SimpleConfigurationService extends BaseSimpleConfigurationService { } +export class SimpleConfigurationService extends BaseSimpleConfigurationService implements IWorkbenchConfigurationService { + async whenRemoteConfigurationLoaded() { } +} //#endregion diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 973ef52ffc5..87318b454bb 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -187,6 +187,9 @@ export class RemoteUserConfiguration extends Disposable { private readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); public readonly onDidChangeConfiguration: Event = this._onDidChangeConfiguration.event; + private readonly _onDidInitialize = this._register(new Emitter()); + public readonly onDidInitialize = this._onDidInitialize.event; + constructor( remoteAuthority: string, configurationCache: IConfigurationCache, @@ -205,6 +208,7 @@ export class RemoteUserConfiguration extends Disposable { this._userConfiguration.dispose(); this._userConfiguration = userConfiguration; this.onDidUserConfigurationChange(configurationModel); + this._onDidInitialize.fire(configurationModel); } }); } diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 7a1b2cd45b1..49a78f4d185 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -12,9 +12,9 @@ import { Queue, Barrier, runWhenIdle } from 'vs/base/common/async'; import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { IWorkspaceContextService, Workspace as BaseWorkspace, WorkbenchState, IWorkspaceFolder, toWorkspaceFolders, IWorkspaceFoldersChangeEvent, WorkspaceFolder, toWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ConfigurationModel, DefaultConfigurationModel, ConfigurationChangeEvent, AllKeysConfigurationChangeEvent, mergeChanges } from 'vs/platform/configuration/common/configurationModels'; -import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData, IConfigurationService, IConfigurationValue, IConfigurationChange } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData, IConfigurationValue, IConfigurationChange } from 'vs/platform/configuration/common/configuration'; import { Configuration } from 'vs/workbench/services/configuration/common/configurationModels'; -import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings, machineOverridableSettings } from 'vs/platform/configuration/common/configurationRegistry'; import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceInitializationPayload, isSingleFolderWorkspaceInitializationPayload, ISingleFolderWorkspaceInitializationPayload, IEmptyWorkspaceInitializationPayload, useSlashForPath, getStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; @@ -38,11 +38,12 @@ class Workspace extends BaseWorkspace { initialized: boolean = false; } -export class WorkspaceService extends Disposable implements IConfigurationService, IWorkspaceContextService { +export class WorkspaceService extends Disposable implements IWorkbenchConfigurationService, IWorkspaceContextService { public _serviceBrand: undefined; private workspace!: Workspace; + private initRemoteUserConfigurationBarrier: Barrier; private completeWorkspaceBarrier: Barrier; private readonly configurationCache: IConfigurationCache; private _configuration: Configuration; @@ -93,6 +94,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic configurationRegistry.registerDefaultConfigurations([environmentService.options.configurationDefaults]); } + this.initRemoteUserConfigurationBarrier = new Barrier(); this.completeWorkspaceBarrier = new Barrier(); this.defaultConfiguration = new DefaultConfigurationModel(); this.configurationCache = configurationCache; @@ -104,9 +106,16 @@ export class WorkspaceService extends Disposable implements IConfigurationServic this.localUserConfiguration = this._register(new UserConfiguration(environmentService.settingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, fileService)); this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration))); if (remoteAuthority) { - this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, fileService, remoteAgentService)); - this._register(this.remoteUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onRemoteUserConfigurationChanged(userConfiguration))); + const remoteUserConfiguration = this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, fileService, remoteAgentService)); + this._register(remoteUserConfiguration.onDidInitialize(remoteUserConfigurationModel => { + this._register(remoteUserConfiguration.onDidChangeConfiguration(remoteUserConfigurationModel => this.onRemoteUserConfigurationChanged(remoteUserConfigurationModel))); + this.onRemoteUserConfigurationChanged(remoteUserConfigurationModel); + this.initRemoteUserConfigurationBarrier.open(); + })); + } else { + this.initRemoteUserConfigurationBarrier.open(); } + this.workspaceConfiguration = this._register(new WorkspaceConfiguration(configurationCache, fileService)); this._register(this.workspaceConfiguration.onDidUpdateConfiguration(() => { this.onWorkspaceConfigurationChanged().then(() => { @@ -336,6 +345,10 @@ export class WorkspaceService extends Disposable implements IConfigurationServic return this._configuration.keys(); } + public async whenRemoteConfigurationLoaded(): Promise { + await this.initRemoteUserConfigurationBarrier.wait(); + } + async initialize(arg: IWorkspaceInitializationPayload): Promise { mark('willInitWorkspaceService'); diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index edec7c0032b..e54d141f447 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -5,6 +5,8 @@ import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { URI } from 'vs/base/common/uri'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const FOLDER_CONFIG_FOLDER_NAME = '.vscode'; export const FOLDER_SETTINGS_NAME = 'settings'; @@ -43,4 +45,13 @@ export interface IConfigurationCache { } +export const IWorkbenchConfigurationService = createDecorator('configurationService'); +export interface IWorkbenchConfigurationService extends IConfigurationService { + /** + * A promise that resolves when the remote configuration is loaded in a remote window. + * The promise is resolved immediately if the window is not remote. + */ + whenRemoteConfigurationLoaded(): Promise; +} + export const TASKS_DEFAULT = '{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": []\n}'; From c4d77ea6193e639dfad1431fe92a6c611d697a28 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 7 Dec 2020 14:02:32 +0100 Subject: [PATCH 150/200] #89559 Set logsPath in window configuration --- src/vs/code/electron-main/window.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index e09fb03efd2..4379b1a8d6e 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -781,6 +781,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { windowConfiguration.windowId = this._win.id; windowConfiguration.sessionId = `window:${this._win.id}`; windowConfiguration.logLevel = this.logService.getLevel(); + windowConfiguration.logsPath = this.environmentService.logsPath; // Set zoomlevel const windowConfig = this.configurationService.getValue('window'); From 66aab34216f488c803b49ff14d50dec90147ad6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 7 Dec 2020 14:42:27 +0100 Subject: [PATCH 151/200] retry createAsset sproc due to ECONNRESET --- build/azure-pipelines/common/createAsset.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/build/azure-pipelines/common/createAsset.ts b/build/azure-pipelines/common/createAsset.ts index d7e62629cb8..666bf05bf68 100644 --- a/build/azure-pipelines/common/createAsset.ts +++ b/build/azure-pipelines/common/createAsset.ts @@ -66,6 +66,20 @@ function getEnv(name: string): string { return result; } +async function retry(fn: () => Promise): Promise { + for (let run = 1; run <= 10; run++) { + try { + return await fn(); + } catch (err) { + if (!/ECONNRESET/.test(err.message)) { + throw err; + } + } + } + + throw new Error('Retried too many times'); +} + async function main(): Promise { const [, , platform, type, fileName, filePath] = process.argv; const quality = getEnv('VSCODE_QUALITY'); @@ -121,7 +135,7 @@ async function main(): Promise { const client = new CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT']!, key: process.env['AZURE_DOCUMENTDB_MASTERKEY'] }); const scripts = client.database('builds').container(quality).scripts; - await scripts.storedProcedure('createAsset').execute('', [commit, asset, true]); + await retry(() => scripts.storedProcedure('createAsset').execute('', [commit, asset, true])); } main().then(() => { From 36628d73b916f872ad2cf3679b38d6a1b32f44ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 7 Dec 2020 15:02:48 +0100 Subject: [PATCH 152/200] add exponential backoff --- build/azure-pipelines/common/createAsset.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/azure-pipelines/common/createAsset.ts b/build/azure-pipelines/common/createAsset.ts index 666bf05bf68..b6d4c966f67 100644 --- a/build/azure-pipelines/common/createAsset.ts +++ b/build/azure-pipelines/common/createAsset.ts @@ -74,6 +74,9 @@ async function retry(fn: () => Promise): Promise { if (!/ECONNRESET/.test(err.message)) { throw err; } + + // maximum delay is 10th retry: ~3 seconds + await new Promise(c => setTimeout(c, (Math.random() * 200) + (50 * Math.pow(1.5, run)))); } } From ffdc1096fa5a1f16a01eff8a6d666100f13b181b Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 7 Dec 2020 15:16:49 +0100 Subject: [PATCH 153/200] Windows - Taskbar entry context menu is empty (fix #111177) --- .../workspaces/electron-main/workspacesHistoryMainService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts index 7a5baa225e5..e0609a560b2 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts @@ -370,7 +370,7 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa return { type: 'task', title, - description, + description: description.substr(0, 255), // https://github.com/microsoft/vscode/issues/111177 program: process.execPath, args, iconPath: 'explorer.exe', // simulate folder icon From de22e951f9ed9f985aa1d6773d3a2d2c43a576d6 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 7 Dec 2020 15:22:04 +0100 Subject: [PATCH 154/200] more cleanup for #111177 --- .../workspacesHistoryMainService.ts | 90 +++++++++---------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts index e0609a560b2..91d62d0ff95 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts @@ -330,57 +330,53 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa }); // Recent Workspaces - try { - if (this.getRecentlyOpened().workspaces.length > 0) { + if (this.getRecentlyOpened().workspaces.length > 0) { - // The user might have meanwhile removed items from the jump list and we have to respect that - // so we need to update our list of recent paths with the choice of the user to not add them again - // Also: Windows will not show our custom category at all if there is any entry which was removed - // by the user! See https://github.com/microsoft/vscode/issues/15052 - let toRemove: URI[] = []; - for (let item of app.getJumpListSettings().removedItems) { - const args = item.args; - if (args) { - const match = /^--(folder|file)-uri\s+"([^"]+)"$/.exec(args); - if (match) { - toRemove.push(URI.parse(match[2])); - } + // The user might have meanwhile removed items from the jump list and we have to respect that + // so we need to update our list of recent paths with the choice of the user to not add them again + // Also: Windows will not show our custom category at all if there is any entry which was removed + // by the user! See https://github.com/microsoft/vscode/issues/15052 + let toRemove: URI[] = []; + for (let item of app.getJumpListSettings().removedItems) { + const args = item.args; + if (args) { + const match = /^--(folder|file)-uri\s+"([^"]+)"$/.exec(args); + if (match) { + toRemove.push(URI.parse(match[2])); } } - this.removeRecentlyOpened(toRemove); - - // Add entries - jumpList.push({ - type: 'custom', - name: nls.localize('recentFolders', "Recent Workspaces"), - items: arrays.coalesce(this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(recent => { - const workspace = isRecentWorkspace(recent) ? recent.workspace : recent.folderUri; - const title = recent.label ? splitName(recent.label).name : this.getSimpleWorkspaceLabel(workspace, this.environmentService.untitledWorkspacesHome); - - let description; - let args; - if (isSingleFolderWorkspaceIdentifier(workspace)) { - description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(dirname(workspace), this.environmentService)); - args = `--folder-uri "${workspace.toString()}"`; - } else { - description = nls.localize('workspaceDesc', "{0} {1}", getBaseLabel(workspace.configPath), getPathLabel(dirname(workspace.configPath), this.environmentService)); - args = `--file-uri "${workspace.configPath.toString()}"`; - } - - return { - type: 'task', - title, - description: description.substr(0, 255), // https://github.com/microsoft/vscode/issues/111177 - program: process.execPath, - args, - iconPath: 'explorer.exe', // simulate folder icon - iconIndex: 0 - }; - })) - }); } - } catch (error) { - this.logService.warn('updateWindowsJumpList#recentWorkspaces', error); // https://github.com/microsoft/vscode/issues/111177 + this.removeRecentlyOpened(toRemove); + + // Add entries + jumpList.push({ + type: 'custom', + name: nls.localize('recentFolders', "Recent Workspaces"), + items: arrays.coalesce(this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(recent => { + const workspace = isRecentWorkspace(recent) ? recent.workspace : recent.folderUri; + const title = recent.label ? splitName(recent.label).name : this.getSimpleWorkspaceLabel(workspace, this.environmentService.untitledWorkspacesHome); + + let description; + let args; + if (isSingleFolderWorkspaceIdentifier(workspace)) { + description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(dirname(workspace), this.environmentService)); + args = `--folder-uri "${workspace.toString()}"`; + } else { + description = nls.localize('workspaceDesc', "{0} {1}", getBaseLabel(workspace.configPath), getPathLabel(dirname(workspace.configPath), this.environmentService)); + args = `--file-uri "${workspace.configPath.toString()}"`; + } + + return { + type: 'task', + title: title.substr(0, 255), // Windows seems to be picky around the length of entries + description: description.substr(0, 255), // (see https://github.com/microsoft/vscode/issues/111177) + program: process.execPath, + args, + iconPath: 'explorer.exe', // simulate folder icon + iconIndex: 0 + }; + })) + }); } // Recent From d0475711090b596bbf44e9afc90b074b9eb1082f Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 7 Dec 2020 15:33:52 +0100 Subject: [PATCH 155/200] Prompt to save untitled file before run/debug fixes #111850 --- src/vs/workbench/contrib/debug/browser/debugService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index e05a471f57b..586c15415e0 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -289,7 +289,7 @@ export class DebugService implements IDebugService { // make sure to save all files and that the configuration is up to date await this.extensionService.activateByEvent('onDebug'); if (!options?.parentSession) { - await this.editorService.saveAll(); + await this.editorService.saveAll({ includeUntitled: true }); } await this.configurationService.reloadConfiguration(launch ? launch.workspace : undefined); await this.extensionService.whenInstalledExtensionsRegistered(); From 4250e343e0fc3af2a2de719a0f49cb40fbe8e32e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 7 Dec 2020 16:15:57 +0100 Subject: [PATCH 156/200] use proper repos for linux arm --- build/gulpfile.vscode.linux.js | 1 + resources/linux/debian/postinst.template | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build/gulpfile.vscode.linux.js b/build/gulpfile.vscode.linux.js index 2833bb14a20..9de7f9bb62c 100644 --- a/build/gulpfile.vscode.linux.js +++ b/build/gulpfile.vscode.linux.js @@ -98,6 +98,7 @@ function prepareDebPackage(arch) { .pipe(replace('@@ARCHITECTURE@@', debArch)) .pipe(replace('@@QUALITY@@', product.quality || '@@QUALITY@@')) .pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@')) + .pipe(replace('@@REPOSITORY_NAME@@', arch === 'x64' ? 'vscode' : 'code')) .pipe(rename('DEBIAN/postinst')); const all = es.merge(control, postinst, postrm, prerm, desktops, appdata, workspaceMime, icon, bash_completion, zsh_completion, code); diff --git a/resources/linux/debian/postinst.template b/resources/linux/debian/postinst.template index 9f26b350999..e1b201b4f9a 100755 --- a/resources/linux/debian/postinst.template +++ b/resources/linux/debian/postinst.template @@ -73,6 +73,6 @@ NdCFTW7wY0Fb1fWJ+/KTsC4= if [ "$WRITE_SOURCE" -eq "1" ]; then echo "### THIS FILE IS AUTOMATICALLY CONFIGURED ### # You may comment out this entry, but any other modifications may be lost. -deb [arch=amd64] http://packages.microsoft.com/repos/vscode stable main" > $CODE_SOURCE_PART +deb [arch=amd64] http://packages.microsoft.com/repos/@@REPOSITORY_NAME@@ stable main" > $CODE_SOURCE_PART fi fi From c2de3a602e8ee704180f1ee95c4240f733fd92ac Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru Date: Mon, 7 Dec 2020 16:34:55 +0100 Subject: [PATCH 157/200] Tweak candidates notebook query --- .vscode/notebooks/endgame.github-issues | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/notebooks/endgame.github-issues b/.vscode/notebooks/endgame.github-issues index e749a11c4be..6f09e38c443 100644 --- a/.vscode/notebooks/endgame.github-issues +++ b/.vscode/notebooks/endgame.github-issues @@ -104,7 +104,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS $MILESTONE label:candidate", + "value": "$REPOS $MILESTONE is:issue is:open label:candidate", "editable": true } ] \ No newline at end of file From cf8ed37206e161a30151defa4fc9ea58c32335bc Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 7 Dec 2020 16:56:54 +0100 Subject: [PATCH 158/200] fixes #111850 --- src/vs/workbench/contrib/debug/browser/debugService.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index 586c15415e0..2dc02fc743b 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -289,7 +289,12 @@ export class DebugService implements IDebugService { // make sure to save all files and that the configuration is up to date await this.extensionService.activateByEvent('onDebug'); if (!options?.parentSession) { - await this.editorService.saveAll({ includeUntitled: true }); + await this.editorService.saveAll(); + const activeEditor = this.editorService.activeEditorPane; + if (activeEditor) { + // Make sure to save the active editor in case it is in untitled file it wont be saved as part of saveAll #111850 + await this.editorService.save({ editor: activeEditor.input, groupId: activeEditor.group.id }); + } } await this.configurationService.reloadConfiguration(launch ? launch.workspace : undefined); await this.extensionService.whenInstalledExtensionsRegistered(); From ab8c8dbd8e5de3fd6f0650a7f23ed660b0211b6a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 7 Dec 2020 17:54:11 +0100 Subject: [PATCH 159/200] Fix #112030 --- .../src/configurationEditingMain.ts | 4 ++-- .../configuration-editing/src/extensionsProposals.ts | 4 ++-- .../src/settingsDocumentHelper.ts | 11 ++++++++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/extensions/configuration-editing/src/configurationEditingMain.ts b/extensions/configuration-editing/src/configurationEditingMain.ts index 966073e23f8..a3ef34f3d83 100644 --- a/extensions/configuration-editing/src/configurationEditingMain.ts +++ b/extensions/configuration-editing/src/configurationEditingMain.ts @@ -81,7 +81,7 @@ function registerExtensionsCompletionsInExtensionsDocument(): vscode.Disposable const range = document.getWordRangeAtPosition(position) || new vscode.Range(position, position); if (location.path[0] === 'recommendations') { const extensionsContent = parse(document.getText()); - return provideInstalledExtensionProposals(extensionsContent && extensionsContent.recommendations || [], range, false); + return provideInstalledExtensionProposals(extensionsContent && extensionsContent.recommendations || [], '', range, false); } return []; } @@ -95,7 +95,7 @@ function registerExtensionsCompletionsInWorkspaceConfigurationDocument(): vscode const range = document.getWordRangeAtPosition(position) || new vscode.Range(position, position); if (location.path[0] === 'extensions' && location.path[1] === 'recommendations') { const extensionsContent = parse(document.getText())['extensions']; - return provideInstalledExtensionProposals(extensionsContent && extensionsContent.recommendations || [], range, false); + return provideInstalledExtensionProposals(extensionsContent && extensionsContent.recommendations || [], '', range, false); } return []; } diff --git a/extensions/configuration-editing/src/extensionsProposals.ts b/extensions/configuration-editing/src/extensionsProposals.ts index 60533ae2975..7fef9836bdc 100644 --- a/extensions/configuration-editing/src/extensionsProposals.ts +++ b/extensions/configuration-editing/src/extensionsProposals.ts @@ -8,14 +8,14 @@ import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -export function provideInstalledExtensionProposals(existing: string[], range: vscode.Range, includeBuiltinExtensions: boolean): vscode.ProviderResult { +export function provideInstalledExtensionProposals(existing: string[], additionalText: string, range: vscode.Range, includeBuiltinExtensions: boolean): vscode.ProviderResult { if (Array.isArray(existing)) { const extensions = includeBuiltinExtensions ? vscode.extensions.all : vscode.extensions.all.filter(e => !(e.id.startsWith('vscode.') || e.id === 'Microsoft.vscode-markdown')); const knownExtensionProposals = extensions.filter(e => existing.indexOf(e.id) === -1); if (knownExtensionProposals.length) { return knownExtensionProposals.map(e => { const item = new vscode.CompletionItem(e.id); - const insertText = `"${e.id}"`; + const insertText = `"${e.id}"${additionalText}`; item.kind = vscode.CompletionItemKind.Value; item.insertText = insertText; item.range = range; diff --git a/extensions/configuration-editing/src/settingsDocumentHelper.ts b/extensions/configuration-editing/src/settingsDocumentHelper.ts index 5e466c2eb6f..f3461f0c3b5 100644 --- a/extensions/configuration-editing/src/settingsDocumentHelper.ts +++ b/extensions/configuration-editing/src/settingsDocumentHelper.ts @@ -48,7 +48,16 @@ export class SettingsDocument { try { ignoredExtensions = parse(this.document.getText())['settingsSync.ignoredExtensions']; } catch (e) {/* ignore error */ } - return provideInstalledExtensionProposals(ignoredExtensions, range, true); + return provideInstalledExtensionProposals(ignoredExtensions, '', range, true); + } + + // remote.extensionKind + if (location.path[0] === 'remote.extensionKind' && location.path.length === 2 && location.isAtPropertyKey) { + let alreadyConfigured: string[] = []; + try { + alreadyConfigured = Object.keys(parse(this.document.getText())['remote.extensionKind']); + } catch (e) {/* ignore error */ } + return provideInstalledExtensionProposals(alreadyConfigured, `: [\n\t"ui"\n]`, range, true); } return this.provideLanguageOverridesCompletionItems(location, position); From 3655a82edcbac3158ce6d26c3cb8cd0401ab70d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 7 Dec 2020 19:56:05 +0100 Subject: [PATCH 160/200] add log to createAsset retry --- build/azure-pipelines/common/createAsset.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build/azure-pipelines/common/createAsset.ts b/build/azure-pipelines/common/createAsset.ts index b6d4c966f67..f422d358b50 100644 --- a/build/azure-pipelines/common/createAsset.ts +++ b/build/azure-pipelines/common/createAsset.ts @@ -75,8 +75,11 @@ async function retry(fn: () => Promise): Promise { throw err; } + const millis = (Math.random() * 200) + (50 * Math.pow(1.5, run)); + console.log(`Creating build asset failed with ECONNRESET, retrying in ${millis}ms...`); + // maximum delay is 10th retry: ~3 seconds - await new Promise(c => setTimeout(c, (Math.random() * 200) + (50 * Math.pow(1.5, run)))); + await new Promise(c => setTimeout(c, millis)); } } From f79bb79d2b6db5c14dca88578999d21f0be42260 Mon Sep 17 00:00:00 2001 From: Greg Van Liew Date: Mon, 7 Dec 2020 13:57:02 -0800 Subject: [PATCH 161/200] Suggest a different description (#112049) --- .../gettingStarted/browser/gettingStarted.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.contribution.ts b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.contribution.ts index b53ddab8504..8f80d2b98bb 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.contribution.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.contribution.ts @@ -44,7 +44,7 @@ if (product.quality !== 'stable') { properties: { 'workbench.experimental.gettingStarted': { type: 'boolean', - description: localize('gettingStartedDescription', "Enables an experimental Getting Started page, accesible via the Help menu."), + description: localize('gettingStartedDescription', "Enables an experimental Getting Started page, available via the Help menu."), default: false, } } From 91c7834e926533bd119b1a4c188b87ed7e2d4f8b Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Mon, 7 Dec 2020 16:00:00 -0800 Subject: [PATCH 162/200] debug: update js-debug --- product.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product.json b/product.json index ee6e68b480e..207bcf8f512 100644 --- a/product.json +++ b/product.json @@ -91,7 +91,7 @@ }, { "name": "ms-vscode.js-debug", - "version": "1.52.1", + "version": "1.52.2", "repo": "https://github.com/microsoft/vscode-js-debug", "metadata": { "id": "25629058-ddac-4e17-abba-74678e126c5d", From aa18ca682765edd34edb0c231053577c5d5835d8 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 8 Dec 2020 08:38:03 +0100 Subject: [PATCH 163/200] Unable to find the registered languages while saving the file. (fix #111788) --- .../services/dialogs/browser/abstractFileDialogService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts b/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts index 222e877c68b..1cd34887e54 100644 --- a/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts +++ b/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts @@ -283,10 +283,10 @@ export abstract class AbstractFileDialogService implements IFileDialogService { const filter: IFilter = { name: languageName, extensions: distinct(extensions).slice(0, 10).map(e => trim(e, '.')) }; - if (ext && extensions.indexOf(ext) >= 0) { + if (ext && extensions.indexOf(ext) >= 0 && !matchingFilter) { matchingFilter = filter; - return null; // matching filter will be added last to the top + return null; // first matching filter will be added to the top } return filter; From 6f5448afac57db6b850be930bee3d5e991557166 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru Date: Tue, 8 Dec 2020 09:01:59 +0100 Subject: [PATCH 164/200] Include candidate pull requests --- .vscode/notebooks/endgame.github-issues | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/notebooks/endgame.github-issues b/.vscode/notebooks/endgame.github-issues index 6f09e38c443..a3c81e4cc6e 100644 --- a/.vscode/notebooks/endgame.github-issues +++ b/.vscode/notebooks/endgame.github-issues @@ -104,7 +104,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS $MILESTONE is:issue is:open label:candidate", + "value": "$REPOS $MILESTONE is:open label:candidate", "editable": true } ] \ No newline at end of file From a6946159d4e880b630604db186ad9c6dc53e9e95 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 8 Dec 2020 09:29:16 +0100 Subject: [PATCH 165/200] :lipstick: layers checker --- build/lib/layersChecker.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/build/lib/layersChecker.ts b/build/lib/layersChecker.ts index 1c7579206af..c0d67db6017 100644 --- a/build/lib/layersChecker.ts +++ b/build/lib/layersChecker.ts @@ -25,8 +25,6 @@ import { match } from 'minimatch'; // Feel free to add more core types as you see needed if present in node.js and browsers const CORE_TYPES = [ 'require', // from our AMD loader - // 'atob', - // 'btoa', 'setTimeout', 'clearTimeout', 'setInterval', From 3212ddbc76fa2ceaa75724245729eaa22022c1cd Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 8 Dec 2020 09:40:42 +0100 Subject: [PATCH 166/200] multibyteAwareBtoa - add commented out failing test for #112013 --- src/vs/base/test/browser/dom.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/base/test/browser/dom.test.ts b/src/vs/base/test/browser/dom.test.ts index 99b4f1b90fc..c7f92e59ab1 100644 --- a/src/vs/base/test/browser/dom.test.ts +++ b/src/vs/base/test/browser/dom.test.ts @@ -73,8 +73,9 @@ suite('dom', () => { }); test('multibyteAwareBtoa', () => { - assert.equal(dom.multibyteAwareBtoa('hello world'), dom.multibyteAwareBtoa('hello world')); - assert.ok(dom.multibyteAwareBtoa('平仮名')); + assert.ok(dom.multibyteAwareBtoa('hello world').length > 0); + assert.ok(dom.multibyteAwareBtoa('平仮名').length > 0); + //assert.ok(dom.multibyteAwareBtoa(new Array(100000).fill('vs').join('')).length > 0); // https://github.com/microsoft/vscode/issues/112013 }); suite('$', () => { From 0e885aaf70ccffd3f2f6ad66c558cfd95e415719 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 8 Dec 2020 09:59:21 +0100 Subject: [PATCH 167/200] retry all cosmosdb ops --- build/azure-pipelines/common/createAsset.ts | 21 +-------------- build/azure-pipelines/common/createBuild.ts | 3 ++- build/azure-pipelines/common/releaseBuild.ts | 3 ++- build/azure-pipelines/common/retry.ts | 26 +++++++++++++++++++ build/azure-pipelines/common/sync-mooncake.ts | 5 ++-- 5 files changed, 34 insertions(+), 24 deletions(-) create mode 100644 build/azure-pipelines/common/retry.ts diff --git a/build/azure-pipelines/common/createAsset.ts b/build/azure-pipelines/common/createAsset.ts index f422d358b50..daf60d710ee 100644 --- a/build/azure-pipelines/common/createAsset.ts +++ b/build/azure-pipelines/common/createAsset.ts @@ -11,6 +11,7 @@ import * as crypto from 'crypto'; import * as azure from 'azure-storage'; import * as mime from 'mime'; import { CosmosClient } from '@azure/cosmos'; +import { retry } from './retry'; interface Asset { platform: string; @@ -66,26 +67,6 @@ function getEnv(name: string): string { return result; } -async function retry(fn: () => Promise): Promise { - for (let run = 1; run <= 10; run++) { - try { - return await fn(); - } catch (err) { - if (!/ECONNRESET/.test(err.message)) { - throw err; - } - - const millis = (Math.random() * 200) + (50 * Math.pow(1.5, run)); - console.log(`Creating build asset failed with ECONNRESET, retrying in ${millis}ms...`); - - // maximum delay is 10th retry: ~3 seconds - await new Promise(c => setTimeout(c, millis)); - } - } - - throw new Error('Retried too many times'); -} - async function main(): Promise { const [, , platform, type, fileName, filePath] = process.argv; const quality = getEnv('VSCODE_QUALITY'); diff --git a/build/azure-pipelines/common/createBuild.ts b/build/azure-pipelines/common/createBuild.ts index c8fd66b791d..e314d7c0988 100644 --- a/build/azure-pipelines/common/createBuild.ts +++ b/build/azure-pipelines/common/createBuild.ts @@ -6,6 +6,7 @@ 'use strict'; import { CosmosClient } from '@azure/cosmos'; +import { retry } from './retry'; if (process.argv.length !== 3) { console.error('Usage: node createBuild.js VERSION'); @@ -48,7 +49,7 @@ async function main(): Promise { const client = new CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT']!, key: process.env['AZURE_DOCUMENTDB_MASTERKEY'] }); const scripts = client.database('builds').container(quality).scripts; - await scripts.storedProcedure('createBuild').execute('', [{ ...build, _partitionKey: '' }]); + await retry(() => scripts.storedProcedure('createBuild').execute('', [{ ...build, _partitionKey: '' }])); } main().then(() => { diff --git a/build/azure-pipelines/common/releaseBuild.ts b/build/azure-pipelines/common/releaseBuild.ts index ac49e7b0042..d42b3f1a078 100644 --- a/build/azure-pipelines/common/releaseBuild.ts +++ b/build/azure-pipelines/common/releaseBuild.ts @@ -6,6 +6,7 @@ 'use strict'; import { CosmosClient } from '@azure/cosmos'; +import { retry } from './retry'; function getEnv(name: string): string { const result = process.env[name]; @@ -58,7 +59,7 @@ async function main(): Promise { console.log(`Releasing build ${commit}...`); const scripts = client.database('builds').container(quality).scripts; - await scripts.storedProcedure('releaseBuild').execute('', [commit]); + await retry(() => scripts.storedProcedure('releaseBuild').execute('', [commit])); } main().then(() => { diff --git a/build/azure-pipelines/common/retry.ts b/build/azure-pipelines/common/retry.ts new file mode 100644 index 00000000000..1737676590d --- /dev/null +++ b/build/azure-pipelines/common/retry.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +export async function retry(fn: () => Promise): Promise { + for (let run = 1; run <= 10; run++) { + try { + return await fn(); + } catch (err) { + if (!/ECONNRESET/.test(err.message)) { + throw err; + } + + const millis = (Math.random() * 200) + (50 * Math.pow(1.5, run)); + console.log(`Failed with ECONNRESET, retrying in ${millis}ms...`); + + // maximum delay is 10th retry: ~3 seconds + await new Promise(c => setTimeout(c, millis)); + } + } + + throw new Error('Retried too many times'); +} diff --git a/build/azure-pipelines/common/sync-mooncake.ts b/build/azure-pipelines/common/sync-mooncake.ts index 76f12185e12..4ffe7a8f15b 100644 --- a/build/azure-pipelines/common/sync-mooncake.ts +++ b/build/azure-pipelines/common/sync-mooncake.ts @@ -9,6 +9,7 @@ import * as url from 'url'; import * as azure from 'azure-storage'; import * as mime from 'mime'; import { CosmosClient } from '@azure/cosmos'; +import { retry } from './retry'; function log(...args: any[]) { console.log(...[`[${new Date().toISOString()}]`, ...args]); @@ -99,8 +100,8 @@ async function sync(commit: string, quality: string): Promise { log(` Updating build in DB...`); const mooncakeUrl = `${process.env['MOONCAKE_CDN_URL']}${blobPath}`; - await container.scripts.storedProcedure('setAssetMooncakeUrl') - .execute('', [commit, asset.platform, asset.type, mooncakeUrl]); + await retry(() => container.scripts.storedProcedure('setAssetMooncakeUrl') + .execute('', [commit, asset.platform, asset.type, mooncakeUrl])); log(` Done ✔️`); } catch (err) { From 861e7bcc1b28ee3a79111c1cbadd4b3d95269ef4 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Tue, 8 Dec 2020 10:02:34 +0100 Subject: [PATCH 168/200] Wait for the remote configuration before creating remote terminal processes --- .../contrib/terminal/common/remoteTerminalChannel.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts b/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts index cc4de710a0a..d25b3982fcc 100644 --- a/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts +++ b/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts @@ -7,7 +7,7 @@ import { Event } from 'vs/base/common/event'; import { withNullAsUndefined } from 'vs/base/common/types'; import { URI, UriComponents } from 'vs/base/common/uri'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { ILogService } from 'vs/platform/log/common/log'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -191,7 +191,7 @@ export class RemoteTerminalChannelClient { constructor( private readonly _remoteAuthority: string, private readonly _channel: IChannel, - @IConfigurationService private readonly _configurationService: IConfigurationService, + @IWorkbenchConfigurationService private readonly _configurationService: IWorkbenchConfigurationService, @IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService, @IConfigurationResolverService private readonly _resolverService: IConfigurationResolverService, @IEnvironmentVariableService private readonly _environmentVariableService: IEnvironmentVariableService, @@ -211,6 +211,9 @@ export class RemoteTerminalChannelClient { } public async createTerminalProcess(shellLaunchConfig: IShellLaunchConfigDto, activeWorkspaceRootUri: URI | undefined, shouldPersistTerminal: boolean, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise { + // Be sure to first wait for the remote configuration + await this._configurationService.whenRemoteConfigurationLoaded(); + const terminalConfig = this._configurationService.getValue(TERMINAL_CONFIG_SECTION); const configuration: ICompleteTerminalConfiguration = { 'terminal.integrated.automationShell.windows': this._readSingleTerminalConfiguration('terminal.integrated.automationShell.windows'), From 08e29d24b4b840155bbf7aed00ef590c96d11865 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 8 Dec 2020 10:20:14 +0100 Subject: [PATCH 169/200] Remove duplicate (case sensitive) recent workspace/folder names on the welcome screen (fix #111954) --- .../workspacesHistoryMainService.ts | 65 ++++++++++--------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts index 91d62d0ff95..f174547116c 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vs/nls'; -import * as arrays from 'vs/base/common/arrays'; +import { localize } from 'vs/nls'; +import { coalesce } from 'vs/base/common/arrays'; import { IStateService } from 'vs/platform/state/node/state'; import { app, JumpListCategory } from 'electron'; import { ILogService } from 'vs/platform/log/common/log'; @@ -14,7 +14,7 @@ import { isWindows, isMacintosh } from 'vs/base/common/platform'; import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IRecentlyOpened, isRecentWorkspace, isRecentFolder, IRecent, isRecentFile, IRecentFolder, IRecentWorkspace, IRecentFile, toStoreData, restoreRecentlyOpened, RecentlyOpenedStorageData, WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces'; import { IWorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService'; import { ThrottledDelayer } from 'vs/base/common/async'; -import { isEqual, dirname, originalFSPath, basename, extUriBiasedIgnorePathCase } from 'vs/base/common/resources'; +import { dirname, originalFSPath, basename, extUriBiasedIgnorePathCase } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService'; @@ -57,10 +57,10 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa declare readonly _serviceBrand: undefined; - private readonly _onRecentlyOpenedChange = new Emitter(); + private readonly _onRecentlyOpenedChange = this._register(new Emitter()); readonly onRecentlyOpenedChange: CommonEvent = this._onRecentlyOpenedChange.event; - private macOSRecentDocumentsUpdater = this._register(new ThrottledDelayer(800)); + private readonly macOSRecentDocumentsUpdater = this._register(new ThrottledDelayer(800)); constructor( @IStateService private readonly stateService: IStateService, @@ -89,40 +89,40 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa } this.updateWindowsJumpList(); - this.onRecentlyOpenedChange(() => this.updateWindowsJumpList()); + this._register(this.onRecentlyOpenedChange(() => this.updateWindowsJumpList())); } - addRecentlyOpened(newlyAdded: IRecent[]): void { + addRecentlyOpened(recentToAdd: IRecent[]): void { const workspaces: Array = []; const files: IRecentFile[] = []; - for (let curr of newlyAdded) { + for (let recent of recentToAdd) { // Workspace - if (isRecentWorkspace(curr)) { - if (!this.workspacesMainService.isUntitledWorkspace(curr.workspace) && indexOfWorkspace(workspaces, curr.workspace) === -1) { - workspaces.push(curr); + if (isRecentWorkspace(recent)) { + if (!this.workspacesMainService.isUntitledWorkspace(recent.workspace) && indexOfWorkspace(workspaces, recent.workspace) === -1) { + workspaces.push(recent); } } // Folder - else if (isRecentFolder(curr)) { - if (indexOfFolder(workspaces, curr.folderUri) === -1) { - workspaces.push(curr); + else if (isRecentFolder(recent)) { + if (indexOfFolder(workspaces, recent.folderUri) === -1) { + workspaces.push(recent); } } // File else { - const alreadyExistsInHistory = indexOfFile(files, curr.fileUri) >= 0; - const shouldBeFiltered = curr.fileUri.scheme === Schemas.file && WorkspacesHistoryMainService.COMMON_FILES_FILTER.indexOf(basename(curr.fileUri)) >= 0; + const alreadyExistsInHistory = indexOfFile(files, recent.fileUri) >= 0; + const shouldBeFiltered = recent.fileUri.scheme === Schemas.file && WorkspacesHistoryMainService.COMMON_FILES_FILTER.indexOf(basename(recent.fileUri)) >= 0; if (!alreadyExistsInHistory && !shouldBeFiltered) { - files.push(curr); + files.push(recent); // Add to recent documents (Windows only, macOS later) - if (isWindows && curr.fileUri.scheme === Schemas.file) { - app.addRecentDocument(curr.fileUri.fsPath); + if (isWindows && recent.fileUri.scheme === Schemas.file) { + app.addRecentDocument(recent.fileUri.fsPath); } } } @@ -147,14 +147,15 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa } } - removeRecentlyOpened(toRemove: URI[]): void { + removeRecentlyOpened(recentToRemove: URI[]): void { const keep = (recent: IRecent) => { const uri = location(recent); - for (const resource of toRemove) { - if (isEqual(resource, uri)) { + for (const resourceToRemove of recentToRemove) { + if (extUriBiasedIgnorePathCase.isEqual(resourceToRemove, uri)) { return false; } } + return true; }; @@ -319,8 +320,8 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa items: [ { type: 'task', - title: nls.localize('newWindow', "New Window"), - description: nls.localize('newWindowDesc', "Opens a new window"), + title: localize('newWindow', "New Window"), + description: localize('newWindowDesc', "Opens a new window"), program: process.execPath, args: '-n', // force new window iconPath: process.execPath, @@ -351,18 +352,18 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa // Add entries jumpList.push({ type: 'custom', - name: nls.localize('recentFolders', "Recent Workspaces"), - items: arrays.coalesce(this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(recent => { + name: localize('recentFolders', "Recent Workspaces"), + items: coalesce(this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(recent => { const workspace = isRecentWorkspace(recent) ? recent.workspace : recent.folderUri; const title = recent.label ? splitName(recent.label).name : this.getSimpleWorkspaceLabel(workspace, this.environmentService.untitledWorkspacesHome); let description; let args; if (isSingleFolderWorkspaceIdentifier(workspace)) { - description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(dirname(workspace), this.environmentService)); + description = localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(dirname(workspace), this.environmentService)); args = `--folder-uri "${workspace.toString()}"`; } else { - description = nls.localize('workspaceDesc', "{0} {1}", getBaseLabel(workspace.configPath), getPathLabel(dirname(workspace.configPath), this.environmentService)); + description = localize('workspaceDesc', "{0} {1}", getBaseLabel(workspace.configPath), getPathLabel(dirname(workspace.configPath), this.environmentService)); args = `--file-uri "${workspace.configPath.toString()}"`; } @@ -398,7 +399,7 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa // Workspace: Untitled if (extUriBiasedIgnorePathCase.isEqualOrParent(workspace.configPath, workspaceHome)) { - return nls.localize('untitledWorkspace', "Untitled (Workspace)"); + return localize('untitledWorkspace', "Untitled (Workspace)"); } let filename = basename(workspace.configPath); @@ -406,7 +407,7 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa filename = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); } - return nls.localize('workspaceName', "{0} (Workspace)", filename); + return localize('workspaceName', "{0} (Workspace)", filename); } } @@ -427,9 +428,9 @@ function indexOfWorkspace(arr: IRecent[], candidate: IWorkspaceIdentifier): numb } function indexOfFolder(arr: IRecent[], candidate: ISingleFolderWorkspaceIdentifier): number { - return arr.findIndex(folder => isRecentFolder(folder) && isEqual(folder.folderUri, candidate)); + return arr.findIndex(folder => isRecentFolder(folder) && extUriBiasedIgnorePathCase.isEqual(folder.folderUri, candidate)); } function indexOfFile(arr: IRecentFile[], candidate: URI): number { - return arr.findIndex(file => isEqual(file.fileUri, candidate)); + return arr.findIndex(file => extUriBiasedIgnorePathCase.isEqual(file.fileUri, candidate)); } From 66f5e9294e3af365bc62260839fe51806eb83ac5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 8 Dec 2020 10:44:22 +0100 Subject: [PATCH 170/200] path lib usage :lipstick: --- src/vs/platform/files/common/fileService.ts | 30 +++++++++---------- .../node/watcher/nsfw/nsfwWatcherService.ts | 24 +++++++-------- .../watcher/unix/chokidarWatcherService.ts | 9 +++--- .../electron-main/workspacesMainService.ts | 11 ++++--- .../terminalValidatedLocalLinkProvider.ts | 7 +++-- .../services/editor/browser/editorService.ts | 5 ++-- .../abstractWorkspaceEditingService.ts | 1 + 7 files changed, 44 insertions(+), 43 deletions(-) diff --git a/src/vs/platform/files/common/fileService.ts b/src/vs/platform/files/common/fileService.ts index 23001b2a20f..81ee5fe2580 100644 --- a/src/vs/platform/files/common/fileService.ts +++ b/src/vs/platform/files/common/fileService.ts @@ -725,16 +725,16 @@ export class FileService extends Disposable implements IFileService { // Check if source is equal or parent to target (requires providers to be the same) if (sourceProvider === targetProvider) { - const { extUri, isPathCaseSensitive } = this.getExtUri(sourceProvider); + const { providerExtUri, isPathCaseSensitive } = this.getExtUri(sourceProvider); if (!isPathCaseSensitive) { - isSameResourceWithDifferentPathCase = extUri.isEqual(source, target); + isSameResourceWithDifferentPathCase = providerExtUri.isEqual(source, target); } if (isSameResourceWithDifferentPathCase && mode === 'copy') { throw new Error(localize('unableToMoveCopyError1', "Unable to copy when source '{0}' is same as target '{1}' with different path case on a case insensitive file system", this.resourceForError(source), this.resourceForError(target))); } - if (!isSameResourceWithDifferentPathCase && extUri.isEqualOrParent(target, source)) { + if (!isSameResourceWithDifferentPathCase && providerExtUri.isEqualOrParent(target, source)) { throw new Error(localize('unableToMoveCopyError2', "Unable to move/copy when source '{0}' is parent of target '{1}'.", this.resourceForError(source), this.resourceForError(target))); } } @@ -751,8 +751,8 @@ export class FileService extends Disposable implements IFileService { // Special case: if the target is a parent of the source, we cannot delete // it as it would delete the source as well. In this case we have to throw if (sourceProvider === targetProvider) { - const { extUri } = this.getExtUri(sourceProvider); - if (extUri.isEqualOrParent(source, target)) { + const { providerExtUri } = this.getExtUri(sourceProvider); + if (providerExtUri.isEqualOrParent(source, target)) { throw new Error(localize('unableToMoveCopyError4', "Unable to move/copy '{0}' into '{1}' since a file would replace the folder it is contained in.", this.resourceForError(source), this.resourceForError(target))); } } @@ -761,11 +761,11 @@ export class FileService extends Disposable implements IFileService { return { exists, isSameResourceWithDifferentPathCase }; } - private getExtUri(provider: IFileSystemProvider): { extUri: IExtUri, isPathCaseSensitive: boolean } { + private getExtUri(provider: IFileSystemProvider): { providerExtUri: IExtUri, isPathCaseSensitive: boolean } { const isPathCaseSensitive = this.isPathCaseSensitive(provider); return { - extUri: isPathCaseSensitive ? extUri : extUriIgnorePathCase, + providerExtUri: isPathCaseSensitive ? extUri : extUriIgnorePathCase, isPathCaseSensitive }; } @@ -791,8 +791,8 @@ export class FileService extends Disposable implements IFileService { const directoriesToCreate: string[] = []; // mkdir until we reach root - const { extUri } = this.getExtUri(provider); - while (!extUri.isEqual(directory, dirname(directory))) { + const { providerExtUri } = this.getExtUri(provider); + while (!providerExtUri.isEqual(directory, dirname(directory))) { try { const stat = await provider.stat(directory); if ((stat.type & FileType.Directory) === 0) { @@ -940,12 +940,12 @@ export class FileService extends Disposable implements IFileService { } private toWatchKey(provider: IFileSystemProvider, resource: URI, options: IWatchOptions): string { - const { extUri } = this.getExtUri(provider); + const { providerExtUri } = this.getExtUri(provider); return [ - extUri.getComparisonKey(resource), // lowercase path if the provider is case insensitive - String(options.recursive), // use recursive: true | false as part of the key - options.excludes.join() // use excludes as part of the key + providerExtUri.getComparisonKey(resource), // lowercase path if the provider is case insensitive + String(options.recursive), // use recursive: true | false as part of the key + options.excludes.join() // use excludes as part of the key ].join(); } @@ -963,8 +963,8 @@ export class FileService extends Disposable implements IFileService { private readonly writeQueues: Map> = new Map(); private ensureWriteQueue(provider: IFileSystemProvider, resource: URI): Queue { - const { extUri } = this.getExtUri(provider); - const queueKey = extUri.getComparisonKey(resource); + const { providerExtUri } = this.getExtUri(provider); + const queueKey = providerExtUri.getComparisonKey(resource); // ensure to never write to the same resource without finishing // the one write. this ensures a write finishes consistently diff --git a/src/vs/platform/files/node/watcher/nsfw/nsfwWatcherService.ts b/src/vs/platform/files/node/watcher/nsfw/nsfwWatcherService.ts index 51a4b1a6510..70c4cfd6193 100644 --- a/src/vs/platform/files/node/watcher/nsfw/nsfwWatcherService.ts +++ b/src/vs/platform/files/node/watcher/nsfw/nsfwWatcherService.ts @@ -3,12 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as glob from 'vs/base/common/glob'; -import * as extpath from 'vs/base/common/extpath'; -import * as path from 'vs/base/common/path'; -import * as platform from 'vs/base/common/platform'; -import { IDiskFileChange, normalizeFileChanges, ILogMessage } from 'vs/platform/files/node/watcher/watcher'; import * as nsfw from 'vscode-nsfw'; +import * as glob from 'vs/base/common/glob'; +import { join } from 'vs/base/common/path'; +import { isMacintosh } from 'vs/base/common/platform'; +import { isEqualOrParent } from 'vs/base/common/extpath'; +import { IDiskFileChange, normalizeFileChanges, ILogMessage } from 'vs/platform/files/node/watcher/watcher'; import { IWatcherService, IWatcherRequest } from 'vs/platform/files/node/watcher/nsfw/watcher'; import { ThrottledDelayer } from 'vs/base/common/async'; import { FileChangeType } from 'vs/platform/files/common/files'; @@ -111,7 +111,7 @@ export class NsfwWatcherService extends Disposable implements IWatcherService { // We have to detect this case and massage the events to correct this. let realBasePathDiffers = false; let realBasePathLength = request.path.length; - if (platform.isMacintosh) { + if (isMacintosh) { try { // First check for symbolic link @@ -141,7 +141,7 @@ export class NsfwWatcherService extends Disposable implements IWatcherService { for (const e of events) { // Logging if (this.verboseLogging) { - const logPath = e.action === nsfw.actions.RENAMED ? path.join(e.directory, e.oldFile || '') + ' -> ' + e.newFile : path.join(e.directory, e.file || ''); + const logPath = e.action === nsfw.actions.RENAMED ? join(e.directory, e.oldFile || '') + ' -> ' + e.newFile : join(e.directory, e.file || ''); this.log(`${e.action === nsfw.actions.CREATED ? '[CREATED]' : e.action === nsfw.actions.DELETED ? '[DELETED]' : e.action === nsfw.actions.MODIFIED ? '[CHANGED]' : '[RENAMED]'} ${logPath}`); } @@ -149,20 +149,20 @@ export class NsfwWatcherService extends Disposable implements IWatcherService { let absolutePath: string; if (e.action === nsfw.actions.RENAMED) { // Rename fires when a file's name changes within a single directory - absolutePath = path.join(e.directory, e.oldFile || ''); + absolutePath = join(e.directory, e.oldFile || ''); if (!this.isPathIgnored(absolutePath, this.pathWatchers[request.path].ignored)) { undeliveredFileEvents.push({ type: FileChangeType.DELETED, path: absolutePath }); } else if (this.verboseLogging) { this.log(` >> ignored ${absolutePath}`); } - absolutePath = path.join(e.newDirectory || e.directory, e.newFile || ''); + absolutePath = join(e.newDirectory || e.directory, e.newFile || ''); if (!this.isPathIgnored(absolutePath, this.pathWatchers[request.path].ignored)) { undeliveredFileEvents.push({ type: FileChangeType.ADDED, path: absolutePath }); } else if (this.verboseLogging) { this.log(` >> ignored ${absolutePath}`); } } else { - absolutePath = path.join(e.directory, e.file || ''); + absolutePath = join(e.directory, e.file || ''); if (!this.isPathIgnored(absolutePath, this.pathWatchers[request.path].ignored)) { undeliveredFileEvents.push({ type: nsfwActionToRawChangeType[e.action], @@ -179,7 +179,7 @@ export class NsfwWatcherService extends Disposable implements IWatcherService { const events = undeliveredFileEvents; undeliveredFileEvents = []; - if (platform.isMacintosh) { + if (isMacintosh) { events.forEach(e => { // Mac uses NFD unicode form on disk, but we want NFC @@ -230,7 +230,7 @@ export class NsfwWatcherService extends Disposable implements IWatcherService { // Normalizes a set of root paths by removing any root paths that are // sub-paths of other roots. return roots.filter(r => roots.every(other => { - return !(r.path.length > other.path.length && extpath.isEqualOrParent(r.path, other.path)); + return !(r.path.length > other.path.length && isEqualOrParent(r.path, other.path)); })); } diff --git a/src/vs/platform/files/node/watcher/unix/chokidarWatcherService.ts b/src/vs/platform/files/node/watcher/unix/chokidarWatcherService.ts index 895e5dfa959..25276aa2ac4 100644 --- a/src/vs/platform/files/node/watcher/unix/chokidarWatcherService.ts +++ b/src/vs/platform/files/node/watcher/unix/chokidarWatcherService.ts @@ -6,9 +6,8 @@ import * as chokidar from 'chokidar'; import * as fs from 'fs'; import * as gracefulFs from 'graceful-fs'; -gracefulFs.gracefulify(fs); -import * as extpath from 'vs/base/common/extpath'; import * as glob from 'vs/base/common/glob'; +import { isEqualOrParent } from 'vs/base/common/extpath'; import { FileChangeType } from 'vs/platform/files/common/files'; import { ThrottledDelayer } from 'vs/base/common/async'; import { normalizeNFC } from 'vs/base/common/normalization'; @@ -20,6 +19,8 @@ import { Emitter, Event } from 'vs/base/common/event'; import { equals } from 'vs/base/common/arrays'; import { Disposable } from 'vs/base/common/lifecycle'; +gracefulFs.gracefulify(fs); // enable gracefulFs + process.noAsar = true; // disable ASAR support in watcher process interface IWatcher { @@ -311,7 +312,7 @@ function isIgnored(path: string, requests: ExtendedWatcherRequest[]): boolean { return false; } - if (extpath.isEqualOrParent(path, request.path)) { + if (isEqualOrParent(path, request.path)) { if (!request.parsedPattern) { if (request.excludes && request.excludes.length > 0) { const pattern = `{${request.excludes.join(',')}}`; @@ -343,7 +344,7 @@ export function normalizeRoots(requests: IWatcherRequest[]): { [basePath: string for (const request of requests) { const basePath = request.path; const ignored = (request.excludes || []).sort(); - if (prevRequest && (extpath.isEqualOrParent(basePath, prevRequest.path))) { + if (prevRequest && (isEqualOrParent(basePath, prevRequest.path))) { if (!isEqualIgnore(ignored, prevRequest.excludes)) { result[prevRequest.path].push({ path: basePath, excludes: ignored }); } diff --git a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts index d5ff4b46d4b..b097660f24a 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts @@ -12,7 +12,7 @@ import { isLinux } from 'vs/base/common/platform'; import { Event, Emitter } from 'vs/base/common/event'; import { ILogService } from 'vs/platform/log/common/log'; import { createHash } from 'crypto'; -import * as json from 'vs/base/common/json'; +import { parse } from 'vs/base/common/json'; import { toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; @@ -66,7 +66,7 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain declare readonly _serviceBrand: undefined; - private readonly untitledWorkspacesHome: URI; // local URI that contains all untitled workspaces + private readonly untitledWorkspacesHome = this.environmentService.untitledWorkspacesHome; // local URI that contains all untitled workspaces private readonly _onUntitledWorkspaceDeleted = this._register(new Emitter()); readonly onUntitledWorkspaceDeleted: Event = this._onUntitledWorkspaceDeleted.event; @@ -81,8 +81,6 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain @IDialogMainService private readonly dialogMainService: IDialogMainService ) { super(); - - this.untitledWorkspacesHome = environmentService.untitledWorkspacesHome; } resolveLocalWorkspaceSync(uri: URI): IResolvedWorkspace | null { @@ -127,7 +125,7 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain private doParseStoredWorkspace(path: URI, contents: string): IStoredWorkspace { // Parse workspace file - let storedWorkspace: IStoredWorkspace = json.parse(contents); // use fault tolerant parser + const storedWorkspace: IStoredWorkspace = parse(contents); // use fault tolerant parser // Filter out folders which do not have a path or uri set if (storedWorkspace && Array.isArray(storedWorkspace.folders)) { @@ -226,7 +224,7 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain } getUntitledWorkspacesSync(): IUntitledWorkspaceInfo[] { - let untitledWorkspaces: IUntitledWorkspaceInfo[] = []; + const untitledWorkspaces: IUntitledWorkspaceInfo[] = []; try { const untitledWorkspacePaths = readdirSync(this.untitledWorkspacesHome.fsPath).map(folder => joinPath(this.untitledWorkspacesHome, folder, UNTITLED_WORKSPACE_NAME)); for (const untitledWorkspacePath of untitledWorkspacePaths) { @@ -243,6 +241,7 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain this.logService.warn(`Unable to read folders in ${this.untitledWorkspacesHome} (${error}).`); } } + return untitledWorkspaces; } diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalValidatedLocalLinkProvider.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalValidatedLocalLinkProvider.ts index fb420ef52ae..c2910ec1192 100644 --- a/src/vs/workbench/contrib/terminal/browser/links/terminalValidatedLocalLinkProvider.ts +++ b/src/vs/workbench/contrib/terminal/browser/links/terminalValidatedLocalLinkProvider.ts @@ -9,7 +9,7 @@ import { OperatingSystem } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { TerminalLink, OPEN_FILE_LABEL, FOLDER_IN_WORKSPACE_LABEL, FOLDER_NOT_IN_WORKSPACE_LABEL } from 'vs/workbench/contrib/terminal/browser/links/terminalLink'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { isEqualOrParent } from 'vs/base/common/resources'; +import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IHostService } from 'vs/workbench/services/host/browser/host'; @@ -62,7 +62,8 @@ export class TerminalValidatedLocalLinkProvider extends TerminalBaseLinkProvider @IInstantiationService private readonly _instantiationService: IInstantiationService, @ICommandService private readonly _commandService: ICommandService, @IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService, - @IHostService private readonly _hostService: IHostService + @IHostService private readonly _hostService: IHostService, + @IUriIdentityService private readonly _uriIdentityService: IUriIdentityService ) { super(); } @@ -183,7 +184,7 @@ export class TerminalValidatedLocalLinkProvider extends TerminalBaseLinkProvider private _isDirectoryInsideWorkspace(uri: URI) { const folders = this._workspaceContextService.getWorkspace().folders; for (let i = 0; i < folders.length; i++) { - if (isEqualOrParent(uri, folders[i].uri)) { + if (this._uriIdentityService.extUri.isEqualOrParent(uri, folders[i].uri)) { return true; } } diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 458e5e41119..bd176bffd4c 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -11,7 +11,7 @@ import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorIn import { Registry } from 'vs/platform/registry/common/platform'; import { ResourceMap } from 'vs/base/common/map'; import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; -import { IFileService, FileOperationEvent, FileOperation, FileChangesEvent, FileChangeType, FileSystemProviderCapabilities } from 'vs/platform/files/common/files'; +import { IFileService, FileOperationEvent, FileOperation, FileChangesEvent, FileChangeType } from 'vs/platform/files/common/files'; import { Schemas } from 'vs/base/common/network'; import { Event, Emitter } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; @@ -251,8 +251,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { if (this.uriIdentityService.extUri.isEqual(source, resource)) { targetResource = target; // file got moved } else { - const ignoreCase = !this.fileService.hasCapability(resource, FileSystemProviderCapabilities.PathCaseSensitive); - const index = indexOfPath(resource.path, source.path, ignoreCase); + const index = indexOfPath(resource.path, source.path, this.uriIdentityService.extUri.ignorePathCasing(resource)); targetResource = joinPath(target, resource.path.substr(index + source.path.length + 1)); // parent folder got moved } diff --git a/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts b/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts index 8a6d94c1e5a..5bfe4a37b48 100644 --- a/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts +++ b/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts @@ -221,6 +221,7 @@ export abstract class AbstractWorkspaceEditingService implements IWorkspaceEditi } // Allow to save the workspace of the current window + // if we have an identical match on the path if (isEqual(workspaceIdentifier.configPath, path)) { return this.saveWorkspace(workspaceIdentifier); } From 208bfc9970c644b004fcfbe19eebd1867feddabe Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 8 Dec 2020 11:06:31 +0100 Subject: [PATCH 171/200] fixes #112046 --- src/vs/workbench/contrib/debug/browser/repl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 74467fa8078..93db72f1439 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -305,7 +305,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { if (this.styleElement) { const debugConsole = this.configurationService.getValue('debug').console; const fontSize = debugConsole.fontSize; - const fontFamily = debugConsole.fontFamily === 'default' ? 'var(--monaco-monospace-font)' : `'${debugConsole.fontFamily}'`; + const fontFamily = debugConsole.fontFamily === 'default' ? 'var(--monaco-monospace-font)' : `${debugConsole.fontFamily}`; const lineHeight = debugConsole.lineHeight ? `${debugConsole.lineHeight}px` : '1.4em'; const backgroundColor = this.themeService.getColorTheme().getColor(this.getBackgroundColor()); From 46ee31fce0f143910dc3ab89afb568ffcfd0a4ee Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 7 Dec 2020 16:27:07 +0100 Subject: [PATCH 172/200] Try to fix markdown tooltip for Safari #111756 --- src/vs/base/browser/ui/iconLabel/iconLabel.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/base/browser/ui/iconLabel/iconLabel.ts b/src/vs/base/browser/ui/iconLabel/iconLabel.ts index 44c56834ff0..50274475e84 100644 --- a/src/vs/base/browser/ui/iconLabel/iconLabel.ts +++ b/src/vs/base/browser/ui/iconLabel/iconLabel.ts @@ -191,6 +191,7 @@ export class IconLabel extends Disposable { } private setupCustomHover(hoverDelegate: IHoverDelegate, htmlElement: HTMLElement, markdownTooltip: string | IIconLabelMarkdownString): void { + htmlElement.setAttribute('title', ''); htmlElement.removeAttribute('title'); let tooltip: () => Promise; if (isString(markdownTooltip)) { From 9edc69706f804c74f22c3c031721404ef0e16fdb Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 8 Dec 2020 11:09:44 +0100 Subject: [PATCH 173/200] Just set textContent for custom hover Fixes #111643 --- .../services/hover/browser/hoverWidget.ts | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/services/hover/browser/hoverWidget.ts b/src/vs/workbench/services/hover/browser/hoverWidget.ts index f0009cb66aa..a7fba5f9a76 100644 --- a/src/vs/workbench/services/hover/browser/hoverWidget.ts +++ b/src/vs/workbench/services/hover/browser/hoverWidget.ts @@ -16,7 +16,6 @@ import { Widget } from 'vs/base/browser/ui/widget'; import { AnchorPosition } from 'vs/base/browser/ui/contextview/contextview'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; -import { MarkdownString, MarkdownStringTextNewlineStyle } from 'vs/base/common/htmlContent'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { MarkdownRenderer } from 'vs/editor/browser/core/markdownRenderer'; @@ -82,25 +81,28 @@ export class HoverWidget extends Widget { const rowElement = $('div.hover-row.markdown-hover'); const contentsElement = $('div.hover-contents'); - const markdown = typeof options.text === 'string' ? new MarkdownString().appendText(options.text, MarkdownStringTextNewlineStyle.Break) : options.text; + if (typeof options.text === 'string') { + contentsElement.textContent = options.text; + } else { + const markdown = options.text; + const mdRenderer = this._instantiationService.createInstance( + MarkdownRenderer, + { codeBlockFontFamily: this._configurationService.getValue('editor').fontFamily || EDITOR_FONT_DEFAULTS.fontFamily } + ); - const mdRenderer = this._instantiationService.createInstance( - MarkdownRenderer, - { codeBlockFontFamily: this._configurationService.getValue('editor').fontFamily || EDITOR_FONT_DEFAULTS.fontFamily } - ); - - const { element } = mdRenderer.render(markdown, { - actionHandler: { - callback: (content) => this._linkHandler(content), - disposeables: this._messageListeners - }, - asyncRenderCallback: () => { - contentsElement.classList.add('code-hover-contents'); - // This changes the dimensions of the hover so trigger a layout - this._onRequestLayout.fire(); - } - }); - contentsElement.appendChild(element); + const { element } = mdRenderer.render(markdown, { + actionHandler: { + callback: (content) => this._linkHandler(content), + disposeables: this._messageListeners + }, + asyncRenderCallback: () => { + contentsElement.classList.add('code-hover-contents'); + // This changes the dimensions of the hover so trigger a layout + this._onRequestLayout.fire(); + } + }); + contentsElement.appendChild(element); + } rowElement.appendChild(contentsElement); this._hover.contentsDomNode.appendChild(rowElement); From 92d6f00d6e2f01efedd26b657c7218baf8c9d5e9 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 8 Dec 2020 15:38:48 +0100 Subject: [PATCH 174/200] debug console: color the debug group elements fixes #112050 --- src/vs/workbench/contrib/debug/browser/repl.ts | 2 +- .../contrib/debug/browser/replViewer.ts | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 93db72f1439..58e44a25ad6 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -559,7 +559,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { this.instantiationService.createInstance(ReplVariablesRenderer, linkDetector), this.instantiationService.createInstance(ReplSimpleElementsRenderer, linkDetector), new ReplEvaluationInputsRenderer(), - new ReplGroupRenderer(), + this.instantiationService.createInstance(ReplGroupRenderer, linkDetector), new ReplEvaluationResultsRenderer(linkDetector), new ReplRawObjectsRenderer(linkDetector), ], diff --git a/src/vs/workbench/contrib/debug/browser/replViewer.ts b/src/vs/workbench/contrib/debug/browser/replViewer.ts index 0d432417fcf..01614150f9e 100644 --- a/src/vs/workbench/contrib/debug/browser/replViewer.ts +++ b/src/vs/workbench/contrib/debug/browser/replViewer.ts @@ -34,7 +34,7 @@ interface IReplEvaluationInputTemplateData { } interface IReplGroupTemplateData { - label: HighlightedLabel; + label: HTMLElement; } interface IReplEvaluationResultTemplateData { @@ -87,22 +87,28 @@ export class ReplEvaluationInputsRenderer implements ITreeRenderer { static readonly ID = 'replGroup'; + constructor( + private readonly linkDetector: LinkDetector, + @IThemeService private readonly themeService: IThemeService + ) { } + get templateId(): string { return ReplGroupRenderer.ID; } - renderTemplate(container: HTMLElement): IReplEvaluationInputTemplateData { - const input = dom.append(container, $('.expression')); - const label = new HighlightedLabel(input, false); + renderTemplate(container: HTMLElement): IReplGroupTemplateData { + const label = dom.append(container, $('.expression')); return { label }; } renderElement(element: ITreeNode, _index: number, templateData: IReplGroupTemplateData): void { const replGroup = element.element; - templateData.label.set(replGroup.name, createMatches(element.filterData)); + dom.clearNode(templateData.label); + const result = handleANSIOutput(replGroup.name, this.linkDetector, this.themeService, undefined); + templateData.label.appendChild(result); } - disposeTemplate(_templateData: IReplEvaluationInputTemplateData): void { + disposeTemplate(_templateData: IReplGroupTemplateData): void { // noop } } From c8b592a57a31a5bd53d1e9fdf1847a850d61757e Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 8 Dec 2020 16:08:06 +0100 Subject: [PATCH 175/200] debug editor decorations: always decorate top stack frame, and decorate focused stack frame if it is not the top stack frame fyi @hediet --- .../browser/callStackEditorContribution.ts | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/callStackEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/callStackEditorContribution.ts index 9fd5d78b003..fa7901ea386 100644 --- a/src/vs/workbench/contrib/debug/browser/callStackEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/callStackEditorContribution.ts @@ -127,17 +127,21 @@ export class CallStackEditorContribution implements IEditorContribution { const isSessionFocused = s === focusedStackFrame?.thread.session; s.getAllThreads().forEach(t => { if (t.stopped) { - let candidateStackFrame = t === focusedStackFrame?.thread ? focusedStackFrame : undefined; - if (!candidateStackFrame) { - const callStack = t.getCallStack(); - if (callStack.length) { - candidateStackFrame = callStack[0]; + const callStack = t.getCallStack(); + const stackFrames: IStackFrame[] = []; + if (callStack.length > 0) { + // Always decorate top stack frame, and decorate focused stack frame if it is not the top stack frame + if (focusedStackFrame && !focusedStackFrame.equals(callStack[0])) { + stackFrames.push(focusedStackFrame); } + stackFrames.push(callStack[0]); } - if (candidateStackFrame && this.uriIdentityService.extUri.isEqual(candidateStackFrame.source.uri, this.editor.getModel()?.uri)) { - decorations.push(...createDecorationsForStackFrame(candidateStackFrame, this.topStackFrameRange, isSessionFocused)); - } + stackFrames.forEach(candidateStackFrame => { + if (candidateStackFrame && this.uriIdentityService.extUri.isEqual(candidateStackFrame.source.uri, this.editor.getModel()?.uri)) { + decorations.push(...createDecorationsForStackFrame(candidateStackFrame, this.topStackFrameRange, isSessionFocused)); + } + }); } }); }); From 768bcf454221232b6d1f342fd801d67266926db9 Mon Sep 17 00:00:00 2001 From: Andre-Fonteles Date: Tue, 8 Dec 2020 10:16:49 -0500 Subject: [PATCH 176/200] Fixed tab switching too fast when wheeling/scrolling (#112034) * Fixed tab switching too fast when wheeling/scrolling * Feedback/Suggested changes adoption * some :lipstick: before merge Co-authored-by: Andre Fonteles Co-authored-by: Benjamin Pasero --- .../browser/parts/editor/tabsTitleControl.ts | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index bcd835f4cc5..44e788c7886 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -73,6 +73,9 @@ export class TabsTitleControl extends TitleControl { private static readonly TAB_HEIGHT = 35; + private static readonly MOUSE_WHEEL_EVENT_THRESHOLD = 150; + private static readonly MOUSE_WHEEL_DISTANCE_THRESHOLD = 1.5; + private titleContainer: HTMLElement | undefined; private tabsAndActionsContainer: HTMLElement | undefined; private tabsContainer: HTMLElement | undefined; @@ -93,6 +96,8 @@ export class TabsTitleControl extends TitleControl { private path: IPath = isWindows ? win32 : posix; + private lastMouseWheelEventTime = 0; + constructor( parent: HTMLElement, accessor: IEditorGroupsAccessor, @@ -337,8 +342,27 @@ export class TabsTitleControl extends TitleControl { } } - // Figure out scrolling direction - const nextEditor = this.group.getEditorByIndex(this.group.getIndexOfEditor(activeEditor) + (e.deltaX < 0 || e.deltaY < 0 /* scrolling up */ ? -1 : 1)); + // Ignore event if the last one happened too recently (https://github.com/microsoft/vscode/issues/96409) + // The restriction is relaxed according to the absolute value of `deltaX` and `deltaY` + // to support discrete (mouse wheel) and contiguous scrolling (touchpad) equally well + const now = Date.now(); + if (now - this.lastMouseWheelEventTime < TabsTitleControl.MOUSE_WHEEL_EVENT_THRESHOLD - 2 * (Math.abs(e.deltaX) + Math.abs(e.deltaY))) { + return; + } + + this.lastMouseWheelEventTime = now; + + // Figure out scrolling direction but ignore it if too subtle + let tabSwitchDirection: number; + if (e.deltaX + e.deltaY < - TabsTitleControl.MOUSE_WHEEL_DISTANCE_THRESHOLD) { + tabSwitchDirection = -1; + } else if (e.deltaX + e.deltaY > TabsTitleControl.MOUSE_WHEEL_DISTANCE_THRESHOLD) { + tabSwitchDirection = 1; + } else { + return; + } + + const nextEditor = this.group.getEditorByIndex(this.group.getIndexOfEditor(activeEditor) + tabSwitchDirection); if (!nextEditor) { return; } From 5e5ae15b22c6617f22923edce6e359897cac0f83 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 8 Dec 2020 16:17:36 +0100 Subject: [PATCH 177/200] debug: show the hover not so eagarly (do it twice as slow as editor hover) --- .../workbench/contrib/debug/browser/debugEditorContribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts index dbd53aa5bba..f37f9dd71d0 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts @@ -339,7 +339,7 @@ export class DebugEditorContribution implements IDebugEditorContribution { if (this.hoverRange) { this.showHover(this.hoverRange, false); } - }, hoverOption.delay); + }, hoverOption.delay * 2); this.toDispose.push(scheduler); return scheduler; From b3a3dc9c0a5d7840a11fe17859e61b780fa5cb84 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 8 Dec 2020 17:03:21 +0100 Subject: [PATCH 178/200] Debt: Test findPorts (#112092) Add a test for the port finding logic --- .../api/node/extHostTunnelService.ts | 173 ++++++------ .../node/api/extHostTunnelService.test.ts | 266 ++++++++++++++++++ 2 files changed, 353 insertions(+), 86 deletions(-) create mode 100644 src/vs/workbench/test/node/api/extHostTunnelService.test.ts diff --git a/src/vs/workbench/api/node/extHostTunnelService.ts b/src/vs/workbench/api/node/extHostTunnelService.ts index 922451d1079..ae477f9eaad 100644 --- a/src/vs/workbench/api/node/extHostTunnelService.ts +++ b/src/vs/workbench/api/node/extHostTunnelService.ts @@ -34,6 +34,92 @@ class ExtensionTunnel implements vscode.Tunnel { } } +export function getSockets(stdout: string): { pid: number, socket: number }[] { + const lines = stdout.trim().split('\n'); + const mapped: { pid: number, socket: number }[] = []; + lines.forEach(line => { + const match = /\/proc\/(\d+)\/fd\/\d+ -> socket:\[(\d+)\]/.exec(line)!; + if (match && match.length >= 3) { + mapped.push({ + pid: parseInt(match[1], 10), + socket: parseInt(match[2], 10) + }); + } + }); + return mapped; +} + +export function loadListeningPorts(...stdouts: string[]): { socket: number, ip: string, port: number }[] { + const table = ([] as Record[]).concat(...stdouts.map(loadConnectionTable)); + return [ + ...new Map( + table.filter(row => row.st === '0A') + .map(row => { + const address = row.local_address.split(':'); + return { + socket: parseInt(row.inode, 10), + ip: parseIpAddress(address[0]), + port: parseInt(address[1], 16) + }; + }).map(port => [port.ip + ':' + port.port, port]) + ).values() + ]; +} + +export function parseIpAddress(hex: string): string { + let result = ''; + if (hex.length === 8) { + for (let i = hex.length - 2; i >= 0; i -= 2) { + result += parseInt(hex.substr(i, 2), 16); + if (i !== 0) { + result += '.'; + } + } + } else { + for (let i = hex.length - 4; i >= 0; i -= 4) { + result += parseInt(hex.substr(i, 4), 16).toString(16); + if (i !== 0) { + result += ':'; + } + } + } + return result; +} + +export function loadConnectionTable(stdout: string): Record[] { + const lines = stdout.trim().split('\n'); + const names = lines.shift()!.trim().split(/\s+/) + .filter(name => name !== 'rx_queue' && name !== 'tm->when'); + const table = lines.map(line => line.trim().split(/\s+/).reduce((obj, value, i) => { + obj[names[i] || i] = value; + return obj; + }, {} as Record)); + return table; +} + +export async function findPorts(tcp: string, tcp6: string, procSockets: string, processes: { pid: number, cwd: string, cmd: string }[]) { + const connections: { socket: number, ip: string, port: number }[] = loadListeningPorts(tcp, tcp6); + const sockets = getSockets(procSockets); + + const socketMap = sockets.reduce((m, socket) => { + m[socket.socket] = socket; + return m; + }, {} as Record); + const processMap = processes.reduce((m, process) => { + m[process.pid] = process; + return m; + }, {} as Record); + + const ports: { host: string, port: number, detail: string }[] = []; + connections.filter((connection => socketMap[connection.socket])).forEach(({ socket, ip, port }) => { + const command = processMap[socketMap[socket].pid].cmd; + if (!command.match(/.*\.vscode-server-[a-zA-Z]+\/bin.*/) && (command.indexOf('out/vs/server/main.js') === -1)) { + ports.push({ host: ip, port, detail: processMap[socketMap[socket].pid].cmd }); + } + }); + return ports; +} + export class ExtHostTunnelService extends Disposable implements IExtHostTunnelService { readonly _serviceBrand: undefined; private readonly _proxy: MainThreadTunnelServiceShape; @@ -137,9 +223,7 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe return undefined; } - async findCandidatePorts(): Promise<{ host: string, port: number, detail: string }[]> { - const ports: { host: string, port: number, detail: string }[] = []; let tcp: string = ''; let tcp6: string = ''; try { @@ -170,89 +254,6 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe // } } - - const connections: { socket: number, ip: string, port: number }[] = this.loadListeningPorts(tcp, tcp6); - const sockets = this.getSockets(procSockets); - - const socketMap = sockets.reduce((m, socket) => { - m[socket.socket] = socket; - return m; - }, {} as Record); - const processMap = processes.reduce((m, process) => { - m[process.pid] = process; - return m; - }, {} as Record); - - connections.filter((connection => socketMap[connection.socket])).forEach(({ socket, ip, port }) => { - const command = processMap[socketMap[socket].pid].cmd; - if (!command.match(/.*\.vscode-server-[a-zA-Z]+\/bin.*/) && (command.indexOf('out/vs/server/main.js') === -1)) { - ports.push({ host: ip, port, detail: processMap[socketMap[socket].pid].cmd }); - } - }); - - return ports; - } - - private getSockets(stdout: string): { pid: number, socket: number }[] { - const lines = stdout.trim().split('\n'); - const mapped: { pid: number, socket: number }[] = []; - lines.forEach(line => { - const match = /\/proc\/(\d+)\/fd\/\d+ -> socket:\[(\d+)\]/.exec(line)!; - if (match && match.length >= 3) { - mapped.push({ - pid: parseInt(match[1], 10), - socket: parseInt(match[2], 10) - }); - } - }); - return mapped; - } - - private loadListeningPorts(...stdouts: string[]): { socket: number, ip: string, port: number }[] { - const table = ([] as Record[]).concat(...stdouts.map(this.loadConnectionTable)); - return [ - ...new Map( - table.filter(row => row.st === '0A') - .map(row => { - const address = row.local_address.split(':'); - return { - socket: parseInt(row.inode, 10), - ip: this.parseIpAddress(address[0]), - port: parseInt(address[1], 16) - }; - }).map(port => [port.ip + ':' + port.port, port]) - ).values() - ]; - } - - private parseIpAddress(hex: string): string { - let result = ''; - if (hex.length === 8) { - for (let i = hex.length - 2; i >= 0; i -= 2) { - result += parseInt(hex.substr(i, 2), 16); - if (i !== 0) { - result += '.'; - } - } - } else { - for (let i = hex.length - 4; i >= 0; i -= 4) { - result += parseInt(hex.substr(i, 4), 16).toString(16); - if (i !== 0) { - result += ':'; - } - } - } - return result; - } - - private loadConnectionTable(stdout: string): Record[] { - const lines = stdout.trim().split('\n'); - const names = lines.shift()!.trim().split(/\s+/) - .filter(name => name !== 'rx_queue' && name !== 'tm->when'); - const table = lines.map(line => line.trim().split(/\s+/).reduce((obj, value, i) => { - obj[names[i] || i] = value; - return obj; - }, {} as Record)); - return table; + return findPorts(tcp, tcp6, procSockets, processes); } } diff --git a/src/vs/workbench/test/node/api/extHostTunnelService.test.ts b/src/vs/workbench/test/node/api/extHostTunnelService.test.ts new file mode 100644 index 00000000000..d10b52100e0 --- /dev/null +++ b/src/vs/workbench/test/node/api/extHostTunnelService.test.ts @@ -0,0 +1,266 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import * as platform from 'vs/base/common/platform'; +import { findPorts, getSockets, loadConnectionTable, loadListeningPorts } from 'vs/workbench/api/node/extHostTunnelService'; + +const tcp = + ` sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode + 0: 00000000:0BBA 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 2335214 1 0000000010173312 100 0 0 10 0 + 1: 00000000:1AF3 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 2334514 1 000000008815920b 100 0 0 10 0 + 2: 0100007F:A9EA 0100007F:1AF3 01 00000000:00000000 00:00000000 00000000 1000 0 2334521 1 00000000a37d44c6 21 4 0 10 -1 + 3: 0100007F:E8B4 0100007F:98EF 01 00000000:00000000 00:00000000 00000000 1000 0 2334532 1 0000000031b88f06 21 4 0 10 -1 + 4: 0100007F:866C 0100007F:8783 01 00000000:00000000 00:00000000 00000000 1000 0 2334510 1 00000000cbf670bb 21 4 30 10 -1 + 5: 0100007F:1AF3 0100007F:A9EA 01 00000000:00000000 00:00000000 00000000 1000 0 2338989 1 0000000000bace62 21 4 1 10 -1 +`; +const tcp6 = + ` sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode + 0: 00000000000000000000000000000000:815B 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 2321070 1 00000000c44f3f02 100 0 0 10 0 + 1: 00000000000000000000000000000000:8783 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 2334509 1 000000003915e812 100 0 0 10 0 + 2: 00000000000000000000000000000000:9907 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 2284465 1 00000000f13b9374 100 0 0 10 0 + 3: 00000000000000000000000000000000:98EF 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 2334531 1 00000000184cae9c 100 0 0 10 0 + 4: 00000000000000000000000000000000:8BCF 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 2329890 1 00000000c05a3466 100 0 0 10 0 + 5: 0000000000000000FFFF00000100007F:8783 0000000000000000FFFF00000100007F:866C 01 00000000:00000000 00:00000000 00000000 1000 0 2334511 1 00000000bf547132 21 4 1 10 -1 + 6: 0000000000000000FFFF00000100007F:98EF 0000000000000000FFFF00000100007F:E8B4 01 00000000:00000000 00:00000000 00000000 1000 0 2334533 1 0000000039d0bcd2 21 4 1 10 -1 + 7: 0000000000000000FFFF0000DFD317AC:9907 0000000000000000FFFF000001D017AC:C123 01 0000005A:00000000 01:00000017 00000000 1000 0 2311039 3 0000000067b6c8db 23 5 25 10 52 + 8: 0000000000000000FFFF0000DFD317AC:9907 0000000000000000FFFF000001D017AC:C124 01 00000000:00000000 00:00000000 00000000 1000 0 2311040 1 00000000230bb017 25 4 30 10 28 + 9: 0000000000000000FFFF0000DFD317AC:9907 0000000000000000FFFF000001D017AC:C213 01 00000000:00000000 00:00000000 00000000 1000 0 2331501 1 00000000957fcb4a 26 4 30 10 57 + 10: 0000000000000000FFFF0000DFD317AC:9907 0000000000000000FFFF000001D017AC:C214 01 00000000:00000000 00:00000000 00000000 1000 0 2331500 1 00000000d7f87ceb 25 4 28 10 -1 +`; + +const procSockets = + `ls: cannot access '/proc/8289/fd/255': No such file or directory + ls: cannot access '/proc/8289/fd/3': No such file or directory + lrwx------ 1 alex alex 64 Dec 8 14:59 /proc/230/fd/3 -> socket:[21862] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/0 -> socket:[2311043] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/1 -> socket:[2311045] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/19 -> socket:[2311040] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/2 -> socket:[2311047] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/20 -> socket:[2314928] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/22 -> socket:[2307042] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/24 -> socket:[2307051] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/25 -> socket:[2307044] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/27 -> socket:[2307046] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/29 -> socket:[2307053] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/3 -> socket:[2311049] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/30 -> socket:[2307048] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/32 -> socket:[2307055] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/33 -> socket:[2307067] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/34 -> socket:[2307057] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/35 -> socket:[2321483] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/37 -> socket:[2321070] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/41 -> socket:[2321485] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/42 -> socket:[2321074] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/43 -> socket:[2321487] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/44 -> socket:[2329890] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/45 -> socket:[2321489] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2504/fd/46 -> socket:[2334509] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/2504/fd/47 -> socket:[2334510] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/2504/fd/48 -> socket:[2329894] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/2504/fd/49 -> socket:[2334511] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/2504/fd/50 -> socket:[2334515] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/2504/fd/51 -> socket:[2334519] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/2504/fd/52 -> socket:[2334518] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/2504/fd/53 -> socket:[2334521] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/2504/fd/54 -> socket:[2334531] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/2504/fd/55 -> socket:[2334532] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/2504/fd/56 -> socket:[2334533] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2515/fd/3 -> socket:[2311053] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2719/fd/0 -> socket:[2307043] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2719/fd/1 -> socket:[2307045] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2719/fd/2 -> socket:[2307047] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2719/fd/3 -> socket:[2307049] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2725/fd/0 -> socket:[2307052] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2725/fd/1 -> socket:[2307054] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2725/fd/2 -> socket:[2307056] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2725/fd/20 -> socket:[2290617] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2725/fd/3 -> socket:[2307058] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2739/fd/0 -> socket:[2307052] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2739/fd/1 -> socket:[2307054] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2739/fd/2 -> socket:[2307056] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2739/fd/3 -> socket:[2290618] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2795/fd/0 -> socket:[2321484] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2795/fd/1 -> socket:[2321486] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2795/fd/2 -> socket:[2321488] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/2795/fd/3 -> socket:[2321490] + lrwx------ 1 alex alex 64 Dec 8 14:59 /proc/314/fd/18 -> socket:[2284465] + lrwx------ 1 alex alex 64 Dec 8 14:59 /proc/314/fd/19 -> socket:[2311039] + lrwx------ 1 alex alex 64 Dec 8 14:59 /proc/314/fd/23 -> socket:[2331501] + lrwx------ 1 alex alex 64 Dec 8 14:59 /proc/314/fd/24 -> socket:[2311052] + lrwx------ 1 alex alex 64 Dec 8 14:59 /proc/314/fd/25 -> socket:[2311042] + lrwx------ 1 alex alex 64 Dec 8 14:59 /proc/314/fd/26 -> socket:[2331504] + lrwx------ 1 alex alex 64 Dec 8 14:59 /proc/314/fd/27 -> socket:[2311051] + lrwx------ 1 alex alex 64 Dec 8 14:59 /proc/314/fd/29 -> socket:[2311044] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/314/fd/30 -> socket:[2321909] + lrwx------ 1 alex alex 64 Dec 8 14:59 /proc/314/fd/31 -> socket:[2311046] + lrwx------ 1 alex alex 64 Dec 8 15:14 /proc/314/fd/33 -> socket:[2311048] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/314/fd/35 -> socket:[2329692] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/314/fd/37 -> socket:[2331506] + lrwx------ 1 alex alex 64 Dec 8 15:20 /proc/314/fd/40 -> socket:[2331508] + lrwx------ 1 alex alex 64 Dec 8 15:20 /proc/314/fd/42 -> socket:[2331510] + lrwx------ 1 alex alex 64 Dec 8 15:17 /proc/314/fd/68 -> socket:[2322083] + lrwx------ 1 alex alex 64 Dec 8 15:22 /proc/4412/fd/20 -> socket:[2335214] + lrwx------ 1 alex alex 64 Dec 8 15:22 /proc/4496/fd/0 -> socket:[2331505] + lrwx------ 1 alex alex 64 Dec 8 15:22 /proc/4496/fd/1 -> socket:[2331507] + lrwx------ 1 alex alex 64 Dec 8 15:22 /proc/4496/fd/2 -> socket:[2331509] + lrwx------ 1 alex alex 64 Dec 8 15:22 /proc/4496/fd/23 -> socket:[2334514] + lrwx------ 1 alex alex 64 Dec 8 15:22 /proc/4496/fd/24 -> socket:[2338989] + lrwx------ 1 alex alex 64 Dec 8 15:22 /proc/4496/fd/26 -> socket:[2338276] + lrwx------ 1 alex alex 64 Dec 8 15:22 /proc/4496/fd/27 -> socket:[2331500] + lrwx------ 1 alex alex 64 Dec 8 15:22 /proc/4496/fd/3 -> socket:[2331511] + lrwx------ 1 alex alex 64 Dec 8 15:22 /proc/4496/fd/31 -> socket:[2338285]`; + +const processes: { pid: number, cwd: string, cmd: string }[] = [ + { + pid: 230, + cwd: '/mnt/c/WINDOWS/system32', + cmd: 'dockerserve--addressunix:///home/alex/.docker/run/docker-cli-api.sock', + }, + { + pid: 2504, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: '/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/node/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/out/bootstrap-fork--type=extensionHost--uriTransformerPath=/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/out/vs/server/uriTransformer.js--useHostProxy=', + }, + { + pid: 2515, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: '/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/node/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/out/bootstrap-fork--type=watcherService' + }, + { + pid: 2526, + cwd: '/home/alex/repos/Microsoft/vscode-extension-samples/helloworld-sample', + cmd: '/bin/bash' + }, { + pid: 2719, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: '/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/node--max-old-space-size=3072/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/extensions/node_modules/typescript/lib/tsserver.js--serverModepartialSemantic--useInferredProjectPerProjectRoot--disableAutomaticTypingAcquisition--cancellationPipeName/tmp/vscode-typescript1000/7cfa7171c0c00aacf1ee/tscancellation-602cd80b954818b6a2f7.tmp*--logVerbosityverbose--logFile/home/alex/.vscode-server-insiders/data/logs/20201208T145954/exthost2/vscode.typescript-language-features/tsserver-log-nxBt2m/tsserver.log--globalPluginstypescript-vscode-sh-plugin--pluginProbeLocations/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/extensions/typescript-language-features--localeen--noGetErrOnBackgroundUpdate--validateDefaultNpmLocation' + }, + { + pid: 2725, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: '/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/node--max-old-space-size=3072/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/extensions/node_modules/typescript/lib/tsserver.js--useInferredProjectPerProjectRoot--enableTelemetry--cancellationPipeName/tmp/vscode-typescript1000/7cfa7171c0c00aacf1ee/tscancellation-04a0b92f880c2fd535ae.tmp*--logVerbosityverbose--logFile/home/alex/.vscode-server-insiders/data/logs/20201208T145954/exthost2/vscode.typescript-language-features/tsserver-log-fqyBrs/tsserver.log--globalPluginstypescript-vscode-sh-plugin--pluginProbeLocations/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/extensions/typescript-language-features--localeen--noGetErrOnBackgroundUpdate--validateDefaultNpmLocation' + }, + { + pid: 2739, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: '/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/node/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/extensions/node_modules/typescript/lib/typingsInstaller.js--globalTypingsCacheLocation/home/alex/.cache/typescript/4.1--enableTelemetry--logFile/home/alex/.vscode-server-insiders/data/logs/20201208T145954/exthost2/vscode.typescript-language-features/tsserver-log-fqyBrs/ti-2725.log--typesMapLocation/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/extensions/node_modules/typescript/lib/typesMap.json--validateDefaultNpmLocation' + }, + { + pid: 2795, + cwd: '/home/alex/repos/Microsoft/vscode-extension-samples/helloworld-sample', + cmd: '/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/node/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/extensions/json-language-features/server/dist/node/jsonServerMain--node-ipc--clientProcessId=2504' + }, + { + pid: 286, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: 'sh-c\"$VSCODE_WSL_EXT_LOCATION/ scripts / wslServer.sh\" bc13785d3dd99b4b0e9da9aed17bb79809a50804 insider .vscode-server-insiders 0 ' + }, + { + pid: 287, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: 'sh/mnt/c/Users/alros/.vscode-insiders/extensions/ms-vscode-remote.remote-wsl-0.52.0/scripts/wslServer.shbc13785d3dd99b4b0e9da9aed17bb79809a50804insider.vscode-server-insiders0' + }, + { + pid: 3058, + cwd: '/home/alex/repos/Microsoft/vscode-extension-samples/helloworld-sample', + cmd: 'npm' + }, + { + pid: 3070, + cwd: '/home/alex/repos/Microsoft/vscode-extension-samples/helloworld-sample', + cmd: 'sh-ctsc -watch -p ./' + }, + { + pid: 3071, + cwd: '/home/alex/repos/Microsoft/vscode-extension-samples/helloworld-sample', + cmd: 'node/home/alex/repos/Microsoft/vscode-extension-samples/helloworld-sample/node_modules/.bin/tsc-watch-p./' + }, + { + pid: 312, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: 'sh/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/server.sh--port=0--use-host-proxy--enable-remote-auto-shutdown--print-ip-address' + }, + { + pid: 314, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: '/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/node/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/out/vs/server/main.js--port=0--use-host-proxy--enable-remote-auto-shutdown--print-ip-address' + }, + { + pid: 3172, + cwd: '/home/alex', + cmd: '/bin/bash' + }, + { + pid: 3610, + cwd: '/home/alex/repos/Microsoft/vscode-extension-samples/helloworld-sample', + cmd: '/bin/bash' + }, + { + pid: 4412, + cwd: '/home/alex/repos/Microsoft/vscode-extension-samples/helloworld-sample', + cmd: 'http-server' + }, + { + pid: 4496, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: '/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/node--inspect-brk=0.0.0.0:6899/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/out/bootstrap-fork--type=extensionHost--uriTransformerPath=/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/out/vs/server/uriTransformer.js--useHostProxy=' + }, + { + pid: 4507, + cwd: '/mnt/c/Users/alros/AppData/Local/Programs/Microsoft VS Code Insiders', + cmd: '/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/node/home/alex/.vscode-server-insiders/bin/bc13785d3dd99b4b0e9da9aed17bb79809a50804/extensions/ms-vscode.js-debug/src/hash.bundle.js' + } +]; + +if (platform.isLinux) { + suite('ExtHostTunnelService', () => { + test('getSockets', function () { + const result = getSockets(procSockets); + assert.equal(result.length, 78); + // 4412 is the pid fo the http-server in the test data + assert.notEqual(result.find(value => value.pid === 4412), undefined); + }); + + test('loadConnectionTable', function () { + const result = loadConnectionTable(tcp); + assert.equal(result.length, 6); + assert.deepEqual(result[0], { + 10: '1', + 11: '0000000010173312', + 12: '100', + 13: '0', + 14: '0', + 15: '10', + 16: '0', + inode: '2335214', + local_address: '00000000:0BBA', + rem_address: '00000000:0000', + retrnsmt: '00000000', + sl: '0:', + st: '0A', + timeout: '0', + tr: '00:00000000', + tx_queue: '00000000:00000000', + uid: '1000' + }); + }); + + test('loadListeningPorts', function () { + const result = loadListeningPorts(tcp, tcp6); + // There should be 7 based on the input data. One of them should be 3002. + assert.equal(result.length, 7); + assert.notEqual(result.find(value => value.port === 3002), undefined); + }); + + test('findPorts', async function () { + const result = await findPorts(tcp, tcp6, procSockets, processes); + assert.equal(result.length, 1); + assert.equal(result[0].host, '0.0.0.0'); + assert.equal(result[0].port, 3002); + assert.equal(result[0].detail, 'http-server'); + }); + }); +} From affd21e65ac41360704b573a4ca3b90107fd9ee8 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 8 Dec 2020 17:20:17 +0100 Subject: [PATCH 179/200] tabs - partially take changes from PR 106448 to reduce diff --- src/vs/base/browser/dom.ts | 2 + src/vs/workbench/browser/part.ts | 2 +- .../browser/parts/editor/editorGroupView.ts | 14 ++--- .../parts/editor/noTabsTitleControl.ts | 6 ++- .../browser/parts/editor/tabsTitleControl.ts | 54 ++++++++++--------- .../browser/parts/editor/titleControl.ts | 16 +++++- 6 files changed, 60 insertions(+), 34 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index b4740dadea0..283b8c82130 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -451,6 +451,8 @@ export interface IDimension { export class Dimension implements IDimension { + static readonly None = new Dimension(0, 0); + constructor( public readonly width: number, public readonly height: number, diff --git a/src/vs/workbench/browser/part.ts b/src/vs/workbench/browser/part.ts index dfab3bc5cfc..8e78cbccc27 100644 --- a/src/vs/workbench/browser/part.ts +++ b/src/vs/workbench/browser/part.ts @@ -162,7 +162,7 @@ class PartLayout { if (this.options && this.options.hasTitle) { titleSize = new Dimension(width, Math.min(height, PartLayout.TITLE_HEIGHT)); } else { - titleSize = new Dimension(0, 0); + titleSize = Dimension.None; } let contentWidth = width; diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index a212456dd4f..ed48c489007 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -1704,13 +1704,15 @@ export class EditorGroupView extends Themable implements IEditorGroupView { layout(width: number, height: number): void { this.dimension = new Dimension(width, height); - // Ensure editor container gets height as CSS depending on the preferred height of the title control - const titleHeight = this.titleDimensions.height; - const editorHeight = Math.max(0, height - titleHeight); - this.editorContainer.style.height = `${editorHeight}px`; + // Layout the title area first to receive the size it occupies + const titleAreaSize = this.titleAreaControl.layout({ + container: this.dimension, + available: new Dimension(width, height - this.editorControl.minimumHeight) + }); - // Forward to controls - this.titleAreaControl.layout(new Dimension(width, titleHeight)); + // Pass the container width and remaining height to the editor layout + const editorHeight = Math.max(0, height - titleAreaSize.height); + this.editorContainer.style.height = `${editorHeight}px`; this.editorControl.layout(new Dimension(width, editorHeight)); } diff --git a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts index 66a7caec173..35f36592e4a 100644 --- a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts @@ -5,7 +5,7 @@ import 'vs/css!./media/notabstitlecontrol'; import { EditorResourceAccessor, Verbosity, IEditorInput, IEditorPartOptions, SideBySideEditor } from 'vs/workbench/common/editor'; -import { TitleControl, IToolbarActions } from 'vs/workbench/browser/parts/editor/titleControl'; +import { TitleControl, IToolbarActions, ITitleControlDimensions } from 'vs/workbench/browser/parts/editor/titleControl'; import { ResourceLabel, IResourceLabel } from 'vs/workbench/browser/labels'; import { TAB_ACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND } from 'vs/workbench/common/theme'; import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch'; @@ -333,9 +333,11 @@ export class NoTabsTitleControl extends TitleControl { }; } - layout(dimension: Dimension): void { + layout(dimensions: ITitleControlDimensions): Dimension { if (this.breadcrumbsControl) { this.breadcrumbsControl.layout(undefined); } + + return new Dimension(dimensions.container.width, this.getDimensions().height); } } diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index 44e788c7886..556e4ffecbe 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -18,7 +18,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IMenuService } from 'vs/platform/actions/common/actions'; -import { TitleControl } from 'vs/workbench/browser/parts/editor/titleControl'; +import { ITitleControlDimensions, TitleControl } from 'vs/workbench/browser/parts/editor/titleControl'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { IDisposable, dispose, DisposableStore, combinedDisposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; @@ -90,7 +90,11 @@ export class TabsTitleControl extends TitleControl { private tabActionBars: ActionBar[] = []; private tabDisposables: IDisposable[] = []; - private dimension: Dimension | undefined; + private dimensions: ITitleControlDimensions = { + container: Dimension.None, + available: Dimension.None + }; + private readonly layoutScheduled = this._register(new MutableDisposable()); private blockRevealActiveTab: boolean | undefined; @@ -380,7 +384,7 @@ export class TabsTitleControl extends TitleControl { // Changing the actions in the toolbar can have an impact on the size of the // tab container, so we need to layout the tabs to make sure the active is visible - this.layout(this.dimension); + this.layout(this.dimensions); } openEditor(editor: IEditorInput): void { @@ -463,7 +467,7 @@ export class TabsTitleControl extends TitleControl { }); // Moving an editor requires a layout to keep the active editor visible - this.layout(this.dimension); + this.layout(this.dimensions); } pinEditor(editor: IEditorInput): void { @@ -490,7 +494,7 @@ export class TabsTitleControl extends TitleControl { }); // A change to the sticky state requires a layout to keep the active editor visible - this.layout(this.dimension); + this.layout(this.dimensions); } setActive(isGroupActive: boolean): void { @@ -502,7 +506,7 @@ export class TabsTitleControl extends TitleControl { // Activity has an impact on the toolbar, so we need to update and layout this.updateEditorActionsToolbar(); - this.layout(this.dimension); + this.layout(this.dimensions); } private updateEditorLabelAggregator = this._register(new RunOnceScheduler(() => this.updateEditorLabels(), 0)); @@ -528,7 +532,7 @@ export class TabsTitleControl extends TitleControl { }); // A change to a label requires a layout to keep the active editor visible - this.layout(this.dimension); + this.layout(this.dimensions); } updateEditorDirty(editor: IEditorInput): void { @@ -1046,7 +1050,7 @@ export class TabsTitleControl extends TitleControl { this.updateEditorActionsToolbar(); // Ensure the active tab is always revealed - this.layout(this.dimension); + this.layout(this.dimensions); } private redrawTab(editor: IEditorInput, index: number, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel, tabLabel: IEditorInputLabel, tabActionBar: ActionBar): void { @@ -1260,7 +1264,7 @@ export class TabsTitleControl extends TitleControl { getDimensions(): IEditorGroupTitleDimensions { let height = TabsTitleControl.TAB_HEIGHT; if (this.breadcrumbsControl && !this.breadcrumbsControl.isHidden()) { - height += BreadcrumbsControl.HEIGHT; + height += BreadcrumbsControl.HEIGHT; // Account for breadcrumbs if visible } return { @@ -1269,12 +1273,14 @@ export class TabsTitleControl extends TitleControl { }; } - layout(dimension: Dimension | undefined): void { - this.dimension = dimension; + layout(dimensions: ITitleControlDimensions): Dimension { + this.dimensions = dimensions; + // We need an opened editor and dimensions to layout the title + // Otherwise quickly return from the layout algorithm const activeTabAndIndex = this.group.activeEditor ? this.getTabAndIndex(this.group.activeEditor) : undefined; - if (!activeTabAndIndex || !this.dimension) { - return; + if (!activeTabAndIndex || dimensions.container === Dimension.None || dimensions.available === Dimension.None) { + return Dimension.None; } // The layout of tabs can be an expensive operation because we access DOM properties @@ -1282,34 +1288,32 @@ export class TabsTitleControl extends TitleControl { // this a little bit we try at least to schedule this work on the next animation frame. if (!this.layoutScheduled.value) { this.layoutScheduled.value = scheduleAtNextAnimationFrame(() => { - const dimension = assertIsDefined(this.dimension); - this.doLayout(dimension); + this.doLayout(this.dimensions); this.layoutScheduled.clear(); }); } + + return new Dimension(dimensions.container.width, this.getDimensions().height); } - private doLayout(dimension: Dimension): void { + private doLayout(dimensions: ITitleControlDimensions): void { const activeTabAndIndex = this.group.activeEditor ? this.getTabAndIndex(this.group.activeEditor) : undefined; if (!activeTabAndIndex) { return; // nothing to do if not editor opened } // Breadcrumbs - this.doLayoutBreadcrumbs(dimension); + this.doLayoutBreadcrumbs(dimensions); // Tabs const [activeTab, activeIndex] = activeTabAndIndex; this.doLayoutTabs(activeTab, activeIndex); } - private doLayoutBreadcrumbs(dimension: Dimension): void { + private doLayoutBreadcrumbs(dimensions: ITitleControlDimensions): void { if (this.breadcrumbsControl && !this.breadcrumbsControl.isHidden()) { - const tabsScrollbar = assertIsDefined(this.tabsScrollbar); - - this.breadcrumbsControl.layout(new Dimension(dimension.width, BreadcrumbsControl.HEIGHT)); - tabsScrollbar.getDomNode().style.height = `${dimension.height - BreadcrumbsControl.HEIGHT}px`; + this.breadcrumbsControl.layout(new Dimension(dimensions.container.width, BreadcrumbsControl.HEIGHT)); } } @@ -1452,8 +1456,10 @@ export class TabsTitleControl extends TitleControl { const editorIndex = this.group.getIndexOfEditor(editor); if (editorIndex >= 0) { const tabsContainer = assertIsDefined(this.tabsContainer); - - return [tabsContainer.children[editorIndex] as HTMLElement, editorIndex]; + const tab = tabsContainer.children[editorIndex]; + if (tab) { + return [tab as HTMLElement, editorIndex]; + } } return undefined; diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index 8358dfcbaac..0eaa213ab76 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -46,6 +46,20 @@ export interface IToolbarActions { secondary: IAction[]; } +export interface ITitleControlDimensions { + + /** + * The size of the parent container the title control is layed out in. + */ + container: Dimension; + + /** + * The maximum size the title control is allowed to consume based on + * other controls that are positioned inside the container. + */ + available: Dimension; +} + export abstract class TitleControl extends Themable { protected readonly groupTransfer = LocalSelectionTransfer.getInstance(); @@ -407,7 +421,7 @@ export abstract class TitleControl extends Themable { abstract updateStyles(): void; - abstract layout(dimension: Dimension): void; + abstract layout(dimensions: ITitleControlDimensions): Dimension; abstract getDimensions(): IEditorGroupTitleDimensions; From b2eedd8ee0905b7aa970541c5e5a9c317c51014d Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Tue, 8 Dec 2020 17:24:59 +0100 Subject: [PATCH 180/200] Add `wss:` / `ws:` to the CSP --- .../extensions/worker/httpWebWorkerExtensionHostIframe.html | 2 +- .../extensions/worker/httpsWebWorkerExtensionHostIframe.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html b/src/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html index 392b4b4aeaa..67560d96e6d 100644 --- a/src/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html +++ b/src/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html @@ -1,7 +1,7 @@ - +