From 868757048df62f4ea905c71774aedc040f0db0df Mon Sep 17 00:00:00 2001 From: Andrew Hlynskyi Date: Sat, 3 Dec 2022 06:22:30 +0200 Subject: [PATCH 001/240] feat: Add resolving of "fileWorkspaceFolderBasename" variable --- .../configuration-editing/src/configurationEditingMain.ts | 1 + .../configurationResolver/common/configurationResolver.ts | 1 + .../services/configurationResolver/common/variableResolver.ts | 3 +++ 3 files changed, 5 insertions(+) diff --git a/extensions/configuration-editing/src/configurationEditingMain.ts b/extensions/configuration-editing/src/configurationEditingMain.ts index acbd032dee2..02f52f6e721 100644 --- a/extensions/configuration-editing/src/configurationEditingMain.ts +++ b/extensions/configuration-editing/src/configurationEditingMain.ts @@ -54,6 +54,7 @@ function registerVariableCompletions(pattern: string): vscode.Disposable { return [ { label: 'workspaceFolder', detail: vscode.l10n.t("The path of the folder opened in VS Code") }, { label: 'workspaceFolderBasename', detail: vscode.l10n.t("The name of the folder opened in VS Code without any slashes (/)") }, + { label: 'fileWorkspaceFolderBasename', detail: vscode.l10n.t("The current opened file workspace folder name without any slashes (/)") }, { label: 'relativeFile', detail: vscode.l10n.t("The current opened file relative to ${workspaceFolder}") }, { label: 'relativeFileDirname', detail: vscode.l10n.t("The current opened file's dirname relative to ${workspaceFolder}") }, { label: 'file', detail: vscode.l10n.t("The current opened file") }, diff --git a/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts b/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts index 135ff269e94..b7aae580717 100644 --- a/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts @@ -97,6 +97,7 @@ export enum VariableKind { SelectedText = 'selectedText', File = 'file', FileWorkspaceFolder = 'fileWorkspaceFolder', + FileWorkspaceFolderBasename = 'fileWorkspaceFolderBasename', RelativeFile = 'relativeFile', RelativeFileDirname = 'relativeFileDirname', FileDirname = 'fileDirname', diff --git a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts index 2f8d679e6e4..a48ba95b5bb 100644 --- a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts @@ -320,6 +320,9 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe case 'fileWorkspaceFolder': return getFolderPathForFile(VariableKind.FileWorkspaceFolder); + case 'fileWorkspaceFolderBasename': + return paths.basename(getFolderPathForFile(VariableKind.FileWorkspaceFolderBasename)); + case 'relativeFile': if (folderUri || argument) { return paths.relative(this.fsPath(getFolderUri(VariableKind.RelativeFile)), getFilePath(VariableKind.RelativeFile)); From ed37d32ee1deac1d074846e8241f647205642b44 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 25 Aug 2023 06:38:50 -0700 Subject: [PATCH 002/240] Sticky scroll WIP Part of #172742 --- .../common/capabilities/capabilities.ts | 1 + .../commandDetectionCapability.ts | 12 +++ .../contrib/terminal/terminal.all.ts | 1 + .../browser/media/stickyScroll.css | 16 ++++ .../terminal.stickyScroll.contribution.ts | 91 +++++++++++++++++++ 5 files changed, 121 insertions(+) create mode 100644 src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css create mode 100644 src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts diff --git a/src/vs/platform/terminal/common/capabilities/capabilities.ts b/src/vs/platform/terminal/common/capabilities/capabilities.ts index e7b7dcb57bd..e47b5c7fc94 100644 --- a/src/vs/platform/terminal/common/capabilities/capabilities.ts +++ b/src/vs/platform/terminal/common/capabilities/capabilities.ts @@ -167,6 +167,7 @@ export interface ICommandDetectionCapability { * case the terminal's initial cwd should be used. */ getCwdForLine(line: number): string | undefined; + getCommandForLine(line: number): ITerminalCommand | ICurrentPartialCommand | undefined; handlePromptStart(options?: IHandleCommandOptions): void; handleContinuationStart(): void; handleContinuationEnd(): void; diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index f3c2519be9e..db0d43ba80e 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -284,6 +284,18 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe this.__isCommandStorageDisabled = true; } + getCommandForLine(line: number): ITerminalCommand | ICurrentPartialCommand | undefined { + // Handle the current partial command first, anything below it's prompt is considered part + // of the current command + if (this._currentCommand.promptStartMarker && line >= this._currentCommand.promptStartMarker?.line) { + return this._currentCommand; + } + // TODO: It would be more reliable to take the closest cwd above the line if it isn't found for the line + // TODO: Use a reverse for loop to find the line to avoid creating another array + const reversed = [...this._commands].reverse(); + return reversed.find(c => c.marker!.line <= line - 1); + } + getCwdForLine(line: number): string | undefined { // Handle the current partial command first, anything below it's prompt is considered part // of the current command diff --git a/src/vs/workbench/contrib/terminal/terminal.all.ts b/src/vs/workbench/contrib/terminal/terminal.all.ts index d2a0d591c81..563bf065317 100644 --- a/src/vs/workbench/contrib/terminal/terminal.all.ts +++ b/src/vs/workbench/contrib/terminal/terminal.all.ts @@ -18,5 +18,6 @@ import 'vs/workbench/contrib/terminalContrib/developer/browser/terminal.develope import 'vs/workbench/contrib/terminalContrib/environmentChanges/browser/terminal.environmentChanges.contribution'; import 'vs/workbench/contrib/terminalContrib/find/browser/terminal.find.contribution'; import 'vs/workbench/contrib/terminalContrib/links/browser/terminal.links.contribution'; +import 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution'; import 'vs/workbench/contrib/terminalContrib/quickFix/browser/terminal.quickFix.contribution'; import 'vs/workbench/contrib/terminalContrib/typeAhead/browser/terminal.typeAhead.contribution'; diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css new file mode 100644 index 00000000000..49cb0cae8db --- /dev/null +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css @@ -0,0 +1,16 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.terminal-sticky-scroll { + position: absolute; + left: 0; + right: 0; + top: 0; + background: red; + z-index: 32; /* Must be higher than .xterm-viewport and decorations*/ + /* TODO: Sticky scroll background key */ + background: var(--vscode-terminal-background, var(--vscode-panel-background)); + box-shadow: var(--vscode-scrollbar-shadow) 0 3px 2px -2px; +} diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts new file mode 100644 index 00000000000..5973426a90e --- /dev/null +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -0,0 +1,91 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/css!./media/stickyScroll'; +import { throttle } from 'vs/base/common/decorators'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { IDetachedTerminalInstance, ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; +import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; +import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; +import type { Terminal as RawXtermTerminal } from 'xterm'; +import { hide, show } from 'vs/base/browser/dom'; + +class TerminalStickyScrollContribution extends DisposableStore implements ITerminalContribution { + static readonly ID = 'terminal.stickyScroll'; + + static get(instance: ITerminalInstance): TerminalStickyScrollContribution | null { + return instance.getContribution(TerminalStickyScrollContribution.ID); + } + + private _xterm?: IXtermTerminal & { raw: RawXtermTerminal }; + private _element?: HTMLElement; + + constructor( + private readonly _instance: ITerminalInstance, + private readonly _processManager: ITerminalProcessManager, + private readonly _widgetManager: TerminalWidgetManager, + @ITerminalService private readonly _terminalService: ITerminalService, + ) { + super(); + } + + xtermReady(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { + this._xterm = xterm; + this.add(xterm.raw.onScroll(() => this._refresh())); + this.add(xterm.raw.onLineFeed(() => this._refresh())); + // TODO: Disable in alt buffer + } + + @throttle(0) + private _refresh(): void { + if (!this._xterm?.raw?.element) { + return; + } + // TODO: Cache + const commandDetection = this._instance.capabilities.get(TerminalCapability.CommandDetection); + if (!commandDetection) { + return; + } + const command = commandDetection.getCommandForLine(this._xterm.raw.buffer.active.viewportY); + // TODO: Expose unified interface for fetching line content + const marker = command && 'commandStartMarker' in command + ? command.commandStartMarker + : command && 'marker' in command + ? command.marker + : undefined; + if (!marker || marker.line === -1) { + return; + } + const element = this._ensureElement(this._xterm.raw.element); + element.textContent = this._xterm.raw.buffer.active.getLine(marker.line)?.translateToString(true) ?? ''; + if (element.textContent === '') { + hide(element); + } else { + show(element); + } + console.log('command!', command); + } + + private _ensureElement(container: HTMLElement): HTMLElement { + if (!this._element) { + this._element = document.createElement('div'); + this._element.classList.add('terminal-sticky-scroll'); + // TODO: listen to font changes + const font = this._terminalService.configHelper.getFont(); + this._element.style.fontSize = `${font.fontSize}px`; + this._element.style.fontFamily = font.fontFamily; + // TODO: Verify these are correct format + this._element.style.letterSpacing = `${font.letterSpacing}px`; + this._element.style.lineHeight = `${font.lineHeight * font.fontSize}px`; + // TODO: Safety + container.querySelector('.xterm-screen')!.append(this._element); + } + return this._element; + } +} + +registerTerminalContribution(TerminalStickyScrollContribution.ID, TerminalStickyScrollContribution, true); From b052d34e5ccee21a65b6b34f06074321e0b31028 Mon Sep 17 00:00:00 2001 From: tisilent Date: Thu, 5 Oct 2023 00:58:02 +0800 Subject: [PATCH 003/240] Add mousedown,contextmenu events --- .../browser/find/simpleFindWidget.ts | 4 ++ .../find/browser/terminalFindWidget.ts | 20 +++++- .../find/browser/textInputContextMenu.ts | 62 +++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/vs/workbench/contrib/terminalContrib/find/browser/textInputContextMenu.ts diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts index 2659700d67d..dfc2cf02c54 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts @@ -289,6 +289,10 @@ export abstract class SimpleFindWidget extends Widget implements IVerticalSashLa return this._domNode; } + public getFindInputDomNode() { + return this._findInput.domNode; + } + public reveal(initialInput?: string, animated = true): void { if (initialInput) { this._findInput.setValue(initialInput); diff --git a/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts b/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts index efb9b621568..f055f70620d 100644 --- a/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/find/browser/terminalFindWidget.ts @@ -3,8 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as dom from 'vs/base/browser/dom'; import { SimpleFindWidget } from 'vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget'; -import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; +import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ITerminalInstance, IXtermTerminal, XtermTerminalConstants } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; @@ -14,6 +15,8 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { Event } from 'vs/base/common/event'; import type { ISearchOptions } from 'xterm-addon-search'; import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { openContextMenu } from 'vs/workbench/contrib/terminalContrib/find/browser/textInputContextMenu'; const TERMINAL_FIND_WIDGET_INITIAL_WIDTH = 419; @@ -27,6 +30,8 @@ export class TerminalFindWidget extends SimpleFindWidget { @IContextViewService _contextViewService: IContextViewService, @IKeybindingService keybindingService: IKeybindingService, @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IContextMenuService _contextMenuService: IContextMenuService, + @IClipboardService _clipboardService: IClipboardService, @IThemeService private readonly _themeService: IThemeService, @IConfigurationService private readonly _configurationService: IConfigurationService ) { @@ -52,6 +57,19 @@ export class TerminalFindWidget extends SimpleFindWidget { this._findInputFocused = TerminalContextKeys.findInputFocus.bindTo(this._contextKeyService); this._findWidgetFocused = TerminalContextKeys.findFocus.bindTo(this._contextKeyService); this._findWidgetVisible = TerminalContextKeys.findVisible.bindTo(this._contextKeyService); + const innerDom = this.getDomNode().firstChild; + if (innerDom) { + this._register(dom.addDisposableListener(innerDom, 'mousedown', (event) => { + event.stopPropagation(); + })); + this._register(dom.addDisposableListener(innerDom, 'contextmenu', (event) => { + event.stopPropagation(); + })); + } + this._register(dom.addDisposableListener(this.getFindInputDomNode(), 'contextmenu', (event) => { + openContextMenu(event, _clipboardService, _contextMenuService); + event.stopPropagation(); + })); this._register(this._themeService.onDidColorThemeChange(() => { if (this.isVisible()) { this.find(true, true); diff --git a/src/vs/workbench/contrib/terminalContrib/find/browser/textInputContextMenu.ts b/src/vs/workbench/contrib/terminalContrib/find/browser/textInputContextMenu.ts new file mode 100644 index 00000000000..68dbae05a05 --- /dev/null +++ b/src/vs/workbench/contrib/terminalContrib/find/browser/textInputContextMenu.ts @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; +import { Action, IAction, Separator } from 'vs/base/common/actions'; +import { isNative } from 'vs/base/common/platform'; +import { localize } from 'vs/nls'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; + +export function openContextMenu(event: MouseEvent, clipboardService: IClipboardService, contextMenuService: IContextMenuService): void { + const standardEvent = new StandardMouseEvent(event); + + // Actions from workbench/browser/actions/textInputActions + const actions: IAction[] = []; + actions.push( + + // Undo/Redo + new Action('undo', localize('undo', "Undo"), undefined, true, async () => document.execCommand('undo')), + new Action('redo', localize('redo', "Redo"), undefined, true, async () => document.execCommand('redo')), + new Separator(), + + // Cut / Copy / Paste + new Action('editor.action.clipboardCutAction', localize('cut', "Cut"), undefined, true, async () => document.execCommand('cut')), + new Action('editor.action.clipboardCopyAction', localize('copy', "Copy"), undefined, true, async () => document.execCommand('copy')), + new Action('editor.action.clipboardPasteAction', localize('paste', "Paste"), undefined, true, async element => { + + // Native: paste is supported + if (isNative) { + document.execCommand('paste'); + } + + // Web: paste is not supported due to security reasons + else { + const clipboardText = await clipboardService.readText(); + if ( + element instanceof HTMLTextAreaElement || + element instanceof HTMLInputElement + ) { + const selectionStart = element.selectionStart || 0; + const selectionEnd = element.selectionEnd || 0; + + element.value = `${element.value.substring(0, selectionStart)}${clipboardText}${element.value.substring(selectionEnd, element.value.length)}`; + element.selectionStart = selectionStart + clipboardText.length; + element.selectionEnd = element.selectionStart; + } + } + }), + new Separator(), + + // Select All + new Action('editor.action.selectAll', localize('selectAll', "Select All"), undefined, true, async () => document.execCommand('selectAll')) + ); + + contextMenuService.showContextMenu({ + getAnchor: () => standardEvent, + getActions: () => actions, + getActionsContext: () => event.target, + }); +} From b1cbd520c9c738491696f39c5faf9e3fea8838e7 Mon Sep 17 00:00:00 2001 From: Cody Beyer Date: Tue, 10 Oct 2023 16:12:13 -0700 Subject: [PATCH 004/240] adding container registry package --- .../contrib/tags/electron-sandbox/workspaceTagsService.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts index 91e03015dc5..a3dc8939bb8 100644 --- a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts +++ b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts @@ -205,6 +205,7 @@ const PyModulesToLookFor = [ 'azure-cognitiveservices-nspkg', 'azure-cognitiveservices-language-nspkg', 'azure-cognitiveservices-knowledge-nspkg', + 'azure-containerregistry', 'azure-monitor', 'azure-mgmt-appcontainers', 'azure-mgmt-apimanagement', @@ -627,6 +628,7 @@ export class WorkspaceTagsService implements IWorkspaceTagsService { "workspace.py.azure-cognitiveservices-nspkg" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.py.azure-cognitiveservices-language-nspkg" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.py.azure-cognitiveservices-knowledge-nspkg" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.py.azure-containerregistry" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.py.azure-ai-metricsadvisor" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.py.azureml-sdk" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.py.azure-keyvault-nspkg" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, From c7474e2dc18f592b2b8bf7fcbfb44f4400c4d2b9 Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Thu, 26 Oct 2023 15:30:25 -0700 Subject: [PATCH 005/240] Show Dynamic Configuration Providers with No Context This PR adds support to show dynamic configurations when a file is not selected. The changes introduces a new method to the Debugger class called hasDynamicConfigurationProviders. It utilizes the existing ConfigurationManager.hasDebugConfigurationProvider but passing Dynamic TiggerKind instead of Initial. --- .../workbench/contrib/debug/browser/debugAdapterManager.ts | 3 ++- src/vs/workbench/contrib/debug/common/debug.ts | 2 +- src/vs/workbench/contrib/debug/common/debugger.ts | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts b/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts index 55314e58a47..423316207be 100644 --- a/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts @@ -341,9 +341,10 @@ export class AdapterManager extends Disposable implements IAdapterManager { // Or if a breakpoint can be set in the current file (good hint that an extension can handle it) if ((!languageLabel || gettingConfigurations || (model && this.canSetBreakpointsIn(model))) && candidates.length === 0) { await this.activateDebuggers('onDebugInitialConfigurations'); + candidates = this.debuggers .filter(a => a.enabled) - .filter(dbg => dbg.hasInitialConfiguration() || dbg.hasConfigurationProvider()); + .filter(dbg => dbg.hasInitialConfiguration() || dbg.hasDynamicConfigurationProviders() || dbg.hasConfigurationProvider()); } if (candidates.length === 0 && languageLabel) { diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index d55bda40b26..7b82c2fe9ac 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -904,7 +904,7 @@ export interface IConfigurationManager { */ onDidSelectConfiguration: Event; - hasDebugConfigurationProvider(debugType: string): boolean; + hasDebugConfigurationProvider(debugType: string, triggerKind?: DebugConfigurationProviderTriggerKind): boolean; getDynamicProviders(): Promise<{ label: string; type: string; pick: () => Promise<{ launch: ILaunch; config: IConfig } | undefined> }[]>; registerDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): IDisposable; diff --git a/src/vs/workbench/contrib/debug/common/debugger.ts b/src/vs/workbench/contrib/debug/common/debugger.ts index e18a400fe91..da2de14c249 100644 --- a/src/vs/workbench/contrib/debug/common/debugger.ts +++ b/src/vs/workbench/contrib/debug/common/debugger.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { isObject } from 'vs/base/common/types'; import { IJSONSchema, IJSONSchemaMap, IJSONSchemaSnippet } from 'vs/base/common/jsonSchema'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { IConfig, IDebuggerContribution, IDebugAdapter, IDebugger, IDebugSession, IAdapterManager, IDebugService, debuggerDisabledMessage, IDebuggerMetadata } from 'vs/workbench/contrib/debug/common/debug'; +import { IConfig, IDebuggerContribution, IDebugAdapter, IDebugger, IDebugSession, IAdapterManager, IDebugService, debuggerDisabledMessage, IDebuggerMetadata, DebugConfigurationProviderTriggerKind } from 'vs/workbench/contrib/debug/common/debug'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import * as ConfigurationResolverUtils from 'vs/workbench/services/configurationResolver/common/configurationResolverUtils'; @@ -176,6 +176,10 @@ export class Debugger implements IDebugger, IDebuggerMetadata { return !!this.debuggerContribution.initialConfigurations; } + hasDynamicConfigurationProviders(): boolean { + return this.debugService.getConfigurationManager().hasDebugConfigurationProvider(this.type, DebugConfigurationProviderTriggerKind.Dynamic); + } + hasConfigurationProvider(): boolean { return this.debugService.getConfigurationManager().hasDebugConfigurationProvider(this.type); } From 6c37d425ebb084086734fd379efbc26d70017512 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 2 Nov 2023 17:37:42 +0100 Subject: [PATCH 006/240] adding code in order to be able to undock the panel chat --- .../contrib/chat/browser/chat.contribution.ts | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index cbe23536b18..28adf7bf0ab 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -10,7 +10,7 @@ import * as nls from 'vs/nls'; import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { Registry } from 'vs/platform/registry/common/platform'; import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; @@ -56,6 +56,10 @@ import { registerChatFileTreeActions } from 'vs/workbench/contrib/chat/browser/a import { QuickChatService } from 'vs/workbench/contrib/chat/browser/chatQuick'; import { ChatAgentService, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents'; import { ChatVariablesService } from 'vs/workbench/contrib/chat/browser/chatVariables'; +import { Action2 } from 'vs/platform/actions/common/actions'; +import { Categories } from 'vs/platform/action/common/actionCommonCategories'; +import { ActiveEditorContext } from 'vs/workbench/common/contextkeys'; +import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; // Register configuration const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); @@ -93,7 +97,7 @@ configurationRegistry.registerConfiguration({ } }); - +// TODO Registry.as(EditorExtensions.EditorPane).registerEditorPane( EditorPaneDescriptor.create( ChatEditor, @@ -234,6 +238,50 @@ class ChatSlashStaticSlashCommandsContribution extends Disposable { } } +export class ChatUndockAction extends Action2 { + + constructor() { + super({ + id: 'chat.action.undock', + title: { + value: nls.localize('chatUndock', "Undock the panel chat (experimental)"), + mnemonicTitle: nls.localize({ key: 'miChatUndock', comment: ['&& denotes a mnemonic'] }, "&&Undock the panel chat (experimental)"), + original: 'Undock the panel chat (experimental)' + }, + category: Categories.View, + precondition: ActiveEditorContext, + f1: true + }); + } + + override async run(accessor: ServicesAccessor): Promise { + + const chatWidgetService = accessor.get(IChatWidgetService); + const lastFocusedWidget = chatWidgetService.lastFocusedWidget; + if (!lastFocusedWidget) { + return; + } + const viewModel = lastFocusedWidget.viewModel; + if (!viewModel) { + return; + } + const sessionId = viewModel.sessionId; + + const editorGroupService = accessor.get(IEditorGroupsService); + // create a chat editor and drop it inside of the group + const editorPanesRegistry = Registry.as(EditorExtensions.EditorPane); + const instantiationService = accessor.get(IInstantiationService); + const chatEditorInput: ChatEditorInput = instantiationService.createInstance(ChatEditorInput, ChatEditorInput.getNewEditorUri(), { target: { sessionId } }); + const editorPaneDescriptor = editorPanesRegistry.getEditorPane(chatEditorInput); + const auxiliaryEditorPart = await editorGroupService.createAuxiliaryEditorPart(); + const editorPane = editorPaneDescriptor?.instantiate(instantiationService); + if (!editorPane || !editorPane.group || !editorPane.input) { + return; + } + editorPane.group.moveEditor(editorPane.input, auxiliaryEditorPart.activeGroup); + } +} + const workbenchContributionsRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchContributionsRegistry.registerWorkbenchContribution(ChatResolverContribution, LifecyclePhase.Starting); workbenchContributionsRegistry.registerWorkbenchContribution(ChatAccessibleViewContribution, LifecyclePhase.Eventually); From b7153f54444f2e4b5e3a24d8b067798499521d65 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 2 Nov 2023 17:58:13 +0100 Subject: [PATCH 007/240] adding code --- .../chat/browser/actions/chatActions.ts | 49 ++++++++++++++++++ .../contrib/chat/browser/chat.contribution.ts | 50 +------------------ 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts index 8d70003a263..e608981d374 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts @@ -32,6 +32,12 @@ import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions'; import { IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents'; import { chatAgentLeader } from 'vs/workbench/contrib/chat/common/chatParserTypes'; +import { Categories } from 'vs/platform/action/common/actionCommonCategories'; +import { ActiveEditorContext } from 'vs/workbench/common/contextkeys'; +import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IEditorPaneRegistry } from 'vs/workbench/browser/editor'; +import { EditorExtensions } from 'vs/workbench/common/editor'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export const CHAT_CATEGORY = { value: localize('chat.category', "Chat"), original: 'Chat' }; export const CHAT_OPEN_ACTION_ID = 'workbench.action.chat.open'; @@ -207,6 +213,49 @@ export function registerChatActions() { widgetService.lastFocusedWidget?.focusInput(); } }); + + registerAction2(class ChatUndockAction extends Action2 { + + constructor() { + super({ + id: 'chat.action.undock', + title: { + value: localize('chatUndock', "Undock the panel chat (experimental)"), + mnemonicTitle: localize({ key: 'miChatUndock', comment: ['&& denotes a mnemonic'] }, "&&Undock the panel chat (experimental)"), + original: 'Undock the panel chat (experimental)' + }, + category: Categories.View, + precondition: ActiveEditorContext, + f1: true + }); + } + + override async run(accessor: ServicesAccessor): Promise { + + const chatWidgetService = accessor.get(IChatWidgetService); + const lastFocusedWidget = chatWidgetService.lastFocusedWidget; + if (!lastFocusedWidget) { + return; + } + const viewModel = lastFocusedWidget.viewModel; + if (!viewModel) { + return; + } + const sessionId = viewModel.sessionId; + const editorGroupService = accessor.get(IEditorGroupsService); + // create a chat editor and drop it inside of the group + const editorPanesRegistry = Registry.as(EditorExtensions.EditorPane); + const instantiationService = accessor.get(IInstantiationService); + const chatEditorInput: ChatEditorInput = instantiationService.createInstance(ChatEditorInput, ChatEditorInput.getNewEditorUri(), { target: { sessionId } }); + const editorPaneDescriptor = editorPanesRegistry.getEditorPane(chatEditorInput); + const auxiliaryEditorPart = await editorGroupService.createAuxiliaryEditorPart(); + const editorPane = editorPaneDescriptor?.instantiate(instantiationService); + if (!editorPane || !editorPane.group || !editorPane.input) { + return; + } + editorPane.group.moveEditor(editorPane.input, auxiliaryEditorPart.activeGroup); + } + }); } export function getOpenChatEditorAction(id: string, label: string, when?: string) { diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index 28adf7bf0ab..7c68e511413 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -10,7 +10,7 @@ import * as nls from 'vs/nls'; import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Registry } from 'vs/platform/registry/common/platform'; import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; @@ -56,10 +56,6 @@ import { registerChatFileTreeActions } from 'vs/workbench/contrib/chat/browser/a import { QuickChatService } from 'vs/workbench/contrib/chat/browser/chatQuick'; import { ChatAgentService, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents'; import { ChatVariablesService } from 'vs/workbench/contrib/chat/browser/chatVariables'; -import { Action2 } from 'vs/platform/actions/common/actions'; -import { Categories } from 'vs/platform/action/common/actionCommonCategories'; -import { ActiveEditorContext } from 'vs/workbench/common/contextkeys'; -import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; // Register configuration const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); @@ -238,50 +234,6 @@ class ChatSlashStaticSlashCommandsContribution extends Disposable { } } -export class ChatUndockAction extends Action2 { - - constructor() { - super({ - id: 'chat.action.undock', - title: { - value: nls.localize('chatUndock', "Undock the panel chat (experimental)"), - mnemonicTitle: nls.localize({ key: 'miChatUndock', comment: ['&& denotes a mnemonic'] }, "&&Undock the panel chat (experimental)"), - original: 'Undock the panel chat (experimental)' - }, - category: Categories.View, - precondition: ActiveEditorContext, - f1: true - }); - } - - override async run(accessor: ServicesAccessor): Promise { - - const chatWidgetService = accessor.get(IChatWidgetService); - const lastFocusedWidget = chatWidgetService.lastFocusedWidget; - if (!lastFocusedWidget) { - return; - } - const viewModel = lastFocusedWidget.viewModel; - if (!viewModel) { - return; - } - const sessionId = viewModel.sessionId; - - const editorGroupService = accessor.get(IEditorGroupsService); - // create a chat editor and drop it inside of the group - const editorPanesRegistry = Registry.as(EditorExtensions.EditorPane); - const instantiationService = accessor.get(IInstantiationService); - const chatEditorInput: ChatEditorInput = instantiationService.createInstance(ChatEditorInput, ChatEditorInput.getNewEditorUri(), { target: { sessionId } }); - const editorPaneDescriptor = editorPanesRegistry.getEditorPane(chatEditorInput); - const auxiliaryEditorPart = await editorGroupService.createAuxiliaryEditorPart(); - const editorPane = editorPaneDescriptor?.instantiate(instantiationService); - if (!editorPane || !editorPane.group || !editorPane.input) { - return; - } - editorPane.group.moveEditor(editorPane.input, auxiliaryEditorPart.activeGroup); - } -} - const workbenchContributionsRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchContributionsRegistry.registerWorkbenchContribution(ChatResolverContribution, LifecyclePhase.Starting); workbenchContributionsRegistry.registerWorkbenchContribution(ChatAccessibleViewContribution, LifecyclePhase.Eventually); From 9d08bee81e15dde4a1ab5c8ef74564b10149285d Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 3 Nov 2023 10:15:14 +0100 Subject: [PATCH 008/240] adding change --- src/vs/workbench/contrib/chat/browser/actions/chatActions.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts index e608981d374..a0412cac5b6 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts @@ -33,7 +33,6 @@ import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/brow import { IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents'; import { chatAgentLeader } from 'vs/workbench/contrib/chat/common/chatParserTypes'; import { Categories } from 'vs/platform/action/common/actionCommonCategories'; -import { ActiveEditorContext } from 'vs/workbench/common/contextkeys'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorPaneRegistry } from 'vs/workbench/browser/editor'; import { EditorExtensions } from 'vs/workbench/common/editor'; @@ -225,7 +224,7 @@ export function registerChatActions() { original: 'Undock the panel chat (experimental)' }, category: Categories.View, - precondition: ActiveEditorContext, + precondition: undefined, f1: true }); } From a796401fe5749a55d8d7872e615e23c749daed8e Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 3 Nov 2023 08:39:10 -0700 Subject: [PATCH 009/240] don't cache persistent tasks --- .../tasks/browser/abstractTaskService.ts | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 037abbeff2c..50e5b92bc61 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -216,8 +216,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private _recentlyUsedTasksV1: LRUCache | undefined; private _recentlyUsedTasks: LRUCache | undefined; - private _persistentTasks: LRUCache | undefined; - protected _taskRunningState: IContextKey; protected _outputChannel: IOutputChannel; @@ -299,7 +297,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (e.affectsConfiguration(TaskSettingId.Reconnection)) { if (!this._configurationService.getValue(TaskSettingId.Reconnection)) { - this._persistentTasks?.clear(); this._storageService.remove(AbstractTaskService.PersistentTasks_Key, StorageScope.WORKSPACE); } } @@ -387,15 +384,19 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private _attemptTaskReconnection(): void { if (this._lifecycleService.startupKind !== StartupKind.ReloadedWindow) { + this._outputChannel.append(nls.localize('TaskService.skippingReconnection', '#taskService startup kind not window reload, setting connected and removing persistent tasks\n')); this._tasksReconnected = true; this._storageService.remove(AbstractTaskService.PersistentTasks_Key, StorageScope.WORKSPACE); } if (!this._configurationService.getValue(TaskSettingId.Reconnection) || this._tasksReconnected) { + this._outputChannel.append(nls.localize('TaskService.notConnecting', '#taskService Setting tasks connected configured value {0}, tasks were already reconnected {1}\n', this._configurationService.getValue(TaskSettingId.Reconnection), this._tasksReconnected)); this._tasksReconnected = true; return; } + this._outputChannel.append(nls.localize('TaskService.reconnecting', '#taskService Reconnecting to running tasks...\n')); this.getWorkspaceTasks(TaskRunSource.Reconnect).then(async () => { this._tasksReconnected = await this._reconnectTasks(); + this._outputChannel.append(nls.localize('TaskService.reconnected', '#taskService Reconnected to running tasks.\n')); this._onDidReconnectToTasks.fire(); }); } @@ -403,8 +404,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private async _reconnectTasks(): Promise { const tasks = await this.getSavedTasks('persistent'); if (!tasks.length) { + this._outputChannel.append(nls.localize('TaskService.noTasks', '#taskService No persistent tasks to reconnect.\n')); return true; } + const taskLabels = tasks.map(task => task._label).join(', '); + this._outputChannel.append(nls.localize('TaskService.reconnectingTasks', '#taskService Reconnecting to {0} tasks...\n', taskLabels)); for (const task of tasks) { if (ConfiguringTask.is(task)) { const resolved = await this.tryResolveTask(task); @@ -964,25 +968,26 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private _getPersistentTasks(): LRUCache { - if (this._persistentTasks) { - return this._persistentTasks; - } + // if (this._persistentTasks) { + // this._outputChannel.append(nls.localize('taskService.gettingCachedTasks', 'Returning cached tasks {0}\n', this._persistentTasks.size)); + // return this._persistentTasks; + // } //TODO: should this # be configurable? - this._persistentTasks = new LRUCache(10); + const persistentTasks = new LRUCache(10); const storageValue = this._storageService.get(AbstractTaskService.PersistentTasks_Key, StorageScope.WORKSPACE); if (storageValue) { try { const values: [string, string][] = JSON.parse(storageValue); if (Array.isArray(values)) { for (const value of values) { - this._persistentTasks.set(value[0], value[1]); + persistentTasks.set(value[0], value[1]); } } } catch (error) { // Ignore. We use the empty result } } - return this._persistentTasks; + return persistentTasks; } private _getFolderFromTaskKey(key: string): { folder: string | undefined; isWorkspaceFile: boolean | undefined } { @@ -1001,7 +1006,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const workspaceToTaskMap: Map = new Map(); const storedTasks = this._getTasksFromStorage(type); const tasks: (Task | ConfiguringTask)[] = []; - + this._outputChannel.append(nls.localize('taskService.getSavedTasks', '#taskService Fetching tasks from task storage.')); function addTaskToMap(map: Map, folder: string | undefined, task: any) { if (folder && !map.has(folder)) { map.set(folder, []); @@ -1010,10 +1015,12 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer map.get(folder).push(task); } } + for (const entry of storedTasks.entries()) { const key = entry[0]; const task = JSON.parse(entry[1]); const folderInfo = this._getFolderFromTaskKey(key); + this._outputChannel.append(nls.localize('taskService.getSavedTasks.reading', '#taskService Reading tasks from task storage, {0}, {1}, {2}', key, task, folderInfo.folder)); addTaskToMap(folderInfo.isWorkspaceFile ? workspaceToTaskMap : folderToTasksMap, folderInfo.folder, task); } @@ -1050,6 +1057,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer for (const key of storedTasks.keys()) { if (readTasksMap.has(key)) { tasks.push(readTasksMap.get(key)!); + this._outputChannel.append(nls.localize('taskService.getSavedTasks.resolved', '#taskService Resolved task {0}', key)); + } else { + this._outputChannel.append(nls.localize('taskService.getSavedTasks.unresolved', '#taskService Unable to resolve task {0}', key)); } } return tasks; @@ -1143,14 +1153,13 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private _savePersistentTasks(): void { - if (!this._persistentTasks) { - return; - } - const keys = [...this._persistentTasks.keys()]; + const persistentTasks = this._getTasksFromStorage('persistent'); + const keys = [...persistentTasks.keys()]; const keyValues: [string, string][] = []; for (const key of keys) { - keyValues.push([key, this._persistentTasks.get(key, Touch.None)!]); + keyValues.push([key, persistentTasks.get(key, Touch.None)!]); } + this._outputChannel.append(nls.localize('savePersistentTask', 'Saving persistent tasks: {0}', keyValues.length)); this._storageService.store(AbstractTaskService.PersistentTasks_Key, JSON.stringify(keyValues), StorageScope.WORKSPACE, StorageTarget.MACHINE); } From ad7850b1c62c84ed463ff624ca9eea38cf4c018f Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 3 Nov 2023 12:23:27 -0700 Subject: [PATCH 010/240] add logs --- .../tasks/browser/abstractTaskService.ts | 55 +++++++++++-------- .../tasks/browser/task.contribution.ts | 5 ++ .../workbench/contrib/tasks/common/tasks.ts | 3 +- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 50e5b92bc61..c322650a4dd 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -334,6 +334,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._willRestart = e.reason !== ShutdownReason.RELOAD; }); this._register(this.onDidStateChange(e => { + this._logService.debug('Task Event kind: ', e.kind); if (e.kind === TaskEventKind.Changed) { // no-op } else if ((this._willRestart || (e.kind === TaskEventKind.Terminated && e.exitReason === TerminalExitReason.User)) && e.taskId) { @@ -384,19 +385,19 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private _attemptTaskReconnection(): void { if (this._lifecycleService.startupKind !== StartupKind.ReloadedWindow) { - this._outputChannel.append(nls.localize('TaskService.skippingReconnection', '#taskService startup kind not window reload, setting connected and removing persistent tasks\n')); + this._log(nls.localize('TaskService.skippingReconnection', '#taskService startup kind not window reload, setting connected and removing persistent tasks\n'), true); this._tasksReconnected = true; this._storageService.remove(AbstractTaskService.PersistentTasks_Key, StorageScope.WORKSPACE); } if (!this._configurationService.getValue(TaskSettingId.Reconnection) || this._tasksReconnected) { - this._outputChannel.append(nls.localize('TaskService.notConnecting', '#taskService Setting tasks connected configured value {0}, tasks were already reconnected {1}\n', this._configurationService.getValue(TaskSettingId.Reconnection), this._tasksReconnected)); + this._log(nls.localize('TaskService.notConnecting', '#taskService Setting tasks connected configured value {0}, tasks were already reconnected {1}\n', this._configurationService.getValue(TaskSettingId.Reconnection), this._tasksReconnected), true); this._tasksReconnected = true; return; } - this._outputChannel.append(nls.localize('TaskService.reconnecting', '#taskService Reconnecting to running tasks...\n')); + this._log(nls.localize('TaskService.reconnecting', '#taskService Reconnecting to running tasks...\n'), true); this.getWorkspaceTasks(TaskRunSource.Reconnect).then(async () => { this._tasksReconnected = await this._reconnectTasks(); - this._outputChannel.append(nls.localize('TaskService.reconnected', '#taskService Reconnected to running tasks.\n')); + this._log(nls.localize('TaskService.reconnected', '#taskService Reconnected to running tasks.\n'), true); this._onDidReconnectToTasks.fire(); }); } @@ -404,11 +405,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private async _reconnectTasks(): Promise { const tasks = await this.getSavedTasks('persistent'); if (!tasks.length) { - this._outputChannel.append(nls.localize('TaskService.noTasks', '#taskService No persistent tasks to reconnect.\n')); + this._log(nls.localize('TaskService.noTasks', '#taskService No persistent tasks to reconnect.\n'), true); return true; } const taskLabels = tasks.map(task => task._label).join(', '); - this._outputChannel.append(nls.localize('TaskService.reconnectingTasks', '#taskService Reconnecting to {0} tasks...\n', taskLabels)); + this._log(nls.localize('TaskService.reconnectingTasks', '#taskService Reconnecting to {0} tasks...\n', taskLabels), true); for (const task of tasks) { if (ConfiguringTask.is(task)) { const resolved = await this.tryResolveTask(task); @@ -816,7 +817,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!matchingProvider) { if (matchingProviderUnavailable) { - this._outputChannel.append(nls.localize( + this._log(nls.localize( 'TaskService.providerUnavailable', 'Warning: {0} tasks are unavailable in the current environment.\n', configuringTask.configures.type @@ -969,7 +970,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private _getPersistentTasks(): LRUCache { // if (this._persistentTasks) { - // this._outputChannel.append(nls.localize('taskService.gettingCachedTasks', 'Returning cached tasks {0}\n', this._persistentTasks.size)); + // this._log(nls.localize('taskService.gettingCachedTasks', 'Returning cached tasks {0}\n', this._persistentTasks.size)); // return this._persistentTasks; // } //TODO: should this # be configurable? @@ -1006,7 +1007,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const workspaceToTaskMap: Map = new Map(); const storedTasks = this._getTasksFromStorage(type); const tasks: (Task | ConfiguringTask)[] = []; - this._outputChannel.append(nls.localize('taskService.getSavedTasks', '#taskService Fetching tasks from task storage.')); + this._log(nls.localize('taskService.getSavedTasks', '#taskService Fetching tasks from task storage.\n'), true); function addTaskToMap(map: Map, folder: string | undefined, task: any) { if (folder && !map.has(folder)) { map.set(folder, []); @@ -1020,7 +1021,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const key = entry[0]; const task = JSON.parse(entry[1]); const folderInfo = this._getFolderFromTaskKey(key); - this._outputChannel.append(nls.localize('taskService.getSavedTasks.reading', '#taskService Reading tasks from task storage, {0}, {1}, {2}', key, task, folderInfo.folder)); + this._log(nls.localize('taskService.getSavedTasks.reading', '#taskService Reading tasks from task storage, {0}, {1}, {2}\n', key, task, folderInfo.folder), true); addTaskToMap(folderInfo.isWorkspaceFile ? workspaceToTaskMap : folderToTasksMap, folderInfo.folder, task); } @@ -1057,9 +1058,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer for (const key of storedTasks.keys()) { if (readTasksMap.has(key)) { tasks.push(readTasksMap.get(key)!); - this._outputChannel.append(nls.localize('taskService.getSavedTasks.resolved', '#taskService Resolved task {0}', key)); + this._log(nls.localize('taskService.getSavedTasks.resolved', '#taskService Resolved task {0}\n', key, true)); } else { - this._outputChannel.append(nls.localize('taskService.getSavedTasks.unresolved', '#taskService Unable to resolve task {0}', key)); + this._log(nls.localize('taskService.getSavedTasks.unresolved', '#taskService Unable to resolve task {0} \n', key, true)); } } return tasks; @@ -1073,6 +1074,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } public removePersistentTask(key: string) { + this._log(nls.localize('taskService.removePersistentTask', '#taskService Removing persistent task {0}\n', key), true); if (this._getTasksFromStorage('persistent').has(key)) { this._getTasksFromStorage('persistent').delete(key); this._savePersistentTasks(); @@ -1147,6 +1149,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!task.configurationProperties.isBackground) { return; } + this._log(nls.localize('taskService.setPersistentTask', '#taskService Setting persistent task {0}\n', key), true); this._getTasksFromStorage('persistent').set(key, JSON.stringify(customizations)); this._savePersistentTasks(); } @@ -1159,7 +1162,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer for (const key of keys) { keyValues.push([key, persistentTasks.get(key, Touch.None)!]); } - this._outputChannel.append(nls.localize('savePersistentTask', 'Saving persistent tasks: {0}', keyValues.length)); + this._log(nls.localize('savePersistentTask', 'Saving persistent tasks: {0}\n', keys.join(', ')), true); this._storageService.store(AbstractTaskService.PersistentTasks_Key, JSON.stringify(keyValues), StorageScope.WORKSPACE, StorageTarget.MACHINE); } @@ -1713,7 +1716,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }; if (workspaceTasks.length > 0) { if (workspaceTasks.length > 1) { - this._outputChannel.append(nls.localize('moreThanOneBuildTask', 'There are many build tasks defined in the tasks.json. Executing the first one.\n')); + this._log(nls.localize('moreThanOneBuildTask', 'There are many build tasks defined in the tasks.json. Executing the first one.\n')); } return { task: workspaceTasks[0], resolver }; } @@ -2004,12 +2007,10 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const error = (error: any) => { try { if (error && Types.isString(error.message)) { - this._outputChannel.append('Error: '); - this._outputChannel.append(error.message); - this._outputChannel.append('\n'); + this._log(`Error: ${error.message}\n`); this._showOutput(); } else { - this._outputChannel.append('Unknown error received while collecting tasks from providers.\n'); + this._log('Unknown error received while collecting tasks from providers.\n'); this._showOutput(); } } finally { @@ -2032,7 +2033,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer // Check that the tasks provided are of the correct type for (const task of taskSet.tasks) { if (task.type !== this._providerTypes.get(handle)) { - this._outputChannel.append(nls.localize('unexpectedTaskType', "The task provider for \"{0}\" tasks unexpectedly provided a task of type \"{1}\".\n", this._providerTypes.get(handle), task.type)); + this._log(nls.localize('unexpectedTaskType', "The task provider for \"{0}\" tasks unexpectedly provided a task of type \"{1}\".\n", this._providerTypes.get(handle), task.type)); if ((task.type !== 'shell') && (task.type !== 'process')) { this._showOutput(); } @@ -2160,13 +2161,13 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } if (requiredTaskProviderUnavailable) { - this._outputChannel.append(nls.localize( + this._log(nls.localize( 'TaskService.providerUnavailable', 'Warning: {0} tasks are unavailable in the current environment.\n', configuringTask.configures.type )); } else { - this._outputChannel.append(nls.localize( + this._log(nls.localize( 'TaskService.noConfiguration', 'Error: The {0} task detection didn\'t contribute a task for the following configuration:\n{1}\nThe task will be ignored.\n', configuringTask.configures.type, @@ -2338,7 +2339,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } } if (isAffected) { - this._outputChannel.append(nls.localize({ key: 'TaskSystem.invalidTaskJsonOther', comment: ['Message notifies of an error in one of several places there is tasks related json, not necessarily in a file named tasks.json'] }, 'Error: The content of the tasks json in {0} has syntax errors. Please correct them before executing a task.\n', location)); + this._log(nls.localize({ key: 'TaskSystem.invalidTaskJsonOther', comment: ['Message notifies of an error in one of several places there is tasks related json, not necessarily in a file named tasks.json'] }, 'Error: The content of the tasks json in {0} has syntax errors. Please correct them before executing a task.\n', location)); this._showOutput(); return { config, hasParseErrors: true }; } @@ -2346,6 +2347,12 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return { config, hasParseErrors: false }; } + private _log(value: string, verbose?: boolean): void { + if (!verbose || verbose && this._configurationService.getValue(TaskSettingId.VerboseLogging)) { + this._outputChannel.append(value); + } + } + private async _computeWorkspaceFileTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise { if (this._executionEngine === ExecutionEngine.Process) { return this._emptyWorkspaceTaskResults(workspaceFolder); @@ -2457,7 +2464,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer workspaceFolders.push(workspaceFolder); } else { ignoredWorkspaceFolders.push(workspaceFolder); - this._outputChannel.append(nls.localize( + this._log(nls.localize( 'taskService.ignoreingFolder', 'Ignoring task configurations for workspace folder {0}. Multi folder workspace task support requires that all folders use task version 2.0.0\n', workspaceFolder.uri.fsPath)); @@ -2520,7 +2527,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } } if (isAffected) { - this._outputChannel.append(nls.localize('TaskSystem.invalidTaskJson', 'Error: The content of the tasks.json file has syntax errors. Please correct them before executing a task.\n')); + this._log(nls.localize('TaskSystem.invalidTaskJson', 'Error: The content of the tasks.json file has syntax errors. Please correct them before executing a task.\n')); this._showOutput(); return { config: undefined, hasParseErrors: true }; } diff --git a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts index f4388813f7c..764209f2d01 100644 --- a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts +++ b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts @@ -553,5 +553,10 @@ configurationRegistry.registerConfiguration({ ], default: 'always', }, + [TaskSettingId.VerboseLogging]: { + type: 'boolean', + description: nls.localize('task.verboseLogging', "Enable verbose logging for tasks."), + default: false + }, } }); diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index fded77d7f8d..88da77f9181 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -1266,7 +1266,8 @@ export const enum TaskSettingId { QuickOpenSkip = 'task.quickOpen.skip', QuickOpenShowAll = 'task.quickOpen.showAll', AllowAutomaticTasks = 'task.allowAutomaticTasks', - Reconnection = 'task.reconnection' + Reconnection = 'task.reconnection', + VerboseLogging = 'task.verboseLogging' } export const enum TasksSchemaProperties { From fb49a38f104fbc6b80a04f1cf11b4894b2fa736a Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 3 Nov 2023 12:53:53 -0700 Subject: [PATCH 011/240] change name, more --- .../tasks/browser/abstractTaskService.ts | 88 ++++++++++--------- .../contrib/tasks/browser/taskQuickPick.ts | 6 +- .../contrib/tasks/browser/tasksQuickAccess.ts | 2 +- .../tasks/browser/terminalTaskSystem.ts | 8 +- .../workbench/contrib/tasks/common/tasks.ts | 13 +-- 5 files changed, 62 insertions(+), 55 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index c322650a4dd..7da5ec04957 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -218,6 +218,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer protected _taskRunningState: IContextKey; + private _persistentTasks: LRUCache | undefined; + protected _outputChannel: IOutputChannel; protected readonly _onDidStateChange: Emitter; private _waitForAllSupportedExecutions: Promise; @@ -334,11 +336,14 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._willRestart = e.reason !== ShutdownReason.RELOAD; }); this._register(this.onDidStateChange(e => { - this._logService.debug('Task Event kind: ', e.kind); + this._log(nls.localize('taskEvent', 'Task Event kind: {0}', e.kind), true); if (e.kind === TaskEventKind.Changed) { // no-op } else if ((this._willRestart || (e.kind === TaskEventKind.Terminated && e.exitReason === TerminalExitReason.User)) && e.taskId) { - this.removePersistentTask(e.taskId); + const key = e.__task.getKey(); + if (key) { + this.removePersistentTask(key); + } } else if (e.kind === TaskEventKind.Start && e.__task && e.__task.getWorkspaceFolder()) { this._setPersistentTask(e.__task); } @@ -385,19 +390,19 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private _attemptTaskReconnection(): void { if (this._lifecycleService.startupKind !== StartupKind.ReloadedWindow) { - this._log(nls.localize('TaskService.skippingReconnection', '#taskService startup kind not window reload, setting connected and removing persistent tasks\n'), true); + this._log(nls.localize('TaskService.skippingReconnection', 'Startup kind not window reload, setting connected and removing persistent tasks'), true); this._tasksReconnected = true; this._storageService.remove(AbstractTaskService.PersistentTasks_Key, StorageScope.WORKSPACE); } if (!this._configurationService.getValue(TaskSettingId.Reconnection) || this._tasksReconnected) { - this._log(nls.localize('TaskService.notConnecting', '#taskService Setting tasks connected configured value {0}, tasks were already reconnected {1}\n', this._configurationService.getValue(TaskSettingId.Reconnection), this._tasksReconnected), true); + this._log(nls.localize('TaskService.notConnecting', 'Setting tasks connected configured value {0}, tasks were already reconnected {1}', this._configurationService.getValue(TaskSettingId.Reconnection), this._tasksReconnected), true); this._tasksReconnected = true; return; } - this._log(nls.localize('TaskService.reconnecting', '#taskService Reconnecting to running tasks...\n'), true); + this._log(nls.localize('TaskService.reconnecting', 'Reconnecting to running tasks...'), true); this.getWorkspaceTasks(TaskRunSource.Reconnect).then(async () => { this._tasksReconnected = await this._reconnectTasks(); - this._log(nls.localize('TaskService.reconnected', '#taskService Reconnected to running tasks.\n'), true); + this._log(nls.localize('TaskService.reconnected', 'Reconnected to running tasks.'), true); this._onDidReconnectToTasks.fire(); }); } @@ -405,11 +410,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private async _reconnectTasks(): Promise { const tasks = await this.getSavedTasks('persistent'); if (!tasks.length) { - this._log(nls.localize('TaskService.noTasks', '#taskService No persistent tasks to reconnect.\n'), true); + this._log(nls.localize('TaskService.noTasks', 'No persistent tasks to reconnect.'), true); return true; } const taskLabels = tasks.map(task => task._label).join(', '); - this._log(nls.localize('TaskService.reconnectingTasks', '#taskService Reconnecting to {0} tasks...\n', taskLabels), true); + this._log(nls.localize('TaskService.reconnectingTasks', 'Reconnecting to {0} tasks...', taskLabels), true); for (const task of tasks) { if (ConfiguringTask.is(task)) { const resolved = await this.tryResolveTask(task); @@ -819,7 +824,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (matchingProviderUnavailable) { this._log(nls.localize( 'TaskService.providerUnavailable', - 'Warning: {0} tasks are unavailable in the current environment.\n', + 'Warning: {0} tasks are unavailable in the current environment.', configuringTask.configures.type )); } @@ -969,26 +974,25 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private _getPersistentTasks(): LRUCache { - // if (this._persistentTasks) { - // this._log(nls.localize('taskService.gettingCachedTasks', 'Returning cached tasks {0}\n', this._persistentTasks.size)); - // return this._persistentTasks; - // } - //TODO: should this # be configurable? - const persistentTasks = new LRUCache(10); + if (this._persistentTasks) { + this._log(nls.localize('taskService.gettingCachedTasks', 'Returning cached tasks {0}', this._persistentTasks.size), true); + return this._persistentTasks; + } + this._persistentTasks = new LRUCache(10); const storageValue = this._storageService.get(AbstractTaskService.PersistentTasks_Key, StorageScope.WORKSPACE); if (storageValue) { try { const values: [string, string][] = JSON.parse(storageValue); if (Array.isArray(values)) { for (const value of values) { - persistentTasks.set(value[0], value[1]); + this._persistentTasks.set(value[0], value[1]); } } } catch (error) { // Ignore. We use the empty result } } - return persistentTasks; + return this._persistentTasks; } private _getFolderFromTaskKey(key: string): { folder: string | undefined; isWorkspaceFile: boolean | undefined } { @@ -1007,7 +1011,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const workspaceToTaskMap: Map = new Map(); const storedTasks = this._getTasksFromStorage(type); const tasks: (Task | ConfiguringTask)[] = []; - this._log(nls.localize('taskService.getSavedTasks', '#taskService Fetching tasks from task storage.\n'), true); + this._log(nls.localize('taskService.getSavedTasks', 'Fetching tasks from task storage.'), true); function addTaskToMap(map: Map, folder: string | undefined, task: any) { if (folder && !map.has(folder)) { map.set(folder, []); @@ -1021,7 +1025,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const key = entry[0]; const task = JSON.parse(entry[1]); const folderInfo = this._getFolderFromTaskKey(key); - this._log(nls.localize('taskService.getSavedTasks.reading', '#taskService Reading tasks from task storage, {0}, {1}, {2}\n', key, task, folderInfo.folder), true); + this._log(nls.localize('taskService.getSavedTasks.reading', 'Reading tasks from task storage, {0}, {1}, {2}', key, task, folderInfo.folder), true); addTaskToMap(folderInfo.isWorkspaceFile ? workspaceToTaskMap : folderToTasksMap, folderInfo.folder, task); } @@ -1040,13 +1044,13 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer tasks: map.get(key) }, TaskRunSource.System, custom, customized, taskConfigSource, true); custom.forEach(task => { - const taskKey = task.getRecentlyUsedKey(); + const taskKey = task.getKey(); if (taskKey) { readTasksMap.set(taskKey, task); } }); for (const configuration in customized) { - const taskKey = customized[configuration].getRecentlyUsedKey(); + const taskKey = customized[configuration].getKey(); if (taskKey) { readTasksMap.set(taskKey, customized[configuration]); } @@ -1058,9 +1062,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer for (const key of storedTasks.keys()) { if (readTasksMap.has(key)) { tasks.push(readTasksMap.get(key)!); - this._log(nls.localize('taskService.getSavedTasks.resolved', '#taskService Resolved task {0}\n', key, true)); + this._log(nls.localize('taskService.getSavedTasks.resolved', 'Resolved task {0}', key), true); } else { - this._log(nls.localize('taskService.getSavedTasks.unresolved', '#taskService Unable to resolve task {0} \n', key, true)); + this._log(nls.localize('taskService.getSavedTasks.unresolved', 'Unable to resolve task {0} ', key), true); } } return tasks; @@ -1074,7 +1078,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } public removePersistentTask(key: string) { - this._log(nls.localize('taskService.removePersistentTask', '#taskService Removing persistent task {0}\n', key), true); + this._log(nls.localize('taskService.removePersistentTask', 'Removing persistent task {0}', key), true); if (this._getTasksFromStorage('persistent').has(key)) { this._getTasksFromStorage('persistent').delete(key); this._savePersistentTasks(); @@ -1089,7 +1093,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private async _setRecentlyUsedTask(task: Task): Promise { - let key = task.getRecentlyUsedKey(); + let key = task.getKey(); if (!InMemoryTask.is(task) && key) { const customizations = this._createCustomizableTask(task); if (ContributedTask.is(task) && customizations) { @@ -1100,7 +1104,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer tasks: [customizations] }, TaskRunSource.System, custom, customized, TaskConfig.TaskConfigSource.TasksJson, true); for (const configuration in customized) { - key = customized[configuration].getRecentlyUsedKey()!; + key = customized[configuration].getKey()!; } } this._getTasksFromStorage('historical').set(key, JSON.stringify(customizations)); @@ -1132,7 +1136,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!this._configurationService.getValue(TaskSettingId.Reconnection)) { return; } - let key = task.getRecentlyUsedKey(); + let key = task.getKey(); if (!InMemoryTask.is(task) && key) { const customizations = this._createCustomizableTask(task); if (ContributedTask.is(task) && customizations) { @@ -1143,26 +1147,26 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer tasks: [customizations] }, TaskRunSource.System, custom, customized, TaskConfig.TaskConfigSource.TasksJson, true); for (const configuration in customized) { - key = customized[configuration].getRecentlyUsedKey()!; + key = customized[configuration].getKey()!; } } if (!task.configurationProperties.isBackground) { return; } - this._log(nls.localize('taskService.setPersistentTask', '#taskService Setting persistent task {0}\n', key), true); + this._log(nls.localize('taskService.setPersistentTask', 'Setting persistent task {0}', key), true); this._getTasksFromStorage('persistent').set(key, JSON.stringify(customizations)); this._savePersistentTasks(); } } private _savePersistentTasks(): void { - const persistentTasks = this._getTasksFromStorage('persistent'); - const keys = [...persistentTasks.keys()]; + this._persistentTasks = this._getTasksFromStorage('persistent'); + const keys = [...this._persistentTasks.keys()]; const keyValues: [string, string][] = []; for (const key of keys) { - keyValues.push([key, persistentTasks.get(key, Touch.None)!]); + keyValues.push([key, this._persistentTasks.get(key, Touch.None)!]); } - this._log(nls.localize('savePersistentTask', 'Saving persistent tasks: {0}\n', keys.join(', ')), true); + this._log(nls.localize('savePersistentTask', 'Saving persistent tasks: {0}', keys.join(', ')), true); this._storageService.store(AbstractTaskService.PersistentTasks_Key, JSON.stringify(keyValues), StorageScope.WORKSPACE, StorageTarget.MACHINE); } @@ -1716,7 +1720,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }; if (workspaceTasks.length > 0) { if (workspaceTasks.length > 1) { - this._log(nls.localize('moreThanOneBuildTask', 'There are many build tasks defined in the tasks.json. Executing the first one.\n')); + this._log(nls.localize('moreThanOneBuildTask', 'There are many build tasks defined in the tasks.json. Executing the first one.')); } return { task: workspaceTasks[0], resolver }; } @@ -2010,7 +2014,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._log(`Error: ${error.message}\n`); this._showOutput(); } else { - this._log('Unknown error received while collecting tasks from providers.\n'); + this._log('Unknown error received while collecting tasks from providers.'); this._showOutput(); } } finally { @@ -2163,13 +2167,13 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (requiredTaskProviderUnavailable) { this._log(nls.localize( 'TaskService.providerUnavailable', - 'Warning: {0} tasks are unavailable in the current environment.\n', + 'Warning: {0} tasks are unavailable in the current environment.', configuringTask.configures.type )); } else { this._log(nls.localize( 'TaskService.noConfiguration', - 'Error: The {0} task detection didn\'t contribute a task for the following configuration:\n{1}\nThe task will be ignored.\n', + 'Error: The {0} task detection didn\'t contribute a task for the following configuration:\n{1}\nThe task will be ignored.', configuringTask.configures.type, JSON.stringify(configuringTask._source.config.element, undefined, 4) )); @@ -2339,7 +2343,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } } if (isAffected) { - this._log(nls.localize({ key: 'TaskSystem.invalidTaskJsonOther', comment: ['Message notifies of an error in one of several places there is tasks related json, not necessarily in a file named tasks.json'] }, 'Error: The content of the tasks json in {0} has syntax errors. Please correct them before executing a task.\n', location)); + this._log(nls.localize({ key: 'TaskSystem.invalidTaskJsonOther', comment: ['Message notifies of an error in one of several places there is tasks related json, not necessarily in a file named tasks.json'] }, 'Error: The content of the tasks json in {0} has syntax errors. Please correct them before executing a task.', location)); this._showOutput(); return { config, hasParseErrors: true }; } @@ -2348,7 +2352,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private _log(value: string, verbose?: boolean): void { - if (!verbose || verbose && this._configurationService.getValue(TaskSettingId.VerboseLogging)) { + if (verbose && this._configurationService.getValue(TaskSettingId.VerboseLogging) || !verbose) { this._outputChannel.append(value); } } @@ -2466,7 +2470,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer ignoredWorkspaceFolders.push(workspaceFolder); this._log(nls.localize( 'taskService.ignoreingFolder', - 'Ignoring task configurations for workspace folder {0}. Multi folder workspace task support requires that all folders use task version 2.0.0\n', + 'Ignoring task configurations for workspace folder {0}. Multi folder workspace task support requires that all folders use task version 2.0.0', workspaceFolder.uri.fsPath)); } } @@ -2527,7 +2531,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } } if (isAffected) { - this._log(nls.localize('TaskSystem.invalidTaskJson', 'Error: The content of the tasks.json file has syntax errors. Please correct them before executing a task.\n')); + this._log(nls.localize('TaskSystem.invalidTaskJson', 'Error: The content of the tasks.json file has syntax errors. Please correct them before executing a task.')); this._showOutput(); return { config: undefined, hasParseErrors: true }; } @@ -2739,7 +2743,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const recentlyUsedTasks = this.getRecentlyUsedTasksV1(); const taskMap: IStringDictionary = Object.create(null); tasks.forEach(task => { - const key = task.getRecentlyUsedKey(); + const key = task.getKey(); if (key) { taskMap[key] = task; } diff --git a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts index 3c15935f60a..6dde509a9d4 100644 --- a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts +++ b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts @@ -149,11 +149,11 @@ export class TaskQuickPick extends Disposable { const definition = configuredTasks[j].getDefinition()?._key; const type = configuredTasks[j].type; const label = configuredTasks[j]._label; - const recentKey = configuredTasks[j].getRecentlyUsedKey(); + const recentKey = configuredTasks[j].getKey(); const findIndex = recentTasks.findIndex((value) => { return (workspaceFolder && definition && value.getWorkspaceFolder()?.uri.toString() === workspaceFolder && ((value.getDefinition()?._key === definition) || (value.type === type && value._label === label))) - || (recentKey && value.getRecentlyUsedKey() === recentKey); + || (recentKey && value.getKey() === recentKey); }); if (findIndex === -1) { dedupedConfiguredTasks.push(configuredTasks[j]); @@ -231,7 +231,7 @@ export class TaskQuickPick extends Disposable { picker.onDidTriggerItemButton(async (context) => { const task = context.item.task; if (context.button.iconClass === ThemeIcon.asClassName(removeTaskIcon)) { - const key = (task && !Types.isString(task)) ? task.getRecentlyUsedKey() : undefined; + const key = (task && !Types.isString(task)) ? task.getKey() : undefined; if (key) { this._taskService.removeRecentlyUsedTask(key); } diff --git a/src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.ts b/src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.ts index dd605f15b54..51e6ae001b0 100644 --- a/src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.ts +++ b/src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.ts @@ -65,7 +65,7 @@ export class TasksQuickAccessProvider extends PickerQuickAccessProvider { if ((index === 1) && (quickAccessEntry.buttons?.length === 2)) { - const key = (task && !isString(task)) ? task.getRecentlyUsedKey() : undefined; + const key = (task && !isString(task)) ? task.getKey() : undefined; if (key) { this._taskService.removeRecentlyUsedTask(key); } diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index dd2d581c170..20b6a6c35e5 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -386,9 +386,9 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { } public getLastInstance(task: Task): Task | undefined { - const recentKey = task.getRecentlyUsedKey(); + const recentKey = task.getKey(); return Object.values(this._activeTasks).reverse().find( - (value) => recentKey && recentKey === value.task.getRecentlyUsedKey())?.task; + (value) => recentKey && recentKey === value.task.getKey())?.task; } public getBusyTasks(): Task[] { @@ -408,9 +408,9 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { } private _getInstances(task: Task): IActiveTerminalData[] { - const recentKey = task.getRecentlyUsedKey(); + const recentKey = task.getKey(); return Object.values(this._activeTasks).filter( - (value) => recentKey && recentKey === value.task.getRecentlyUsedKey()); + (value) => recentKey && recentKey === value.task.getKey()); } private _removeFromActiveTasks(task: Task | string): void { diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index 88da77f9181..b7884faa838 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -617,7 +617,7 @@ export abstract class CommonTask { return this._id; } - public getRecentlyUsedKey(): string | undefined { + public getKey(): string | undefined { return undefined; } @@ -788,10 +788,13 @@ export class CustomTask extends CommonTask { } public override getCommonTaskId(): string { - return this._source.customizes ? super.getCommonTaskId() : (this.getRecentlyUsedKey() ?? super.getCommonTaskId()); + return this._source.customizes ? super.getCommonTaskId() : (this.getKey() ?? super.getCommonTaskId()); } - public override getRecentlyUsedKey(): string | undefined { + /** + * @returns A key representing the task + */ + public override getKey(): string | undefined { interface ICustomKey { type: string; folder: string; @@ -875,7 +878,7 @@ export class ConfiguringTask extends CommonTask { return this._source.kind === TaskSourceKind.User ? USER_TASKS_GROUP_KEY : this._source.config.workspaceFolder?.uri.toString(); } - public override getRecentlyUsedKey(): string | undefined { + public override getKey(): string | undefined { interface ICustomKey { type: string; folder: string; @@ -963,7 +966,7 @@ export class ContributedTask extends CommonTask { return undefined; } - public override getRecentlyUsedKey(): string | undefined { + public override getKey(): string | undefined { interface IContributedKey { type: string; scope: number; From 07d41544090de1bdb054759fc65693aeac7be8bd Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 3 Nov 2023 12:58:01 -0700 Subject: [PATCH 012/240] fix some things --- .../contrib/tasks/browser/abstractTaskService.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 7da5ec04957..6d3af6885d1 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -216,10 +216,10 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private _recentlyUsedTasksV1: LRUCache | undefined; private _recentlyUsedTasks: LRUCache | undefined; - protected _taskRunningState: IContextKey; - private _persistentTasks: LRUCache | undefined; + protected _taskRunningState: IContextKey; + protected _outputChannel: IOutputChannel; protected readonly _onDidStateChange: Emitter; private _waitForAllSupportedExecutions: Promise; @@ -299,6 +299,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (e.affectsConfiguration(TaskSettingId.Reconnection)) { if (!this._configurationService.getValue(TaskSettingId.Reconnection)) { + this._persistentTasks?.clear(); this._storageService.remove(AbstractTaskService.PersistentTasks_Key, StorageScope.WORKSPACE); } } @@ -978,6 +979,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._log(nls.localize('taskService.gettingCachedTasks', 'Returning cached tasks {0}', this._persistentTasks.size), true); return this._persistentTasks; } + //TODO: should this # be configurable? this._persistentTasks = new LRUCache(10); const storageValue = this._storageService.get(AbstractTaskService.PersistentTasks_Key, StorageScope.WORKSPACE); if (storageValue) { @@ -1020,7 +1022,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer map.get(folder).push(task); } } - for (const entry of storedTasks.entries()) { const key = entry[0]; const task = JSON.parse(entry[1]); @@ -2353,7 +2354,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private _log(value: string, verbose?: boolean): void { if (verbose && this._configurationService.getValue(TaskSettingId.VerboseLogging) || !verbose) { - this._outputChannel.append(value); + this._outputChannel.append(value + '\n'); } } From b9007fd69884b63f4404ddc0798d2530df2ee745 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Fri, 3 Nov 2023 13:35:03 -0700 Subject: [PATCH 013/240] Update src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 6d3af6885d1..d4f7debf897 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -2353,7 +2353,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private _log(value: string, verbose?: boolean): void { - if (verbose && this._configurationService.getValue(TaskSettingId.VerboseLogging) || !verbose) { + if (!verbose || this._configurationService.getValue(TaskSettingId.VerboseLogging)) { this._outputChannel.append(value + '\n'); } } From 14678c041fe5e50185410592efcc4414e58c2ac3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 6 Nov 2023 08:21:36 +0100 Subject: [PATCH 014/240] eng - ensure `node` for remote smoke tests (#197509) end - ensure `node` for remote smoke tests --- build/azure-pipelines/linux/product-build-linux-test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/azure-pipelines/linux/product-build-linux-test.yml b/build/azure-pipelines/linux/product-build-linux-test.yml index bb75be37e4b..74ebb91e344 100644 --- a/build/azure-pipelines/linux/product-build-linux-test.yml +++ b/build/azure-pipelines/linux/product-build-linux-test.yml @@ -151,6 +151,10 @@ steps: - script: yarn gulp compile-extension:markdown-language-features compile-extension-media compile-extension:vscode-test-resolver displayName: Build extensions for smoke tests + - script: yarn gulp node + displayName: Download node.js for remote smoke tests + retryCountOnTaskFailure: 3 + - script: yarn smoketest-no-compile --tracing timeoutInMinutes: 20 displayName: Run smoke tests (Electron) From 6454416d2957b7c4e49dbd8a7099e9d3f4880f48 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 6 Nov 2023 08:22:33 +0100 Subject: [PATCH 015/240] aux window - some polish (#197510) - seed the aux window ID based on the main one - avoid using non-main windows for `getActiveWindowId` --- src/vs/base/browser/dom.ts | 2 +- src/vs/platform/native/electron-main/nativeHostMainService.ts | 2 +- .../auxiliaryWindow/browser/auxiliaryWindowService.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index e39ade1ff36..0d6a8f3709b 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -33,7 +33,7 @@ export const { registerWindow, getWindows, getWindowsCount, getWindowId, onDidRe const mainWindow = window as CodeWindow; if (typeof mainWindow.vscodeWindowId !== 'number') { Object.defineProperty(window, 'vscodeWindowId', { - get: () => -1 + get: () => 1 }); } windows.set(mainWindow.vscodeWindowId, { window: mainWindow, disposables: new DisposableStore() }); diff --git a/src/vs/platform/native/electron-main/nativeHostMainService.ts b/src/vs/platform/native/electron-main/nativeHostMainService.ts index 1cd821a33af..29132727162 100644 --- a/src/vs/platform/native/electron-main/nativeHostMainService.ts +++ b/src/vs/platform/native/electron-main/nativeHostMainService.ts @@ -150,7 +150,7 @@ export class NativeHostMainService extends Disposable implements INativeHostMain } async getActiveWindowId(windowId: number | undefined): Promise { - const activeWindow = BrowserWindow.getFocusedWindow() || this.windowsMainService.getLastActiveWindow(); + const activeWindow = this.windowsMainService.getFocusedWindow() || this.windowsMainService.getLastActiveWindow(); if (activeWindow) { return activeWindow.id; } diff --git a/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts b/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts index 67d0d81e1bf..ecf390dda1b 100644 --- a/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts +++ b/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts @@ -6,7 +6,7 @@ import { localize } from 'vs/nls'; import { mark } from 'vs/base/common/performance'; import { Emitter, Event } from 'vs/base/common/event'; -import { CodeWindow, Dimension, EventHelper, EventType, addDisposableListener, cloneGlobalStylesheets, copyAttributes, createMetaElement, getActiveWindow, getClientArea, isGlobalStylesheet, position, registerWindow, sharedMutationObserver, size, trackAttributes } from 'vs/base/browser/dom'; +import { CodeWindow, Dimension, EventHelper, EventType, addDisposableListener, cloneGlobalStylesheets, copyAttributes, createMetaElement, getActiveWindow, getClientArea, getWindowId, isGlobalStylesheet, position, registerWindow, sharedMutationObserver, size, trackAttributes } from 'vs/base/browser/dom'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; @@ -62,7 +62,7 @@ export class BrowserAuxiliaryWindowService extends Disposable implements IAuxili private static readonly DEFAULT_SIZE = { width: 800, height: 600 }; - private static WINDOW_IDS = 0; + private static WINDOW_IDS = getWindowId(window) + 1; // start from the main window ID + 1 private readonly _onDidOpenAuxiliaryWindow = this._register(new Emitter()); readonly onDidOpenAuxiliaryWindow = this._onDidOpenAuxiliaryWindow.event; From 25ba16e724f9398a98b0e3656d8997565939fbef Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 6 Nov 2023 08:23:59 +0100 Subject: [PATCH 016/240] vscode://file// links no longer working (fix #197319) (#197511) --- src/vs/base/common/labels.ts | 6 +- src/vs/base/test/common/labels.test.ts | 2 + src/vs/code/electron-main/app.ts | 78 +++++++++++++++----------- 3 files changed, 50 insertions(+), 36 deletions(-) diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts index 707ed621b22..1229b7f59e8 100644 --- a/src/vs/base/common/labels.ts +++ b/src/vs/base/common/labels.ts @@ -80,10 +80,10 @@ export function getPathLabel(resource: URI, formatting: IPathLabelFormatting): s // to a user home resource. We cannot assume that the resource is // already a user home resource. let userHomeCandidate: string; - if (resource.scheme !== tildifier.userHome.scheme && resource.path.startsWith(posix.sep)) { + if (resource.scheme !== tildifier.userHome.scheme && resource.path[0] === posix.sep && resource.path[1] !== posix.sep) { userHomeCandidate = tildifier.userHome.with({ path: resource.path }).fsPath; } else { - userHomeCandidate = resource.fsPath; + userHomeCandidate = absolutePath; } absolutePath = tildify(userHomeCandidate, userHome, os); @@ -108,7 +108,7 @@ function getRelativePathLabel(resource: URI, relativePathProvider: IRelativePath // the resource belongs to, we need to make sure to convert it // to a workspace resource. We cannot assume that the resource is // already matching the workspace. - if (resource.scheme !== firstFolder.uri.scheme && resource.path.startsWith(posix.sep)) { + if (resource.scheme !== firstFolder.uri.scheme && resource.path[0] === posix.sep && resource.path[1] !== posix.sep) { resource = firstFolder.uri.with({ path: resource.path }); } diff --git a/src/vs/base/test/common/labels.test.ts b/src/vs/base/test/common/labels.test.ts index 8928b09c72d..6c9d3eb0f11 100644 --- a/src/vs/base/test/common/labels.test.ts +++ b/src/vs/base/test/common/labels.test.ts @@ -162,6 +162,7 @@ suite('Labels', () => { test('getPathLabel', () => { const winFileUri = URI.file('c:/some/folder/file.txt'); const nixFileUri = URI.file('/some/folder/file.txt'); + const nixBadFileUri = URI.revive({ scheme: 'vscode', authority: 'file', path: '//some/folder/file.txt' }); const uncFileUri = URI.file('c:/some/folder/file.txt').with({ authority: 'auth' }); const remoteFileUri = URI.file('/some/folder/file.txt').with({ scheme: 'vscode-test', authority: 'auth' }); @@ -190,6 +191,7 @@ suite('Labels', () => { assert.strictEqual(labels.getPathLabel(nixFileUri, { os: OperatingSystem.Windows, tildify: { userHome: nixUserHome } }), '\\some\\folder\\file.txt'); assert.strictEqual(labels.getPathLabel(nixFileUri, { os: OperatingSystem.Macintosh, tildify: { userHome: nixUserHome } }), '~/folder/file.txt'); + assert.strictEqual(labels.getPathLabel(nixBadFileUri, { os: OperatingSystem.Macintosh, tildify: { userHome: nixUserHome } }), '/some/folder/file.txt'); assert.strictEqual(labels.getPathLabel(nixFileUri, { os: OperatingSystem.Linux, tildify: { userHome: nixUserHome } }), '~/folder/file.txt'); assert.strictEqual(labels.getPathLabel(nixFileUri, { os: OperatingSystem.Windows, tildify: { userHome: remoteUserHome } }), '\\some\\folder\\file.txt'); diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 192447bb600..cb641c7a08b 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -84,7 +84,7 @@ import { NativeURLService } from 'vs/platform/url/common/urlService'; import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener'; import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService'; import { WebviewMainService } from 'vs/platform/webview/electron-main/webviewMainService'; -import { IWindowOpenable } from 'vs/platform/window/common/window'; +import { isFolderToOpen, isWorkspaceToOpen, IWindowOpenable } from 'vs/platform/window/common/window'; import { IWindowsMainService, OpenContext } from 'vs/platform/windows/electron-main/windows'; import { ICodeWindow } from 'vs/platform/window/electron-main/window'; import { WindowsMainService } from 'vs/platform/windows/electron-main/windowsMainService'; @@ -727,17 +727,17 @@ export class CodeApplication extends Disposable { continue; // invalid } - if (await this.shouldBlockURI(protocolUrl.uri, windowsMainService, dialogMainService)) { - this.logService.trace('app#resolveInitialProtocolUrls() protocol url was blocked:', protocolUrl.uri.toString(true)); - - continue; // blocked - } - const windowOpenable = this.getWindowOpenableFromProtocolUrl(protocolUrl.uri); if (windowOpenable) { - this.logService.trace('app#resolveInitialProtocolUrls() protocol url will be handled as window to open:', protocolUrl.uri.toString(true), windowOpenable); + if (await this.shouldBlockOpenable(windowOpenable, windowsMainService, dialogMainService)) { + this.logService.trace('app#resolveInitialProtocolUrls() protocol url was blocked:', protocolUrl.uri.toString(true)); - openables.push(windowOpenable); // handled as window to open + continue; // blocked + } else { + this.logService.trace('app#resolveInitialProtocolUrls() protocol url will be handled as window to open:', protocolUrl.uri.toString(true), windowOpenable); + + openables.push(windowOpenable); // handled as window to open + } } else { this.logService.trace('app#resolveInitialProtocolUrls() protocol url will be passed to active window for handling:', protocolUrl.uri.toString(true)); @@ -748,8 +748,21 @@ export class CodeApplication extends Disposable { return { urls, openables }; } - private async shouldBlockURI(uri: URI, windowsMainService: IWindowsMainService, dialogMainService: IDialogMainService): Promise { - if (uri.authority !== Schemas.file && uri.authority !== Schemas.vscodeRemote) { + private async shouldBlockOpenable(openable: IWindowOpenable, windowsMainService: IWindowsMainService, dialogMainService: IDialogMainService): Promise { + let openableUri: URI; + let message: string; + if (isWorkspaceToOpen(openable)) { + openableUri = openable.workspaceUri; + message = localize('confirmOpenMessageWorkspace', "An external application wants to open '{0}' in {1}. Do you want to open this workspace file?", openableUri.scheme === Schemas.file ? getPathLabel(openableUri, { os: OS, tildify: this.environmentMainService }) : openableUri.toString(true), this.productService.nameShort); + } else if (isFolderToOpen(openable)) { + openableUri = openable.folderUri; + message = localize('confirmOpenMessageFolder', "An external application wants to open '{0}' in {1}. Do you want to open this folder?", openableUri.scheme === Schemas.file ? getPathLabel(openableUri, { os: OS, tildify: this.environmentMainService }) : openableUri.toString(true), this.productService.nameShort); + } else { + openableUri = openable.fileUri; + message = localize('confirmOpenMessageFileOrFolder', "An external application wants to open '{0}' in {1}. Do you want to open this file or folder?", openableUri.scheme === Schemas.file ? getPathLabel(openableUri, { os: OS, tildify: this.environmentMainService }) : openableUri.toString(true), this.productService.nameShort); + } + + if (openableUri.scheme !== Schemas.file && openableUri.scheme !== Schemas.vscodeRemote) { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // @@ -765,7 +778,7 @@ export class CodeApplication extends Disposable { return false; } - const askForConfirmation = this.configurationService.getValue(CodeApplication.SECURITY_PROTOCOL_HANDLING_CONFIRMATION_SETTING_KEY[uri.authority]); + const askForConfirmation = this.configurationService.getValue(CodeApplication.SECURITY_PROTOCOL_HANDLING_CONFIRMATION_SETTING_KEY[openableUri.scheme]); if (askForConfirmation === false) { return false; // not blocked via settings } @@ -776,9 +789,9 @@ export class CodeApplication extends Disposable { localize({ key: 'open', comment: ['&& denotes a mnemonic'] }, "&&Yes"), localize({ key: 'cancel', comment: ['&& denotes a mnemonic'] }, "&&No") ], - message: localize('confirmOpenMessage', "An external application wants to open '{0}' in {1}. Do you want to open this file or folder?", uri.authority === Schemas.file ? getPathLabel(uri, { os: OS, tildify: this.environmentMainService }) : uri.toString(true), this.productService.nameShort), + message, detail: localize('confirmOpenDetail', "If you did not initiate this request, it may represent an attempted attack on your system. Unless you took an explicit action to initiate this request, you should press 'No'"), - checkboxLabel: uri.authority === Schemas.file ? localize('doNotAskAgainLocal', "Allow opening local paths without asking") : localize('doNotAskAgainRemote', "Allow opening remote paths without asking"), + checkboxLabel: openableUri.scheme === Schemas.file ? localize('doNotAskAgainLocal', "Allow opening local paths without asking") : localize('doNotAskAgainRemote', "Allow opening remote paths without asking"), cancelId: 1 }); @@ -791,7 +804,7 @@ export class CodeApplication extends Disposable { // update settings from within a window. But we do not know if a window // is about to open or can already handle the request, so we have to send // to any current window and any newly opening window. - const request = { channel: 'vscode:disablePromptForProtocolHandling', args: uri.authority === Schemas.file ? 'local' : 'remote' }; + const request = { channel: 'vscode:disablePromptForProtocolHandling', args: openableUri.scheme === Schemas.file ? 'local' : 'remote' }; windowsMainService.sendToFocused(request.channel, request.args); windowsMainService.sendToOpeningWindow(request.channel, request.args); } @@ -866,13 +879,6 @@ export class CodeApplication extends Disposable { }); } - // If URI should be blocked, behave as if it's handled - if (await this.shouldBlockURI(uri, windowsMainService, dialogMainService)) { - this.logService.trace('app#handleProtocolUrl() protocol url was blocked:', uri.toString(true)); - - return true; - } - let shouldOpenInNewWindow = false; // We should handle the URI in a new window if the URL contains `windowId=_blank` @@ -907,20 +913,26 @@ export class CodeApplication extends Disposable { // Check if the protocol URL is a window openable to open... const windowOpenableFromProtocolUrl = this.getWindowOpenableFromProtocolUrl(uri); if (windowOpenableFromProtocolUrl) { - this.logService.trace('app#handleProtocolUrl() opening protocol url as window:', windowOpenableFromProtocolUrl, uri.toString(true)); + if (await this.shouldBlockOpenable(windowOpenableFromProtocolUrl, windowsMainService, dialogMainService)) { + this.logService.trace('app#handleProtocolUrl() protocol url was blocked:', uri.toString(true)); - const window = firstOrDefault(await windowsMainService.open({ - context: OpenContext.API, - cli: { ...this.environmentMainService.args }, - urisToOpen: [windowOpenableFromProtocolUrl], - forceNewWindow: shouldOpenInNewWindow, - gotoLineMode: true - // remoteAuthority: will be determined based on windowOpenableFromProtocolUrl - })); + return true; // If openable should be blocked, behave as if it's handled + } else { + this.logService.trace('app#handleProtocolUrl() opening protocol url as window:', windowOpenableFromProtocolUrl, uri.toString(true)); - window?.focus(); // this should help ensuring that the right window gets focus when multiple are opened + const window = firstOrDefault(await windowsMainService.open({ + context: OpenContext.API, + cli: { ...this.environmentMainService.args }, + urisToOpen: [windowOpenableFromProtocolUrl], + forceNewWindow: shouldOpenInNewWindow, + gotoLineMode: true + // remoteAuthority: will be determined based on windowOpenableFromProtocolUrl + })); - return true; + window?.focus(); // this should help ensuring that the right window gets focus when multiple are opened + + return true; + } } // ...or if we should open in a new window and then handle it within that window From 33f712ff8245340d4ebc8d26239ba81392be21d1 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 6 Nov 2023 11:07:50 +0100 Subject: [PATCH 017/240] State `SaveStrategy.IMMEDIATE` is risky (fix #197372) (#197373) --- src/vs/platform/state/node/stateService.ts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/vs/platform/state/node/stateService.ts b/src/vs/platform/state/node/stateService.ts index debf184e7d4..46dd2baa43e 100644 --- a/src/vs/platform/state/node/stateService.ts +++ b/src/vs/platform/state/node/stateService.ts @@ -25,20 +25,18 @@ export class FileStorage extends Disposable { private storage: StorageDatabase = Object.create(null); private lastSavedStorageContents = ''; - private readonly flushDelayer: ThrottledDelayer | undefined; + private readonly flushDelayer = this._register(new ThrottledDelayer(this.saveStrategy === SaveStrategy.IMMEDIATE ? 0 : 100 /* buffer saves over a short time */)); private initializing: Promise | undefined = undefined; private closing: Promise | undefined = undefined; constructor( private readonly storagePath: URI, - saveStrategy: SaveStrategy, + private readonly saveStrategy: SaveStrategy, private readonly logService: ILogService, private readonly fileService: IFileService, ) { super(); - - this.flushDelayer = saveStrategy === SaveStrategy.IMMEDIATE ? undefined : this._register(new ThrottledDelayer(100 /* buffer saves over a short time */)); } init(): Promise { @@ -119,11 +117,7 @@ export class FileStorage extends Disposable { return; // already about to close } - if (this.flushDelayer) { - return this.flushDelayer.trigger(() => this.doSave()); - } - - return this.doSave(); + return this.flushDelayer.trigger(() => this.doSave()); } private async doSave(): Promise { @@ -151,9 +145,7 @@ export class FileStorage extends Disposable { async close(): Promise { if (!this.closing) { - this.closing = this.flushDelayer - ? this.flushDelayer.trigger(() => this.doSave(), 0 /* as soon as possible */) - : this.doSave(); + this.closing = this.flushDelayer.trigger(() => this.doSave(), 0 /* as soon as possible */); } return this.closing; From 0a292ccaae288beb6a02aa9b4d8f53b5ebe04567 Mon Sep 17 00:00:00 2001 From: tisilent Date: Mon, 6 Nov 2023 18:17:37 +0800 Subject: [PATCH 018/240] Delete hide assignment in _adoptConfiguration* --- .../workbench/contrib/tasks/browser/terminalTaskSystem.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index dd2d581c170..d3b7b34aa1c 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -588,12 +588,6 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { } else { dependencyTask.configurationProperties.icon = task.configurationProperties.icon; } - - if (dependencyTask.configurationProperties.hide) { - dependencyTask.configurationProperties.hide ||= task.configurationProperties.hide; - } else { - dependencyTask.configurationProperties.hide = task.configurationProperties.hide; - } } private async _getDependencyPromise(task: IActiveTerminalData): Promise { From 96025e70158b544a1d21667ee349aec9fd21a8f6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 6 Nov 2023 11:59:34 +0100 Subject: [PATCH 019/240] Don't dispose diff zone widgets when hiding them. (#197525) fixes https://github.com/microsoft/vscode-copilot/issues/2617 fixes https://github.com/microsoft/vscode-copilot/issues/2627 --- .../workbench/contrib/inlineChat/browser/inlineChatStrategies.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts index 41271d9c977..77b8e300def 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts @@ -421,7 +421,6 @@ export class LivePreviewStrategy extends LiveStrategy { if (!diff || diff.changes.length === 0) { for (const zone of this._diffZonePool) { zone.hide(); - zone.dispose(); } return; } From 912c2d98e3540477ef4040b8d0c8c2ed18c39dad Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 6 Nov 2023 12:00:24 +0100 Subject: [PATCH 020/240] aux window - ensure native host service is properly typed in all contexts (#197527) --- build/lib/layersChecker.js | 12 +++++++++++- build/lib/layersChecker.ts | 11 +++++++++++ .../code/electron-sandbox/issue/issueReporterMain.ts | 2 +- .../processExplorer/processExplorerMain.ts | 2 +- src/vs/code/node/sharedProcess/sharedProcessMain.ts | 3 ++- .../nativeHostService.ts | 0 .../host/electron-sandbox/nativeHostService.ts | 2 +- 7 files changed, 27 insertions(+), 5 deletions(-) rename src/vs/platform/native/{electron-sandbox => common}/nativeHostService.ts (100%) diff --git a/build/lib/layersChecker.js b/build/lib/layersChecker.js index 4dfa1b44d4b..485e2fc7d07 100644 --- a/build/lib/layersChecker.js +++ b/build/lib/layersChecker.js @@ -125,6 +125,16 @@ const RULES = [ '@types/node' // no node.js ] }, + // Common: vs/platform/native/common/nativeHostService.ts + { + target: '**/vs/platform/native/common/nativeHostService.ts', + allowedTypes: CORE_TYPES, + disallowedTypes: [ /* Ignore native types that are defined from here */], + disallowedDefinitions: [ + 'lib.dom.d.ts', // no DOM + '@types/node' // no node.js + ] + }, // Common: vs/workbench/api/common/extHostExtensionService.ts { target: '**/vs/workbench/api/common/extHostExtensionService.ts', @@ -288,4 +298,4 @@ for (const sourceFile of program.getSourceFiles()) { if (hasErrors) { process.exit(1); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXJzQ2hlY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxheWVyc0NoZWNrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyxpQ0FBaUM7QUFDakMsMkJBQThDO0FBQzlDLCtCQUE4QztBQUM5Qyx5Q0FBa0M7QUFFbEMsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBQ0YsK0ZBQStGO0FBQy9GLG1EQUFtRDtBQUNuRCw0RUFBNEU7QUFDNUUsaUVBQWlFO0FBQ2pFLEVBQUU7QUFDRixnR0FBZ0c7QUFDaEcsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBRUYsbUZBQW1GO0FBQ25GLHdGQUF3RjtBQUN4RixNQUFNLFVBQVUsR0FBRztJQUNsQixTQUFTLEVBQUUsc0JBQXNCO0lBQ2pDLFlBQVk7SUFDWixjQUFjO0lBQ2QsYUFBYTtJQUNiLGVBQWU7SUFDZixTQUFTO0lBQ1QsU0FBUztJQUNULE9BQU87SUFDUCxrQkFBa0I7SUFDbEIsUUFBUTtJQUNSLGFBQWE7SUFDYixhQUFhO0lBQ2IsTUFBTTtJQUNOLGdCQUFnQjtJQUNoQixPQUFPO0lBQ1AsWUFBWTtJQUNaLGFBQWE7SUFDYixhQUFhO0lBQ2IsV0FBVztJQUNYLFlBQVk7SUFDWixZQUFZO0lBQ1osY0FBYztJQUNkLGNBQWM7SUFDZCxtQkFBbUI7SUFDbkIsZ0JBQWdCO0lBQ2hCLGVBQWU7SUFDZixNQUFNO0lBQ04sTUFBTTtJQUNOLGlCQUFpQjtJQUNqQixhQUFhO0lBQ2IsZ0JBQWdCO0lBQ2hCLGFBQWE7SUFDYixLQUFLO0lBQ0wsaUJBQWlCO0lBQ2pCLGVBQWU7SUFDZixPQUFPO0lBQ1AsYUFBYTtJQUNiLGtCQUFrQjtJQUNsQixhQUFhO0lBQ2IsTUFBTTtDQUNOLENBQUM7QUFFRixvRUFBb0U7QUFDcEUsb0VBQW9FO0FBQ3BFLE1BQU0sWUFBWSxHQUFHO0lBQ3BCLGtCQUFrQjtJQUNsQiwyQkFBMkI7SUFDM0Isa0NBQWtDO0lBQ2xDLDRCQUE0QjtJQUM1QiwwQkFBMEI7SUFDMUIsb0JBQW9CO0lBQ3BCLHFCQUFxQjtDQUNyQixDQUFDO0FBRUYsTUFBTSxLQUFLLEdBQVk7SUFFdEIsY0FBYztJQUNkO1FBQ0MsTUFBTSxFQUFFLGtCQUFrQjtRQUMxQixJQUFJLEVBQUUsSUFBSSxDQUFDLHlCQUF5QjtLQUNwQztJQUVELHFDQUFxQztJQUNyQztRQUNDLE1BQU0sRUFBRSwrQkFBK0I7UUFDdkMsWUFBWSxFQUFFO1lBQ2IsR0FBRyxVQUFVO1lBRWIsMkNBQTJDO1lBQzNDLGNBQWM7U0FDZDtRQUNELGVBQWUsRUFBRSxZQUFZO1FBQzdCLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCwyQ0FBMkM7SUFDM0M7UUFDQyxNQUFNLEVBQUUsd0NBQXdDO1FBQ2hELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCw4Q0FBOEM7SUFDOUM7UUFDQyxNQUFNLEVBQUUsd0NBQXdDO1FBQ2hELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCw4Q0FBOEM7SUFDOUM7UUFDQyxNQUFNLEVBQUUsd0NBQXdDO1FBQ2hELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCw2REFBNkQ7SUFDN0Q7UUFDQyxNQUFNLEVBQUUsdURBQXVEO1FBQy9ELFlBQVksRUFBRTtZQUNiLEdBQUcsVUFBVTtZQUViLHdCQUF3QjtZQUN4QixRQUFRO1NBQ1I7UUFDRCxlQUFlLEVBQUUsWUFBWTtRQUM3QixxQkFBcUIsRUFBRTtZQUN0QixjQUFjLEVBQUUsU0FBUztZQUN6QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsU0FBUztJQUNUO1FBQ0MsTUFBTSxFQUFFLG9CQUFvQjtRQUM1QixZQUFZLEVBQUUsVUFBVTtRQUN4QixlQUFlLEVBQUUsWUFBWTtRQUM3QixxQkFBcUIsRUFBRTtZQUN0QixjQUFjLEVBQUUsU0FBUztZQUN6QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsVUFBVTtJQUNWO1FBQ0MsTUFBTSxFQUFFLHFCQUFxQjtRQUM3QixZQUFZLEVBQUUsVUFBVTtRQUN4QixlQUFlLEVBQUUsWUFBWTtRQUM3QixrQkFBa0IsRUFBRTtZQUNuQixtQ0FBbUMsQ0FBQyxzRkFBc0Y7U0FDMUg7UUFDRCxxQkFBcUIsRUFBRTtZQUN0QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsMkJBQTJCO0lBQzNCO1FBQ0MsTUFBTSxFQUFFLDZCQUE2QjtRQUNyQyxZQUFZLEVBQUUsVUFBVTtRQUN4QixlQUFlLEVBQUUsWUFBWTtRQUM3QixxQkFBcUIsRUFBRTtZQUN0QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsVUFBVTtJQUNWO1FBQ0MsTUFBTSxFQUFFLGtCQUFrQjtRQUMxQixZQUFZLEVBQUUsVUFBVTtRQUN4QixxQkFBcUIsRUFBRTtZQUN0QixjQUFjLENBQUMsU0FBUztTQUN4QjtLQUNEO0lBRUQscUJBQXFCO0lBQ3JCO1FBQ0MsTUFBTSxFQUFFLDhCQUE4QjtRQUN0QyxZQUFZLEVBQUUsVUFBVTtRQUN4QixxQkFBcUIsRUFBRTtZQUN0QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsa0JBQWtCO0lBQ2xCO1FBQ0MsTUFBTSxFQUFFLDJCQUEyQjtRQUNuQyxZQUFZLEVBQUU7WUFDYixHQUFHLFVBQVU7WUFFYixnRUFBZ0U7WUFDaEUsT0FBTztZQUNQLFNBQVM7U0FDVDtRQUNELGVBQWUsRUFBRTtZQUNoQixTQUFTLENBQUMsNENBQTRDO1NBQ3REO1FBQ0QscUJBQXFCLEVBQUU7WUFDdEIsY0FBYyxDQUFDLFNBQVM7U0FDeEI7S0FDRDtDQUNELENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxlQUFlLENBQUMsQ0FBQztBQVd6RSxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7QUFFdEIsU0FBUyxTQUFTLENBQUMsT0FBbUIsRUFBRSxVQUF5QixFQUFFLElBQVc7SUFDN0UsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRXRCLFNBQVMsU0FBUyxDQUFDLElBQWE7UUFDL0IsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDNUMsT0FBTyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLGVBQWU7UUFDekQsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN6QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFakQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2IsT0FBTztRQUNSLENBQUM7UUFFRCxJQUFJLGFBQWEsR0FBUSxNQUFNLENBQUM7UUFFaEMsT0FBTyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDN0IsYUFBYSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUM7UUFDdEMsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFHLGFBQTBCLENBQUM7UUFDaEQsTUFBTSxJQUFJLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRXBDLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMxRCxPQUFPLENBQUMsV0FBVztRQUNwQixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ25FLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEdBQUcsVUFBVSxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3RGLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0RBQW9ELElBQUkscUJBQXFCLElBQUksQ0FBQyxNQUFNLE1BQU0sVUFBVSxDQUFDLFFBQVEsS0FBSyxJQUFJLEdBQUcsQ0FBQyxJQUFJLFNBQVMsR0FBRyxDQUFDLHdIQUF3SCxDQUFDLENBQUM7WUFFclIsU0FBUyxHQUFHLElBQUksQ0FBQztZQUNqQixPQUFPO1FBQ1IsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUM7UUFDekMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDakMsZUFBZSxFQUFFLEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ3pELElBQUksV0FBVyxFQUFFLENBQUM7b0JBQ2pCLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUM7b0JBQ2xDLElBQUksTUFBTSxFQUFFLENBQUM7d0JBQ1osTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7d0JBQ2hELElBQUksZ0JBQWdCLEVBQUUsQ0FBQzs0QkFDdEIsTUFBTSxrQkFBa0IsR0FBRyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUM7NEJBQ3JELElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0NBQzdCLEtBQUssTUFBTSxpQkFBaUIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztvQ0FDekQsSUFBSSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzt3Q0FDeEQsU0FBUyxlQUFlLENBQUM7b0NBQzFCLENBQUM7Z0NBQ0YsQ0FBQzs0QkFDRixDQUFDOzRCQUNELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7Z0NBQ2hDLEtBQUssTUFBTSxvQkFBb0IsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztvQ0FDL0QsSUFBSSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzt3Q0FDM0QsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxVQUFVLENBQUMsNkJBQTZCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7d0NBRXRGLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0RBQXNELElBQUksV0FBVyxvQkFBb0IscUJBQXFCLElBQUksQ0FBQyxNQUFNLE1BQU0sVUFBVSxDQUFDLFFBQVEsS0FBSyxJQUFJLEdBQUcsQ0FBQyxJQUFJLFNBQVMsR0FBRyxDQUFDLHVIQUF1SCxDQUFDLENBQUM7d0NBRXJULFNBQVMsR0FBRyxJQUFJLENBQUM7d0NBQ2pCLE9BQU87b0NBQ1IsQ0FBQztnQ0FDRixDQUFDOzRCQUNGLENBQUM7d0JBQ0YsQ0FBQztvQkFDRixDQUFDO2dCQUNGLENBQUM7WUFDRixDQUFDO1FBQ0YsQ0FBQztJQUNGLENBQUM7QUFDRixDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsWUFBb0I7SUFDMUMsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUVsRSxNQUFNLGdCQUFnQixHQUF1QixFQUFFLFVBQVUsRUFBRSxlQUFVLEVBQUUsYUFBYSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUEsaUJBQVksRUFBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEVBQUUseUJBQXlCLEVBQUUsT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztJQUNwTixNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUMsMEJBQTBCLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxJQUFBLGNBQU8sRUFBQyxJQUFBLGNBQU8sRUFBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFFMUksTUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFFekUsT0FBTyxFQUFFLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztBQUN6RixDQUFDO0FBRUQsRUFBRTtBQUNGLG9DQUFvQztBQUNwQyxFQUFFO0FBQ0YsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBRTlDLEtBQUssTUFBTSxVQUFVLElBQUksT0FBTyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7SUFDbkQsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxQixJQUFJLElBQUEsaUJBQUssRUFBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2hCLFNBQVMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3RDLENBQUM7WUFFRCxNQUFNO1FBQ1AsQ0FBQztJQUNGLENBQUM7QUFDRixDQUFDO0FBRUQsSUFBSSxTQUFTLEVBQUUsQ0FBQztJQUNmLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsQ0FBQyJ9 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXJzQ2hlY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxheWVyc0NoZWNrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyxpQ0FBaUM7QUFDakMsMkJBQThDO0FBQzlDLCtCQUE4QztBQUM5Qyx5Q0FBa0M7QUFFbEMsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBQ0YsK0ZBQStGO0FBQy9GLG1EQUFtRDtBQUNuRCw0RUFBNEU7QUFDNUUsaUVBQWlFO0FBQ2pFLEVBQUU7QUFDRixnR0FBZ0c7QUFDaEcsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBRUYsbUZBQW1GO0FBQ25GLHdGQUF3RjtBQUN4RixNQUFNLFVBQVUsR0FBRztJQUNsQixTQUFTLEVBQUUsc0JBQXNCO0lBQ2pDLFlBQVk7SUFDWixjQUFjO0lBQ2QsYUFBYTtJQUNiLGVBQWU7SUFDZixTQUFTO0lBQ1QsU0FBUztJQUNULE9BQU87SUFDUCxrQkFBa0I7SUFDbEIsUUFBUTtJQUNSLGFBQWE7SUFDYixhQUFhO0lBQ2IsTUFBTTtJQUNOLGdCQUFnQjtJQUNoQixPQUFPO0lBQ1AsWUFBWTtJQUNaLGFBQWE7SUFDYixhQUFhO0lBQ2IsV0FBVztJQUNYLFlBQVk7SUFDWixZQUFZO0lBQ1osY0FBYztJQUNkLGNBQWM7SUFDZCxtQkFBbUI7SUFDbkIsZ0JBQWdCO0lBQ2hCLGVBQWU7SUFDZixNQUFNO0lBQ04sTUFBTTtJQUNOLGlCQUFpQjtJQUNqQixhQUFhO0lBQ2IsZ0JBQWdCO0lBQ2hCLGFBQWE7SUFDYixLQUFLO0lBQ0wsaUJBQWlCO0lBQ2pCLGVBQWU7SUFDZixPQUFPO0lBQ1AsYUFBYTtJQUNiLGtCQUFrQjtJQUNsQixhQUFhO0lBQ2IsTUFBTTtDQUNOLENBQUM7QUFFRixvRUFBb0U7QUFDcEUsb0VBQW9FO0FBQ3BFLE1BQU0sWUFBWSxHQUFHO0lBQ3BCLGtCQUFrQjtJQUNsQiwyQkFBMkI7SUFDM0Isa0NBQWtDO0lBQ2xDLDRCQUE0QjtJQUM1QiwwQkFBMEI7SUFDMUIsb0JBQW9CO0lBQ3BCLHFCQUFxQjtDQUNyQixDQUFDO0FBRUYsTUFBTSxLQUFLLEdBQVk7SUFFdEIsY0FBYztJQUNkO1FBQ0MsTUFBTSxFQUFFLGtCQUFrQjtRQUMxQixJQUFJLEVBQUUsSUFBSSxDQUFDLHlCQUF5QjtLQUNwQztJQUVELHFDQUFxQztJQUNyQztRQUNDLE1BQU0sRUFBRSwrQkFBK0I7UUFDdkMsWUFBWSxFQUFFO1lBQ2IsR0FBRyxVQUFVO1lBRWIsMkNBQTJDO1lBQzNDLGNBQWM7U0FDZDtRQUNELGVBQWUsRUFBRSxZQUFZO1FBQzdCLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCwyQ0FBMkM7SUFDM0M7UUFDQyxNQUFNLEVBQUUsd0NBQXdDO1FBQ2hELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCw4Q0FBOEM7SUFDOUM7UUFDQyxNQUFNLEVBQUUsd0NBQXdDO1FBQ2hELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCw4Q0FBOEM7SUFDOUM7UUFDQyxNQUFNLEVBQUUsd0NBQXdDO1FBQ2hELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCx5REFBeUQ7SUFDekQ7UUFDQyxNQUFNLEVBQUUsbURBQW1EO1FBQzNELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCw2REFBNkQ7SUFDN0Q7UUFDQyxNQUFNLEVBQUUsdURBQXVEO1FBQy9ELFlBQVksRUFBRTtZQUNiLEdBQUcsVUFBVTtZQUViLHdCQUF3QjtZQUN4QixRQUFRO1NBQ1I7UUFDRCxlQUFlLEVBQUUsWUFBWTtRQUM3QixxQkFBcUIsRUFBRTtZQUN0QixjQUFjLEVBQUUsU0FBUztZQUN6QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsU0FBUztJQUNUO1FBQ0MsTUFBTSxFQUFFLG9CQUFvQjtRQUM1QixZQUFZLEVBQUUsVUFBVTtRQUN4QixlQUFlLEVBQUUsWUFBWTtRQUM3QixxQkFBcUIsRUFBRTtZQUN0QixjQUFjLEVBQUUsU0FBUztZQUN6QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsVUFBVTtJQUNWO1FBQ0MsTUFBTSxFQUFFLHFCQUFxQjtRQUM3QixZQUFZLEVBQUUsVUFBVTtRQUN4QixlQUFlLEVBQUUsWUFBWTtRQUM3QixrQkFBa0IsRUFBRTtZQUNuQixtQ0FBbUMsQ0FBQyxzRkFBc0Y7U0FDMUg7UUFDRCxxQkFBcUIsRUFBRTtZQUN0QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsMkJBQTJCO0lBQzNCO1FBQ0MsTUFBTSxFQUFFLDZCQUE2QjtRQUNyQyxZQUFZLEVBQUUsVUFBVTtRQUN4QixlQUFlLEVBQUUsWUFBWTtRQUM3QixxQkFBcUIsRUFBRTtZQUN0QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsVUFBVTtJQUNWO1FBQ0MsTUFBTSxFQUFFLGtCQUFrQjtRQUMxQixZQUFZLEVBQUUsVUFBVTtRQUN4QixxQkFBcUIsRUFBRTtZQUN0QixjQUFjLENBQUMsU0FBUztTQUN4QjtLQUNEO0lBRUQscUJBQXFCO0lBQ3JCO1FBQ0MsTUFBTSxFQUFFLDhCQUE4QjtRQUN0QyxZQUFZLEVBQUUsVUFBVTtRQUN4QixxQkFBcUIsRUFBRTtZQUN0QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsa0JBQWtCO0lBQ2xCO1FBQ0MsTUFBTSxFQUFFLDJCQUEyQjtRQUNuQyxZQUFZLEVBQUU7WUFDYixHQUFHLFVBQVU7WUFFYixnRUFBZ0U7WUFDaEUsT0FBTztZQUNQLFNBQVM7U0FDVDtRQUNELGVBQWUsRUFBRTtZQUNoQixTQUFTLENBQUMsNENBQTRDO1NBQ3REO1FBQ0QscUJBQXFCLEVBQUU7WUFDdEIsY0FBYyxDQUFDLFNBQVM7U0FDeEI7S0FDRDtDQUNELENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxlQUFlLENBQUMsQ0FBQztBQVd6RSxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7QUFFdEIsU0FBUyxTQUFTLENBQUMsT0FBbUIsRUFBRSxVQUF5QixFQUFFLElBQVc7SUFDN0UsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRXRCLFNBQVMsU0FBUyxDQUFDLElBQWE7UUFDL0IsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDNUMsT0FBTyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLGVBQWU7UUFDekQsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN6QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFakQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2IsT0FBTztRQUNSLENBQUM7UUFFRCxJQUFJLGFBQWEsR0FBUSxNQUFNLENBQUM7UUFFaEMsT0FBTyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDN0IsYUFBYSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUM7UUFDdEMsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFHLGFBQTBCLENBQUM7UUFDaEQsTUFBTSxJQUFJLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRXBDLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMxRCxPQUFPLENBQUMsV0FBVztRQUNwQixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ25FLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEdBQUcsVUFBVSxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3RGLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0RBQW9ELElBQUkscUJBQXFCLElBQUksQ0FBQyxNQUFNLE1BQU0sVUFBVSxDQUFDLFFBQVEsS0FBSyxJQUFJLEdBQUcsQ0FBQyxJQUFJLFNBQVMsR0FBRyxDQUFDLHdIQUF3SCxDQUFDLENBQUM7WUFFclIsU0FBUyxHQUFHLElBQUksQ0FBQztZQUNqQixPQUFPO1FBQ1IsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUM7UUFDekMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDakMsZUFBZSxFQUFFLEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ3pELElBQUksV0FBVyxFQUFFLENBQUM7b0JBQ2pCLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUM7b0JBQ2xDLElBQUksTUFBTSxFQUFFLENBQUM7d0JBQ1osTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7d0JBQ2hELElBQUksZ0JBQWdCLEVBQUUsQ0FBQzs0QkFDdEIsTUFBTSxrQkFBa0IsR0FBRyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUM7NEJBQ3JELElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0NBQzdCLEtBQUssTUFBTSxpQkFBaUIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztvQ0FDekQsSUFBSSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzt3Q0FDeEQsU0FBUyxlQUFlLENBQUM7b0NBQzFCLENBQUM7Z0NBQ0YsQ0FBQzs0QkFDRixDQUFDOzRCQUNELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7Z0NBQ2hDLEtBQUssTUFBTSxvQkFBb0IsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztvQ0FDL0QsSUFBSSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzt3Q0FDM0QsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxVQUFVLENBQUMsNkJBQTZCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7d0NBRXRGLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0RBQXNELElBQUksV0FBVyxvQkFBb0IscUJBQXFCLElBQUksQ0FBQyxNQUFNLE1BQU0sVUFBVSxDQUFDLFFBQVEsS0FBSyxJQUFJLEdBQUcsQ0FBQyxJQUFJLFNBQVMsR0FBRyxDQUFDLHVIQUF1SCxDQUFDLENBQUM7d0NBRXJULFNBQVMsR0FBRyxJQUFJLENBQUM7d0NBQ2pCLE9BQU87b0NBQ1IsQ0FBQztnQ0FDRixDQUFDOzRCQUNGLENBQUM7d0JBQ0YsQ0FBQztvQkFDRixDQUFDO2dCQUNGLENBQUM7WUFDRixDQUFDO1FBQ0YsQ0FBQztJQUNGLENBQUM7QUFDRixDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsWUFBb0I7SUFDMUMsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUVsRSxNQUFNLGdCQUFnQixHQUF1QixFQUFFLFVBQVUsRUFBRSxlQUFVLEVBQUUsYUFBYSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUEsaUJBQVksRUFBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEVBQUUseUJBQXlCLEVBQUUsT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztJQUNwTixNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUMsMEJBQTBCLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxJQUFBLGNBQU8sRUFBQyxJQUFBLGNBQU8sRUFBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFFMUksTUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFFekUsT0FBTyxFQUFFLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztBQUN6RixDQUFDO0FBRUQsRUFBRTtBQUNGLG9DQUFvQztBQUNwQyxFQUFFO0FBQ0YsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBRTlDLEtBQUssTUFBTSxVQUFVLElBQUksT0FBTyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7SUFDbkQsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxQixJQUFJLElBQUEsaUJBQUssRUFBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2hCLFNBQVMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3RDLENBQUM7WUFFRCxNQUFNO1FBQ1AsQ0FBQztJQUNGLENBQUM7QUFDRixDQUFDO0FBRUQsSUFBSSxTQUFTLEVBQUUsQ0FBQztJQUNmLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsQ0FBQyJ9 \ No newline at end of file diff --git a/build/lib/layersChecker.ts b/build/lib/layersChecker.ts index e7fdfd4214e..515081d7828 100644 --- a/build/lib/layersChecker.ts +++ b/build/lib/layersChecker.ts @@ -135,6 +135,17 @@ const RULES: IRule[] = [ ] }, + // Common: vs/platform/native/common/nativeHostService.ts + { + target: '**/vs/platform/native/common/nativeHostService.ts', + allowedTypes: CORE_TYPES, + disallowedTypes: [/* Ignore native types that are defined from here */], + disallowedDefinitions: [ + 'lib.dom.d.ts', // no DOM + '@types/node' // no node.js + ] + }, + // Common: vs/workbench/api/common/extHostExtensionService.ts { target: '**/vs/workbench/api/common/extHostExtensionService.ts', diff --git a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts index 3d7ef0fa47c..ebefca402ea 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts @@ -17,7 +17,7 @@ import { ElectronIPCMainProcessService } from 'vs/platform/ipc/electron-sandbox/ import { registerMainProcessRemoteService } from 'vs/platform/ipc/electron-sandbox/services'; import { IIssueMainService, IssueReporterWindowConfiguration } from 'vs/platform/issue/common/issue'; import { INativeHostService } from 'vs/platform/native/common/native'; -import { NativeHostService } from 'vs/platform/native/electron-sandbox/nativeHostService'; +import { NativeHostService } from 'vs/platform/native/common/nativeHostService'; import { IssueReporter } from './issueReporterService'; export function startup(configuration: IssueReporterWindowConfiguration) { diff --git a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts index 19763e979f1..b6d0fc503f7 100644 --- a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts @@ -20,7 +20,7 @@ import { ByteSize } from 'vs/platform/files/common/files'; import { ElectronIPCMainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService'; import { ProcessExplorerData, ProcessExplorerStyles, ProcessExplorerWindowConfiguration } from 'vs/platform/issue/common/issue'; import { INativeHostService } from 'vs/platform/native/common/native'; -import { NativeHostService } from 'vs/platform/native/electron-sandbox/nativeHostService'; +import { NativeHostService } from 'vs/platform/native/common/nativeHostService'; import { getIconsStyleSheet } from 'vs/platform/theme/browser/iconsStyleSheet'; import { applyZoom, zoomIn, zoomOut } from 'vs/platform/window/electron-sandbox/window'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; diff --git a/src/vs/code/node/sharedProcess/sharedProcessMain.ts b/src/vs/code/node/sharedProcess/sharedProcessMain.ts index 84d080486a3..3c5650cb69d 100644 --- a/src/vs/code/node/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/node/sharedProcess/sharedProcessMain.ts @@ -106,6 +106,7 @@ import { ExtensionsProfileScannerService } from 'vs/platform/extensionManagement import { RequestChannelClient } from 'vs/platform/request/common/requestIpc'; import { ExtensionRecommendationNotificationServiceChannelClient } from 'vs/platform/extensionRecommendations/common/extensionRecommendationsIpc'; import { INativeHostService } from 'vs/platform/native/common/native'; +import { NativeHostService } from 'vs/platform/native/common/nativeHostService'; import { UserDataAutoSyncService } from 'vs/platform/userDataSync/node/userDataAutoSyncService'; import { ExtensionTipsService } from 'vs/platform/extensionManagement/node/extensionTipsService'; import { IMainProcessService, MainProcessService } from 'vs/platform/ipc/common/mainProcessService'; @@ -274,7 +275,7 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter { services.set(IV8InspectProfilingService, new SyncDescriptor(V8InspectProfilingService, undefined, false /* proxied to other processes */)); // Native Host - const nativeHostService = ProxyChannel.toService(mainProcessService.getChannel('nativeHost')); + const nativeHostService = new NativeHostService(-1 /* we are not running in a browser window context */, mainProcessService) as INativeHostService; services.set(INativeHostService, nativeHostService); // Download diff --git a/src/vs/platform/native/electron-sandbox/nativeHostService.ts b/src/vs/platform/native/common/nativeHostService.ts similarity index 100% rename from src/vs/platform/native/electron-sandbox/nativeHostService.ts rename to src/vs/platform/native/common/nativeHostService.ts diff --git a/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts b/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts index 32350e21ec2..05a84b5f4ec 100644 --- a/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts +++ b/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts @@ -11,7 +11,7 @@ import { ILabelService, Verbosity } from 'vs/platform/label/common/label'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWindowOpenable, IOpenWindowOptions, isFolderToOpen, isWorkspaceToOpen, IOpenEmptyWindowOptions } from 'vs/platform/window/common/window'; import { Disposable } from 'vs/base/common/lifecycle'; -import { NativeHostService } from 'vs/platform/native/electron-sandbox/nativeHostService'; +import { NativeHostService } from 'vs/platform/native/common/nativeHostService'; import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService'; import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService'; import { IAuxiliaryWindowService, isAuxiliaryWindow } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService'; From f8cfa707844ed0ee93f3fc5526020dc467f55ba0 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 6 Nov 2023 12:45:53 +0100 Subject: [PATCH 021/240] move extension containers actions to search (#197533) --- .../browser/extensions.contribution.ts | 12 +++++------ .../extensions/browser/extensionsViewlet.ts | 20 +++++++++++++++---- .../browser/media/extensionsViewlet.css | 16 ++++++++++++++- .../contrib/extensions/common/extensions.ts | 3 +++ 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 3b7f3a69780..db5a46e3525 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -13,7 +13,7 @@ import { EnablementState, IExtensionManagementServerService, IWorkbenchExtension import { IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; -import { VIEWLET_ID, IExtensionsWorkbenchService, IExtensionsViewPaneContainer, TOGGLE_IGNORE_EXTENSION_ACTION_ID, INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID, WORKSPACE_RECOMMENDATIONS_VIEW_ID, IWorkspaceRecommendedExtensionsView, AutoUpdateConfigurationKey, HasOutdatedExtensionsContext, SELECT_INSTALL_VSIX_EXTENSION_COMMAND_ID, LIST_WORKSPACE_UNSUPPORTED_EXTENSIONS_COMMAND_ID, ExtensionEditorTab, THEME_ACTIONS_GROUP, INSTALL_ACTIONS_GROUP, OUTDATED_EXTENSIONS_VIEW_ID, CONTEXT_HAS_GALLERY, IExtension } from 'vs/workbench/contrib/extensions/common/extensions'; +import { VIEWLET_ID, IExtensionsWorkbenchService, IExtensionsViewPaneContainer, TOGGLE_IGNORE_EXTENSION_ACTION_ID, INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID, WORKSPACE_RECOMMENDATIONS_VIEW_ID, IWorkspaceRecommendedExtensionsView, AutoUpdateConfigurationKey, HasOutdatedExtensionsContext, SELECT_INSTALL_VSIX_EXTENSION_COMMAND_ID, LIST_WORKSPACE_UNSUPPORTED_EXTENSIONS_COMMAND_ID, ExtensionEditorTab, THEME_ACTIONS_GROUP, INSTALL_ACTIONS_GROUP, OUTDATED_EXTENSIONS_VIEW_ID, CONTEXT_HAS_GALLERY, IExtension, extensionsSearchActionsMenu } from 'vs/workbench/contrib/extensions/common/extensions'; import { ReinstallAction, InstallSpecificVersionOfExtensionAction, ConfigureWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction, PromptExtensionInstallFailureAction, SearchExtensionsAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, SetColorThemeAction, SetFileIconThemeAction, SetProductIconThemeAction, ClearLanguageAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput'; import { ExtensionEditor } from 'vs/workbench/contrib/extensions/browser/extensionEditor'; @@ -885,12 +885,11 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi }); const extensionsFilterSubMenu = new MenuId('extensionsFilterSubMenu'); - MenuRegistry.appendMenuItem(MenuId.ViewContainerTitle, { + MenuRegistry.appendMenuItem(extensionsSearchActionsMenu, { submenu: extensionsFilterSubMenu, title: localize('filterExtensions', "Filter Extensions..."), - when: ContextKeyExpr.equals('viewContainer', VIEWLET_ID), group: 'navigation', - order: 1, + order: 2, icon: filterIcon, }); @@ -1128,10 +1127,9 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi f1: true, precondition: SearchHasTextContext, menu: { - id: MenuId.ViewContainerTitle, - when: ContextKeyExpr.equals('viewContainer', VIEWLET_ID), + id: extensionsSearchActionsMenu, group: 'navigation', - order: 3, + order: 1, }, run: async (accessor: ServicesAccessor) => { const viewPaneContainer = accessor.get(IViewsService).getActiveViewPaneContainerWithId(VIEWLET_ID); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 7957a1598ec..0ff891c4e28 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -16,7 +16,7 @@ import { append, $, Dimension, hide, show, DragAndDropObserver, trackFocus } fro import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { IExtensionsWorkbenchService, IExtensionsViewPaneContainer, VIEWLET_ID, CloseExtensionDetailsOnViewChangeKey, INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID, WORKSPACE_RECOMMENDATIONS_VIEW_ID, AutoCheckUpdatesConfigurationKey, OUTDATED_EXTENSIONS_VIEW_ID, CONTEXT_HAS_GALLERY } from '../common/extensions'; +import { IExtensionsWorkbenchService, IExtensionsViewPaneContainer, VIEWLET_ID, CloseExtensionDetailsOnViewChangeKey, INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID, WORKSPACE_RECOMMENDATIONS_VIEW_ID, AutoCheckUpdatesConfigurationKey, OUTDATED_EXTENSIONS_VIEW_ID, CONTEXT_HAS_GALLERY, extensionsSearchActionsMenu } from '../common/extensions'; import { InstallLocalExtensionsInRemoteAction, InstallRemoteExtensionsInLocalAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkbenchExtensionEnablementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; @@ -62,6 +62,8 @@ import { extname } from 'vs/base/common/resources'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ILocalizedString } from 'vs/platform/action/common/action'; import { registerNavigableContainer } from 'vs/workbench/browser/actions/widgetNavigationCommands'; +import { MenuWorkbenchToolBar } from 'vs/platform/actions/browser/toolbar'; +import { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem'; export const DefaultViewsContext = new RawContextKey('defaultExtensionViews', true); export const ExtensionsSortByContext = new RawContextKey('extensionsSortByValue', ''); @@ -554,7 +556,9 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE const searchValue = this.searchViewletState['query.value'] ? this.searchViewletState['query.value'] : ''; - this.searchBox = this._register(this.instantiationService.createInstance(SuggestEnabledInput, `${VIEWLET_ID}.searchbox`, header, { + const searchContainer = append(header, $('.extensions-search-container')); + + this.searchBox = this._register(this.instantiationService.createInstance(SuggestEnabledInput, `${VIEWLET_ID}.searchbox`, searchContainer, { triggerCharacters: ['@'], sortKey: (item: string) => { if (item.indexOf(':') === -1) { return 'a'; } @@ -571,12 +575,20 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE } this._register(this.searchBox.onInputDidChange(() => { - this.sortByContextKey.set(Query.parse(this.searchBox!.getValue() || '').sortBy); + this.sortByContextKey.set(Query.parse(this.searchBox?.getValue() ?? '').sortBy); this.triggerSearch(); }, this)); this._register(this.searchBox.onShouldFocusResults(() => this.focusListView(), this)); + const controlElement = append(searchContainer, $('.extensions-search-actions-container')); + this._register(this.instantiationService.createInstance(MenuWorkbenchToolBar, controlElement, extensionsSearchActionsMenu, { + toolbarOptions: { + primaryGroup: () => true, + }, + actionViewItemProvider: action => createActionViewItem(this.instantiationService, action) + })); + // Register DragAndDrop support this._register(new DragAndDropObserver(this.root, { onDragEnd: (e: DragEvent) => undefined, @@ -644,7 +656,7 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE this.root.classList.toggle('narrow', dimension.width <= 250); this.root.classList.toggle('mini', dimension.width <= 200); } - this.searchBox?.layout(new Dimension(dimension.width - 34 - /*padding*/8, 20)); + this.searchBox?.layout(new Dimension(dimension.width - 34 - /*padding*/8 - (24 * 2), 20)); super.layout(new Dimension(dimension.width, dimension.height - 41)); } diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css index 47e19378fa0..552e9cf54c2 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css @@ -23,7 +23,11 @@ padding: 5px 12px 6px 20px; } -.extensions-viewlet > .header > .search-box { +.extensions-viewlet > .header > .extensions-search-container { + position: relative; +} + +.extensions-viewlet > .header > .extensions-search-container > .search-box { width: 100%; height: 28px; line-height: 18px; @@ -34,6 +38,16 @@ -moz-appearance: textfield; } +.extensions-viewlet > .header > .extensions-search-container > .extensions-search-actions-container { + display: flex; + align-items: center; + position: absolute; + top: 0; + right: 0; + height: 100%; +} + + .extensions-viewlet > .extensions { height: calc(100% - 41px); } diff --git a/src/vs/workbench/contrib/extensions/common/extensions.ts b/src/vs/workbench/contrib/extensions/common/extensions.ts index 5582a39fea9..3b77ce18a1e 100644 --- a/src/vs/workbench/contrib/extensions/common/extensions.ts +++ b/src/vs/workbench/contrib/extensions/common/extensions.ts @@ -18,6 +18,7 @@ import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IExtensionsStatus } from 'vs/workbench/services/extensions/common/extensions'; import { IExtensionEditorOptions } from 'vs/workbench/contrib/extensions/common/extensionsInput'; import { ProgressLocation } from 'vs/platform/progress/common/progress'; +import { MenuId } from 'vs/platform/actions/common/actions'; export const VIEWLET_ID = 'workbench.view.extensions'; @@ -199,3 +200,5 @@ export const CONTEXT_HAS_GALLERY = new RawContextKey('hasGallery', fals // Context Menu Groups export const THEME_ACTIONS_GROUP = '_theme_'; export const INSTALL_ACTIONS_GROUP = '0_install'; + +export const extensionsSearchActionsMenu = new MenuId('extensionsSearchActionsMenu'); From cff1d63da0394377e403c452236c77c0c9425d6c Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 6 Nov 2023 12:47:59 +0100 Subject: [PATCH 022/240] Add jersey icon to user data profile icons (#197534) --- .../services/userDataProfile/common/userDataProfileIcons.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfileIcons.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfileIcons.ts index cb660577b2e..c56bc226966 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfileIcons.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfileIcons.ts @@ -91,5 +91,6 @@ export const ICONS = [ Codicon.paintcan, Codicon.archive, Codicon.mic, + Codicon.jersey, ]; From 6786b8fb9a4ff4e5dd411f1fc299bdbcb6956326 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 6 Nov 2023 12:58:50 +0100 Subject: [PATCH 023/240] untitled - use ref counted lifecycle (#194371) * wip * cleanup * also use ref in main * fix one test * adop `canDispose` for untitled as well * untitled - ignore dirty on change on revert --- .../api/browser/mainThreadDocuments.ts | 8 +++-- .../common/editor/textResourceEditorInput.ts | 4 +-- .../files/browser/editors/fileEditorInput.ts | 4 +-- .../textfile/common/textEditorService.ts | 15 +------- .../common/textModelResolverService.ts | 9 +++-- .../common/untitledTextEditorInput.ts | 29 +++++++++++++-- .../common/untitledTextEditorModel.ts | 35 +++++++++++-------- .../common/untitledTextEditorService.ts | 30 ++++++++++++++++ .../test/browser/untitledTextEditor.test.ts | 30 +++++++++++++++- 9 files changed, 125 insertions(+), 39 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadDocuments.ts b/src/vs/workbench/api/browser/mainThreadDocuments.ts index 4d28ce7f8e9..02d36af3856 100644 --- a/src/vs/workbench/api/browser/mainThreadDocuments.ts +++ b/src/vs/workbench/api/browser/mainThreadDocuments.ts @@ -17,7 +17,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ import { toLocalResource, extUri, IExtUri } from 'vs/base/common/resources'; import { IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { Emitter } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; import { IPathService } from 'vs/workbench/services/path/common/pathService'; import { ResourceMap } from 'vs/base/common/map'; import { IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; @@ -267,15 +267,19 @@ export class MainThreadDocuments extends Disposable implements MainThreadDocumen } private async _doCreateUntitled(associatedResource?: URI, languageId?: string, initialValue?: string): Promise { - const model = await this._textFileService.untitled.resolve({ + const model = this._textFileService.untitled.create({ associatedResource, languageId, initialValue }); const resource = model.resource; + const ref = await this._textModelResolverService.createModelReference(resource); if (!this._modelTrackers.has(resource)) { + ref.dispose(); throw new Error(`expected URI ${resource.toString()} to have come to LIFE`); } + this._modelReferenceCollection.add(resource, ref, ref.object.textEditorModel.getValueLength()); + Event.once(model.onDidRevert)(() => this._modelReferenceCollection.remove(resource)); this._proxy.$acceptDirtyStateChanged(resource, true); // mark as dirty return resource; } diff --git a/src/vs/workbench/common/editor/textResourceEditorInput.ts b/src/vs/workbench/common/editor/textResourceEditorInput.ts index 07b06ab96cb..02217560ffd 100644 --- a/src/vs/workbench/common/editor/textResourceEditorInput.ts +++ b/src/vs/workbench/common/editor/textResourceEditorInput.ts @@ -99,7 +99,7 @@ export class TextResourceEditorInput extends AbstractTextResourceEditorInput imp private description: string | undefined, private preferredLanguageId: string | undefined, private preferredContents: string | undefined, - @ITextModelService private readonly textModelResolverService: ITextModelService, + @ITextModelService private readonly textModelService: ITextModelService, @ITextFileService textFileService: ITextFileService, @IEditorService editorService: IEditorService, @IFileService fileService: IFileService, @@ -160,7 +160,7 @@ export class TextResourceEditorInput extends AbstractTextResourceEditorInput imp this.preferredLanguageId = undefined; if (!this.modelReference) { - this.modelReference = this.textModelResolverService.createModelReference(this.resource); + this.modelReference = this.textModelService.createModelReference(this.resource); } const ref = await this.modelReference; diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts index d6c151043f0..0a0cbcc764d 100644 --- a/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts +++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts @@ -93,7 +93,7 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements preferredContents: string | undefined, @IInstantiationService private readonly instantiationService: IInstantiationService, @ITextFileService textFileService: ITextFileService, - @ITextModelService private readonly textModelResolverService: ITextModelService, + @ITextModelService private readonly textModelService: ITextModelService, @ILabelService labelService: ILabelService, @IFileService fileService: IFileService, @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, @@ -348,7 +348,7 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements // resolve() ensures we are not creating model references for these kind of resources. // In addition we have a bit of payload to take into account (encoding, reload) that the text resolver does not handle yet. if (!this.cachedTextFileModelReference) { - this.cachedTextFileModelReference = await this.textModelResolverService.createModelReference(this.resource) as IReference; + this.cachedTextFileModelReference = await this.textModelService.createModelReference(this.resource) as IReference; } const model = this.cachedTextFileModelReference.object; diff --git a/src/vs/workbench/services/textfile/common/textEditorService.ts b/src/vs/workbench/services/textfile/common/textEditorService.ts index 8595dfe0772..d3e6d529e71 100644 --- a/src/vs/workbench/services/textfile/common/textEditorService.ts +++ b/src/vs/workbench/services/textfile/common/textEditorService.ts @@ -146,20 +146,7 @@ export class TextEditorService extends Disposable implements ITextEditorService untitledModel = this.untitledTextEditorService.create({ associatedResource: untitledInput.resource, ...untitledOptions }); } - return this.createOrGetCached(untitledModel.resource, () => { - - // Factory function for new untitled editor - const input = this.instantiationService.createInstance(UntitledTextEditorInput, untitledModel); - - // We dispose the untitled model once the editor - // is being disposed. Even though we may have not - // created the model initially, the lifecycle for - // untitled is tightly coupled with the editor - // lifecycle for now. - Event.once(input.onWillDispose)(() => untitledModel.dispose()); - - return input; - }); + return this.createOrGetCached(untitledModel.resource, () => this.instantiationService.createInstance(UntitledTextEditorInput, untitledModel)); } // Text File/Resource Editor Support diff --git a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts index 0dc7a0735fd..620abdc7e88 100644 --- a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts +++ b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts @@ -18,6 +18,7 @@ import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/ import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { ModelUndoRedoParticipant } from 'vs/editor/common/services/modelUndoRedoParticipant'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { UntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel'; class ResourceModelCollection extends ReferenceCollection> { @@ -102,9 +103,9 @@ class ResourceModelCollection extends ReferenceCollection): void { - // untitled and inMemory are bound to a different lifecycle + // inMemory is bound to a different lifecycle const resource = URI.parse(key); - if (resource.scheme === Schemas.untitled || resource.scheme === Schemas.inMemory) { + if (resource.scheme === Schemas.inMemory) { return; } @@ -125,6 +126,10 @@ class ResourceModelCollection extends ReferenceCollection | undefined = undefined; + private cachedUntitledTextEditorModelReference: IReference | undefined = undefined; constructor( readonly model: IUntitledTextEditorModel, @@ -43,7 +46,8 @@ export class UntitledTextEditorInput extends AbstractTextResourceEditorInput imp @IFileService fileService: IFileService, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, @IPathService private readonly pathService: IPathService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, + @ITextModelService private readonly textModelService: ITextModelService ) { super(model.resource, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService); @@ -120,11 +124,22 @@ export class UntitledTextEditorInput extends AbstractTextResourceEditorInput imp override async resolve(): Promise { if (!this.modelResolve) { - this.modelResolve = this.model.resolve(); + this.modelResolve = (async () => { + + // Acquire a model reference + this.cachedUntitledTextEditorModelReference = await this.textModelService.createModelReference(this.resource) as IReference; + })(); } await this.modelResolve; + // It is possible that this input was disposed before the model + // finished resolving. As such, we need to make sure to dispose + // the model reference to not leak it. + if (this.isDisposed()) { + this.disposeModelReference(); + } + return this.model; } @@ -176,8 +191,18 @@ export class UntitledTextEditorInput extends AbstractTextResourceEditorInput imp } override dispose(): void { + + // Model this.modelResolve = undefined; + // Model reference + this.disposeModelReference(); + super.dispose(); } + + private disposeModelReference(): void { + dispose(this.cachedUntitledTextEditorModelReference); + this.cachedUntitledTextEditorModelReference = undefined; + } } diff --git a/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts b/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts index 06ab35ec8c5..43402bc496c 100644 --- a/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts +++ b/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts @@ -12,7 +12,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackup'; import { ITextResourceConfigurationChangeEvent, ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; import { ITextModel } from 'vs/editor/common/model'; -import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel'; +import { createTextBufferFactory, createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel'; import { ITextEditorModel } from 'vs/editor/common/services/resolverService'; import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IWorkingCopy, WorkingCopyCapabilities, IWorkingCopyBackup, NO_TYPE_ID, IWorkingCopySaveEvent } from 'vs/workbench/services/workingCopy/common/workingCopy'; @@ -273,16 +273,19 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IUnt async revert(): Promise { + // Reset contents to be empty + this.ignoreDirtyOnModelContentChange = true; + try { + this.updateTextEditorModel(createTextBufferFactory('')); + } finally { + this.ignoreDirtyOnModelContentChange = false; + } + // No longer dirty this.setDirty(false); // Emit as event this._onDidRevert.fire(); - - // A reverted untitled model is invalid because it has - // no actual source on disk to revert to. As such we - // dispose the model. - this.dispose(); } async backup(token: CancellationToken): Promise { @@ -307,6 +310,8 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IUnt //#region Resolve + private ignoreDirtyOnModelContentChange = false; + override async resolve(): Promise { // Create text editor model if not yet done @@ -375,16 +380,18 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IUnt } private onModelContentChanged(textEditorModel: ITextModel, e: IModelContentChangedEvent): void { + if (!this.ignoreDirtyOnModelContentChange) { - // mark the untitled text editor as non-dirty once its content becomes empty and we do - // not have an associated path set. we never want dirty indicator in that case. - if (!this.hasAssociatedFilePath && textEditorModel.getLineCount() === 1 && textEditorModel.getLineLength(1) === 0) { - this.setDirty(false); - } + // mark the untitled text editor as non-dirty once its content becomes empty and we do + // not have an associated path set. we never want dirty indicator in that case. + if (!this.hasAssociatedFilePath && textEditorModel.getLineCount() === 1 && textEditorModel.getLineLength(1) === 0) { + this.setDirty(false); + } - // turn dirty otherwise - else { - this.setDirty(true); + // turn dirty otherwise + else { + this.setDirty(true); + } } // Check for name change if first line changed in the range of 0-FIRST_LINE_NAME_CANDIDATE_MAX_LENGTH columns diff --git a/src/vs/workbench/services/untitled/common/untitledTextEditorService.ts b/src/vs/workbench/services/untitled/common/untitledTextEditorService.ts index 1122ba55f90..8b4d6a5919e 100644 --- a/src/vs/workbench/services/untitled/common/untitledTextEditorService.ts +++ b/src/vs/workbench/services/untitled/common/untitledTextEditorService.ts @@ -117,6 +117,13 @@ export interface IUntitledTextEditorModelManager { * Figures out if the given resource has an associated resource or not. */ isUntitledWithAssociatedResource(resource: URI): boolean; + + /** + * Waits for the model to be ready to be disposed. There may be conditions + * under which the model cannot be disposed, e.g. when it is dirty. Once the + * promise is settled, it is safe to dispose the model. + */ + canDispose(model: IUntitledTextEditorModel): true | Promise; } export interface IUntitledTextEditorService extends IUntitledTextEditorModelManager { @@ -270,6 +277,29 @@ export class UntitledTextEditorService extends Disposable implements IUntitledTe isUntitledWithAssociatedResource(resource: URI): boolean { return resource.scheme === Schemas.untitled && resource.path.length > 1 && !UntitledTextEditorService.UNTITLED_WITHOUT_ASSOCIATED_RESOURCE_REGEX.test(resource.path); } + + canDispose(model: UntitledTextEditorModel): true | Promise { + if (model.isDisposed()) { + return true; // quick return if model already disposed + } + + // promise based return in all other cases + return this.doCanDispose(model); + } + + private async doCanDispose(model: UntitledTextEditorModel): Promise { + + // dirty model: we do not allow to dispose dirty models to prevent + // data loss cases. dirty models can only be disposed when they are + // either saved or reverted + if (model.isDirty()) { + await Event.toPromise(model.onDidChangeDirty); + + return this.canDispose(model); + } + + return true; + } } registerSingleton(IUntitledTextEditorService, UntitledTextEditorService, InstantiationType.Delayed); diff --git a/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.test.ts b/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.test.ts index c70d755430b..f65c4f2c15d 100644 --- a/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.test.ts +++ b/src/vs/workbench/services/untitled/test/browser/untitledTextEditor.test.ts @@ -14,7 +14,7 @@ import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry' import { ISingleEditOperation } from 'vs/editor/common/core/editOperation'; import { Range } from 'vs/editor/common/core/range'; import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput'; -import { IUntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel'; +import { IUntitledTextEditorModel, UntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel'; import { CancellationToken } from 'vs/base/common/cancellation'; import { EditorInputCapabilities } from 'vs/workbench/common/editor'; import { DisposableStore } from 'vs/base/common/lifecycle'; @@ -22,6 +22,7 @@ import { isReadable, isReadableStream } from 'vs/base/common/stream'; import { readableToBuffer, streamToBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer'; import { LanguageDetectionLanguageEventSource } from 'vs/workbench/services/languageDetection/common/languageDetectionWorkerService'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; +import { timeout } from 'vs/base/common/async'; suite('Untitled text editors', () => { @@ -573,5 +574,32 @@ suite('Untitled text editors', () => { assert.strictEqual(counter, 1, 'Another change to same encoding does not fire event'); }); + test('canDispose with dirty model', async function () { + const service = accessor.untitledTextEditorService; + const input = disposables.add(instantiationService.createInstance(UntitledTextEditorInput, service.create())); + + const model = disposables.add(await input.resolve()); + + model.textEditorModel?.setValue('foo'); + + const canDisposePromise = service.canDispose(model as UntitledTextEditorModel); + assert.ok(canDisposePromise instanceof Promise); + + let canDispose = false; + (async () => { + canDispose = await canDisposePromise; + })(); + + assert.strictEqual(canDispose, false); + model.revert({ soft: true }); + + await timeout(0); + + assert.strictEqual(canDispose, true); + + const canDispose2 = service.canDispose(model as UntitledTextEditorModel); + assert.strictEqual(canDispose2, true); + }); + ensureNoDisposablesAreLeakedInTestSuite(); }); From 4faf905f813080da34d97bad740abde512f66650 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 6 Nov 2023 07:18:45 -0800 Subject: [PATCH 024/240] Fix compile errors --- .../browser/terminal.stickyScroll.contribution.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index 5973426a90e..2972e8abb70 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -7,11 +7,11 @@ import 'vs/css!./media/stickyScroll'; import { throttle } from 'vs/base/common/decorators'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; -import { IDetachedTerminalInstance, ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; -import type { Terminal as RawXtermTerminal } from 'xterm'; +import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; import { hide, show } from 'vs/base/browser/dom'; class TerminalStickyScrollContribution extends DisposableStore implements ITerminalContribution { @@ -26,8 +26,8 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi constructor( private readonly _instance: ITerminalInstance, - private readonly _processManager: ITerminalProcessManager, - private readonly _widgetManager: TerminalWidgetManager, + processManager: ITerminalProcessManager | ITerminalProcessInfo, + widgetManager: TerminalWidgetManager, @ITerminalService private readonly _terminalService: ITerminalService, ) { super(); From 74202a4412cb24aa9c16548b7f664277031d3283 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 6 Nov 2023 07:56:15 -0800 Subject: [PATCH 025/240] Get sticky scroll rendering with an xterm instance --- .../contrib/terminal/browser/terminal.ts | 4 +- .../terminal/browser/xterm/xtermTerminal.ts | 6 +- .../browser/media/stickyScroll.css | 5 + .../terminal.stickyScroll.contribution.ts | 114 ++++++++++++++++-- 4 files changed, 114 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index ce5c9213f6f..bc02e19edce 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -25,7 +25,7 @@ import { XtermTerminal } from 'vs/workbench/contrib/terminal/browser/xterm/xterm import { IRegisterContributedProfileArgs, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalFont, ITerminalProcessExtHostProxy, ITerminalProcessInfo } from 'vs/workbench/contrib/terminal/common/terminal'; import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { ISimpleSelectedSuggestion } from 'vs/workbench/services/suggest/browser/simpleSuggestWidget'; -import type { IMarker, Terminal as RawXtermTerminal } from '@xterm/xterm'; +import type { IMarker, ITheme, Terminal as RawXtermTerminal } from '@xterm/xterm'; export const ITerminalService = createDecorator('terminalService'); export const ITerminalEditorService = createDecorator('terminalEditorService'); @@ -1146,6 +1146,8 @@ export interface IXtermTerminal extends IDisposable { * Refreshes the terminal after it has been moved. */ refresh(): void; + + getXtermTheme(theme?: IColorTheme): ITheme; } export interface IDetachedXtermTerminal extends IXtermTerminal { diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index 4963c4f95b6..db3c84369d7 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -223,7 +223,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach documentOverride: layoutService.container.ownerDocument, altClickMovesCursor: config.altClickMovesCursor && editorOptions.multiCursorModifier === 'alt', scrollback: config.scrollback, - theme: this._getXtermTheme(), + theme: this.getXtermTheme(), drawBoldTextInBrightColors: config.drawBoldTextInBrightColors, fontFamily: font.fontFamily, fontWeight: config.fontWeight, @@ -897,7 +897,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach }; } - private _getXtermTheme(theme?: IColorTheme): ITheme { + getXtermTheme(theme?: IColorTheme): ITheme { if (!theme) { theme = this._themeService.getColorTheme(); } @@ -938,7 +938,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach } private _updateTheme(theme?: IColorTheme): void { - this.raw.options.theme = this._getXtermTheme(theme); + this.raw.options.theme = this.getXtermTheme(theme); } refresh() { diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css index 49cb0cae8db..49d0f7bcc31 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css @@ -14,3 +14,8 @@ background: var(--vscode-terminal-background, var(--vscode-panel-background)); box-shadow: var(--vscode-scrollbar-shadow) 0 3px 2px -2px; } + +.terminal-sticky-scroll .xterm { + /* TODO: Remove !important */ + position: relative !important; +} diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index 2972e8abb70..b473a4671dd 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -11,8 +11,18 @@ import { ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTermi import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; -import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; +import type { ITheme, Terminal as RawXtermTerminal } from '@xterm/xterm'; +import type { CanvasAddon as CanvasAddonType } from '@xterm/addon-canvas'; +import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; import { hide, show } from 'vs/base/browser/dom'; +import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { importAMDNodeModule } from 'vs/amdX'; +import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; + +let CanvasAddon: typeof CanvasAddonType; +let SerializeAddon: typeof SerializeAddonType; class TerminalStickyScrollContribution extends DisposableStore implements ITerminalContribution { static readonly ID = 'terminal.stickyScroll'; @@ -23,11 +33,16 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi private _xterm?: IXtermTerminal & { raw: RawXtermTerminal }; private _element?: HTMLElement; + private _stickyScrollOverlay?: RawXtermTerminal; + private _overlaySerializeAddon?: SerializeAddonType; constructor( private readonly _instance: ITerminalInstance, processManager: ITerminalProcessManager | ITerminalProcessInfo, widgetManager: TerminalWidgetManager, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IKeybindingService private readonly _keybindingService: IKeybindingService, + @IThemeService private readonly _themeService: IThemeService, @ITerminalService private readonly _terminalService: ITerminalService, ) { super(); @@ -38,6 +53,24 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi this.add(xterm.raw.onScroll(() => this._refresh())); this.add(xterm.raw.onLineFeed(() => this._refresh())); // TODO: Disable in alt buffer + + TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { + const overlay = new ctor({ + rows: 1, + cols: xterm.raw.cols + }); + this._stickyScrollOverlay = overlay; + this._getSerializeAddonConstructor().then(addonCtor => { + this._overlaySerializeAddon = new addonCtor(); + xterm.raw.loadAddon(this._overlaySerializeAddon); + }); + // TODO: Track and sync with real instance + // if (gpu renderer) { + this._getCanvasAddonConstructor().then(addonCtor => { + overlay.loadAddon(new addonCtor()); + }); + // } + }); } @throttle(0) @@ -61,31 +94,90 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi return; } const element = this._ensureElement(this._xterm.raw.element); - element.textContent = this._xterm.raw.buffer.active.getLine(marker.line)?.translateToString(true) ?? ''; + // element.textContent = this._xterm.raw.buffer.active.getLine(marker.line)?.translateToString(true) ?? ''; if (element.textContent === '') { hide(element); } else { show(element); } console.log('command!', command); + + if (this._stickyScrollOverlay) { + this._stickyScrollOverlay.write('\x1b[H\x1b[K'); + // TODO: Serialize line instead + // TODO: Support providing single line/range serialize addon + const s = this._overlaySerializeAddon?.serialize({ + scrollback: this._xterm.raw.buffer.active.baseY - marker.line + }); + if (s) { + const content = s.substring(0, s.indexOf('\r')); + + // const content = this._xterm.raw.buffer.active.getLine(marker.line)?.translateToString(true) ?? ''; + if (content) { + this._stickyScrollOverlay.write(content); + } + } + this._syncOptions(this._stickyScrollOverlay, this._xterm.raw); + } } private _ensureElement(container: HTMLElement): HTMLElement { if (!this._element) { this._element = document.createElement('div'); this._element.classList.add('terminal-sticky-scroll'); - // TODO: listen to font changes - const font = this._terminalService.configHelper.getFont(); - this._element.style.fontSize = `${font.fontSize}px`; - this._element.style.fontFamily = font.fontFamily; - // TODO: Verify these are correct format - this._element.style.letterSpacing = `${font.letterSpacing}px`; - this._element.style.lineHeight = `${font.lineHeight * font.fontSize}px`; - // TODO: Safety - container.querySelector('.xterm-screen')!.append(this._element); + // // TODO: Safety + this._xterm!.raw.element!.parentElement!.append(this._element); + + + // TODO: Add to a container outside the xterm instance? + // TODO: Remove ! + this._stickyScrollOverlay!.open(this._element); } + return this._element; } + + private _syncOptions(target: RawXtermTerminal, copyFrom: RawXtermTerminal): void { + const o = copyFrom.options; + target.resize(copyFrom.cols, 1); + target.options = { + // TODO: Support in xterm.js? + // cursorStyle: 'none' + cursorInactiveStyle: 'none', + scrollback: 0, + logLevel: 'off', + theme: this._xterm!.getXtermTheme(), + + documentOverride: o.documentOverride, + fontFamily: o.fontFamily, + fontWeight: o.fontWeight, + fontWeightBold: o.fontWeightBold, + fontSize: o.fontSize, + letterSpacing: o.letterSpacing, + lineHeight: o.lineHeight, + drawBoldTextInBrightColors: o.drawBoldTextInBrightColors, + minimumContrastRatio: o.minimumContrastRatio, + tabStopWidth: o.tabStopWidth, + overviewRulerWidth: o.overviewRulerWidth, + }; + } + + + // TODO: Share ctor + protected async _getCanvasAddonConstructor(): Promise { + if (!CanvasAddon) { + CanvasAddon = (await importAMDNodeModule('@xterm/addon-canvas', 'lib/xterm-addon-canvas.js')).CanvasAddon; + } + return CanvasAddon; + } + + // TODO: Share ctor + protected async _getSerializeAddonConstructor(): Promise { + if (!SerializeAddon) { + SerializeAddon = (await importAMDNodeModule('@xterm/addon-serialize', 'lib/addon-serialize.js')).SerializeAddon; + } + return SerializeAddon; + } } registerTerminalContribution(TerminalStickyScrollContribution.ID, TerminalStickyScrollContribution, true); From bcf5c8f894c8cb97657e5ce27284f23a09a46ded Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 6 Nov 2023 08:00:58 -0800 Subject: [PATCH 026/240] Clean up, track buffer change --- .../contrib/terminal/browser/terminal.ts | 5 +++ .../terminal/browser/xterm/xtermTerminal.ts | 1 + .../terminal.stickyScroll.contribution.ts | 42 +++++++++++-------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index bc02e19edce..c13ea3da3f7 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -1041,6 +1041,11 @@ export interface IXtermTerminal extends IDisposable { */ readonly isFocused: boolean; + /** + * Whether a canvas-based renderer is being used. + */ + readonly isGpuAccelerated: boolean; + /** * Attached the terminal to the given element * @param container Container the terminal will be rendered in diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index db3c84369d7..001c43f1992 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -148,6 +148,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach get findResult(): { resultIndex: number; resultCount: number } | undefined { return this._lastFindResult; } get isStdinDisabled(): boolean { return !!this.raw.options.disableStdin; } + get isGpuAccelerated(): boolean { return !!(this._canvasAddon || this._webglAddon); } private readonly _onDidRequestRunCommand = this._register(new Emitter<{ command: ITerminalCommand; copyAsHtml?: boolean; noNewLine?: boolean }>()); readonly onDidRequestRunCommand = this._onDidRequestRunCommand.event; diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index b473a4671dd..faaea85e909 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -7,19 +7,18 @@ import 'vs/css!./media/stickyScroll'; import { throttle } from 'vs/base/common/decorators'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; -import { ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ITerminalContribution, ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; -import type { ITheme, Terminal as RawXtermTerminal } from '@xterm/xterm'; +import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; import type { CanvasAddon as CanvasAddonType } from '@xterm/addon-canvas'; import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; -import { hide, show } from 'vs/base/browser/dom'; +import { hide, setVisibility, show } from 'vs/base/browser/dom'; import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { importAMDNodeModule } from 'vs/amdX'; -import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; let CanvasAddon: typeof CanvasAddonType; let SerializeAddon: typeof SerializeAddonType; @@ -34,7 +33,8 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi private _xterm?: IXtermTerminal & { raw: RawXtermTerminal }; private _element?: HTMLElement; private _stickyScrollOverlay?: RawXtermTerminal; - private _overlaySerializeAddon?: SerializeAddonType; + private _serializeAddon?: SerializeAddonType; + private _canvasAddon?: CanvasAddonType; constructor( private readonly _instance: ITerminalInstance, @@ -42,14 +42,19 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi widgetManager: TerminalWidgetManager, @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IKeybindingService private readonly _keybindingService: IKeybindingService, - @IThemeService private readonly _themeService: IThemeService, - @ITerminalService private readonly _terminalService: ITerminalService, ) { super(); } xtermReady(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { this._xterm = xterm; + + this.add(xterm.raw.buffer.onBufferChange(buffer => { + const element = this._ensureElement(); + setVisibility(buffer.type === 'normal', element); + })); + + // TODO: Skip these when hidden this.add(xterm.raw.onScroll(() => this._refresh())); this.add(xterm.raw.onLineFeed(() => this._refresh())); // TODO: Disable in alt buffer @@ -61,15 +66,16 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi }); this._stickyScrollOverlay = overlay; this._getSerializeAddonConstructor().then(addonCtor => { - this._overlaySerializeAddon = new addonCtor(); - xterm.raw.loadAddon(this._overlaySerializeAddon); + this._serializeAddon = new addonCtor(); + xterm.raw.loadAddon(this._serializeAddon); }); - // TODO: Track and sync with real instance - // if (gpu renderer) { - this._getCanvasAddonConstructor().then(addonCtor => { - overlay.loadAddon(new addonCtor()); - }); - // } + // TODO: Sync every render + if (xterm.isGpuAccelerated) { + this._getCanvasAddonConstructor().then(addonCtor => { + this._canvasAddon = new addonCtor(); + overlay.loadAddon(this._canvasAddon); + }); + } }); } @@ -93,7 +99,7 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi if (!marker || marker.line === -1) { return; } - const element = this._ensureElement(this._xterm.raw.element); + const element = this._ensureElement(); // element.textContent = this._xterm.raw.buffer.active.getLine(marker.line)?.translateToString(true) ?? ''; if (element.textContent === '') { hide(element); @@ -106,7 +112,7 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi this._stickyScrollOverlay.write('\x1b[H\x1b[K'); // TODO: Serialize line instead // TODO: Support providing single line/range serialize addon - const s = this._overlaySerializeAddon?.serialize({ + const s = this._serializeAddon?.serialize({ scrollback: this._xterm.raw.buffer.active.baseY - marker.line }); if (s) { @@ -121,7 +127,7 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi } } - private _ensureElement(container: HTMLElement): HTMLElement { + private _ensureElement(): HTMLElement { if (!this._element) { this._element = document.createElement('div'); this._element.classList.add('terminal-sticky-scroll'); From 9050cd75533497f06480488eaa10d393f26b1f49 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 6 Nov 2023 18:06:36 +0100 Subject: [PATCH 027/240] aux window - reduce global access to `window` (#197538) --- .eslintrc.json | 62 +++++++++++++------ src/bootstrap-window.js | 2 + src/vs/amdX.ts | 2 + src/vs/base/browser/broadcast.ts | 11 ++-- src/vs/base/browser/browser.ts | 13 ++-- src/vs/base/browser/canIUse.ts | 5 +- src/vs/base/browser/dom.ts | 34 +++++----- src/vs/base/browser/iframe.ts | 4 +- src/vs/base/browser/indexedDB.ts | 5 +- src/vs/base/browser/mouseEvent.ts | 3 +- src/vs/base/browser/touch.ts | 5 +- src/vs/base/browser/trustedTypes.ts | 3 +- src/vs/base/browser/ui/list/listView.ts | 2 +- src/vs/base/browser/ui/list/listWidget.ts | 4 +- src/vs/base/browser/ui/splitview/paneview.ts | 10 +-- src/vs/base/browser/window.ts | 18 ++++++ .../base/parts/ipc/electron-sandbox/ipc.mp.ts | 5 +- src/vs/code/browser/workbench/callback.html | 2 +- src/vs/code/browser/workbench/workbench.html | 2 +- src/vs/code/browser/workbench/workbench.ts | 37 +++++------ .../issue/issueReporterService.ts | 9 +-- .../processExplorer/processExplorerMain.ts | 13 ++-- .../editor/browser/config/fontMeasurements.ts | 5 +- .../editor/browser/controller/mouseTarget.ts | 13 ++-- .../browser/controller/pointerHandler.ts | 3 +- .../browser/controller/textAreaInput.ts | 5 +- src/vs/editor/browser/editorDom.ts | 5 +- .../editor/browser/services/openerService.ts | 3 +- .../browser/standaloneLayoutService.ts | 3 +- .../standalone/browser/standaloneServices.ts | 3 +- .../browser/standaloneThemeService.ts | 3 +- .../browser/accessibilityService.ts | 3 +- src/vs/platform/dnd/browser/dnd.ts | 3 +- src/vs/platform/log/browser/log.ts | 3 +- .../browser/quickInputController.ts | 3 +- .../remote/browser/browserSocketFactory.ts | 5 +- .../browser/remoteAuthorityResolverService.ts | 3 +- .../test/browser/telemetryService.test.ts | 35 ++++++----- .../browser/userDataProfile.ts | 12 ++-- .../window/electron-sandbox/window.ts | 3 +- .../browser/actions/windowActions.ts | 3 +- src/vs/workbench/browser/contextkeys.ts | 5 +- .../browser/parts/editor/editorPanes.ts | 3 +- .../browser/parts/editor/editorStatus.ts | 4 +- .../browser/parts/titlebar/menubarControl.ts | 3 +- .../browser/parts/titlebar/titlebarPart.ts | 3 +- src/vs/workbench/browser/web.main.ts | 3 +- src/vs/workbench/browser/window.ts | 9 +-- src/vs/workbench/browser/workbench.ts | 7 ++- .../codeEditor/browser/toggleWordWrap.ts | 3 +- .../contrib/debug/browser/debugSession.ts | 3 +- .../contrib/debug/browser/debugToolBar.ts | 15 ++--- .../browser/extensionsWorkbenchService.ts | 3 +- .../contrib/files/browser/fileImportExport.ts | 5 +- .../files/browser/views/explorerViewer.ts | 5 +- .../files/browser/views/openEditorsView.ts | 3 +- .../contrib/find/notebookFindWidget.ts | 12 ++-- .../browser/view/renderers/webviewPreloads.ts | 41 ++++++------ .../contrib/remote/browser/remoteIndicator.ts | 5 +- .../browser/telemetry.contribution.ts | 3 +- .../terminal/browser/terminalConfigHelper.ts | 9 +-- .../terminal/browser/terminalInstance.ts | 11 ++-- .../browser/terminalProcessManager.ts | 5 +- .../terminal/browser/terminalStatusList.ts | 5 +- .../terminal/browser/terminalTabbedView.ts | 6 +- .../terminal/browser/xterm/xtermTerminal.ts | 9 +-- .../links/browser/terminalLink.ts | 3 +- .../links/browser/terminalLinkResolver.ts | 5 +- .../themes/browser/themes.contribution.ts | 5 +- .../contrib/webview/browser/webviewElement.ts | 11 ++-- .../browser/webviewWindowDragMonitor.ts | 7 ++- .../electron-sandbox/desktop.main.ts | 3 +- src/vs/workbench/electron-sandbox/window.ts | 11 ++-- .../browser/auxiliaryWindowService.ts | 9 +-- .../auxiliaryWindowService.ts | 3 +- .../configuration/browser/configuration.ts | 6 +- .../test/browser/configuration.test.ts | 12 ++-- .../dialogs/browser/fileDialogService.ts | 19 +++--- .../services/driver/browser/driver.ts | 3 +- .../driver/electron-sandbox/driver.ts | 3 +- .../extensions/browser/extensionService.ts | 3 +- .../browser/webWorkerExtensionHost.ts | 7 ++- .../host/browser/browserHostService.ts | 9 +-- .../services/hover/browser/hoverService.ts | 5 +- .../services/hover/browser/hoverWidget.ts | 7 ++- .../keybinding/browser/keybindingService.ts | 7 ++- .../lifecycle/browser/lifecycleService.ts | 9 +-- .../localization/browser/localeService.ts | 16 ++--- .../browser/browserHostColorSchemeService.ts | 7 ++- .../themes/browser/fileIconThemeData.ts | 3 +- .../test/browser/workbenchTestServices.ts | 7 ++- 91 files changed, 423 insertions(+), 304 deletions(-) create mode 100644 src/vs/base/browser/window.ts diff --git a/.eslintrc.json b/.eslintrc.json index d7edeea91b8..0c1557f932e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -48,25 +48,6 @@ "orientation", "context" ], // non-complete list of globals that are easy to access unintentionally - "no-restricted-syntax": [ - "warn", - { - "selector": "BinaryExpression[operator='instanceof'][right.name='MouseEvent']", - "message": "Use DOM.isMouseEvent() to support multi-window scenarios." - }, - { - "selector": "BinaryExpression[operator='instanceof'][right.name='KeyboardEvent']", - "message": "Use DOM.isKeyboardEvent() to support multi-window scenarios." - }, - { - "selector": "BinaryExpression[operator='instanceof'][right.name='PointerEvent']", - "message": "Use DOM.isPointerEvent() to support multi-window scenarios." - }, - { - "selector": "BinaryExpression[operator='instanceof'][right.name='DragEvent']", - "message": "Use DOM.isDragEvent() to support multi-window scenarios." - } - ], "no-var": "warn", "jsdoc/no-types": "warn", "semi": "off", @@ -700,6 +681,49 @@ "target": "src/{bootstrap-amd.js,bootstrap-fork.js,bootstrap-node.js,bootstrap-window.js,bootstrap.js,cli.js,main.js,server-cli.js,server-main.js}", "restrictions": [] } + ], + "no-restricted-syntax": [ + "warn", + { + "selector": "BinaryExpression[operator='instanceof'][right.name='MouseEvent']", + "message": "Use DOM.isMouseEvent() to support multi-window scenarios." + }, + { + "selector": "BinaryExpression[operator='instanceof'][right.name='KeyboardEvent']", + "message": "Use DOM.isKeyboardEvent() to support multi-window scenarios." + }, + { + "selector": "BinaryExpression[operator='instanceof'][right.name='PointerEvent']", + "message": "Use DOM.isPointerEvent() to support multi-window scenarios." + }, + { + "selector": "BinaryExpression[operator='instanceof'][right.name='DragEvent']", + "message": "Use DOM.isDragEvent() to support multi-window scenarios." + } + ], + "no-restricted-globals": [ + "warn", + "name", + "length", + "event", + "closed", + "external", + "status", + "origin", + "orientation", + "context", + { + "name": "requestAnimationFrame", + "message": "Use .requestAnimationFrame to support multi-window scenarios." + }, + { + "name": "cancelAnimationFrame", + "message": "Use .cancelAnimationFrame to support multi-window scenarios." + }, + { + "name": "window", + "message": "Be aware of multi-window scenarios: Use DOM.getWindow() or DOM.getActiveWindow() to obtain the correct window for the context you are in. Only use window.ts#mainWindow if you target the main window." + } ] } }, diff --git a/src/bootstrap-window.js b/src/bootstrap-window.js index 04aa152d75f..6334d62afc5 100644 --- a/src/bootstrap-window.js +++ b/src/bootstrap-window.js @@ -8,6 +8,8 @@ //@ts-check 'use strict'; +/* eslint-disable no-restricted-globals */ + // Simple module style to support node.js and browser environments (function (globalThis, factory) { diff --git a/src/vs/amdX.ts b/src/vs/amdX.ts index 75b21c60828..03460284b21 100644 --- a/src/vs/amdX.ts +++ b/src/vs/amdX.ts @@ -57,8 +57,10 @@ class AMDModuleImporter { (globalThis).define.amd = true; if (this._isRenderer) { + // eslint-disable-next-line no-restricted-globals this._amdPolicy = window.trustedTypes?.createPolicy('amdLoader', { createScriptURL(value) { + // eslint-disable-next-line no-restricted-globals if (value.startsWith(window.location.origin)) { return value; } diff --git a/src/vs/base/browser/broadcast.ts b/src/vs/base/browser/broadcast.ts index d7785f42ff8..53c921fdb2e 100644 --- a/src/vs/base/browser/broadcast.ts +++ b/src/vs/base/browser/broadcast.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { mainWindow } from 'vs/base/browser/window'; import { getErrorMessage } from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; @@ -18,7 +19,7 @@ export class BroadcastDataChannel extends Disposable { super(); // Use BroadcastChannel - if ('BroadcastChannel' in window) { + if ('BroadcastChannel' in mainWindow) { try { this.broadcastChannel = new BroadcastChannel(channelName); const listener = (event: MessageEvent) => { @@ -49,8 +50,8 @@ export class BroadcastDataChannel extends Disposable { this._onDidReceiveData.fire(JSON.parse(event.newValue)); } }; - window.addEventListener('storage', listener); - this._register(toDisposable(() => window.removeEventListener('storage', listener))); + mainWindow.addEventListener('storage', listener); + this._register(toDisposable(() => mainWindow.removeEventListener('storage', listener))); } /** @@ -62,8 +63,8 @@ export class BroadcastDataChannel extends Disposable { this.broadcastChannel.postMessage(data); } else { // remove previous changes so that event is triggered even if new changes are same as old changes - window.localStorage.removeItem(this.channelName); - window.localStorage.setItem(this.channelName, JSON.stringify(data)); + localStorage.removeItem(this.channelName); + localStorage.setItem(this.channelName, JSON.stringify(data)); } } } diff --git a/src/vs/base/browser/browser.ts b/src/vs/base/browser/browser.ts index 2ac4671e497..de37d415e03 100644 --- a/src/vs/base/browser/browser.ts +++ b/src/vs/base/browser/browser.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { $window } from 'vs/base/browser/window'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, markAsSingleton } from 'vs/base/common/lifecycle'; @@ -73,7 +74,7 @@ class DevicePixelRatioMonitor extends Disposable { private _handleChange(fireEvent: boolean): void { this._mediaQueryList?.removeEventListener('change', this._listener); - this._mediaQueryList = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`); + this._mediaQueryList = $window.matchMedia(`(resolution: ${$window.devicePixelRatio}dppx)`); this._mediaQueryList.addEventListener('change', this._listener); if (fireEvent) { @@ -107,7 +108,7 @@ class PixelRatioImpl extends Disposable { private _getPixelRatio(): number { const ctx: any = document.createElement('canvas').getContext('2d'); - const dpr = window.devicePixelRatio || 1; + const dpr = $window.devicePixelRatio || 1; const bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || @@ -144,7 +145,7 @@ class PixelRatioFacade { export function addMatchMediaChangeListener(query: string | MediaQueryList, callback: (this: MediaQueryList, ev: MediaQueryListEvent) => any): void { if (typeof query === 'string') { - query = window.matchMedia(query); + query = $window.matchMedia(query); } query.addEventListener('change', callback); } @@ -193,9 +194,9 @@ export const isElectron = (userAgent.indexOf('Electron/') >= 0); export const isAndroid = (userAgent.indexOf('Android') >= 0); let standalone = false; -if (window.matchMedia) { - const standaloneMatchMedia = window.matchMedia('(display-mode: standalone) or (display-mode: window-controls-overlay)'); - const fullScreenMatchMedia = window.matchMedia('(display-mode: fullscreen)'); +if ($window.matchMedia) { + const standaloneMatchMedia = $window.matchMedia('(display-mode: standalone) or (display-mode: window-controls-overlay)'); + const fullScreenMatchMedia = $window.matchMedia('(display-mode: fullscreen)'); standalone = standaloneMatchMedia.matches; addMatchMediaChangeListener(standaloneMatchMedia, ({ matches }) => { // entering fullscreen would change standaloneMatchMedia.matches to false diff --git a/src/vs/base/browser/canIUse.ts b/src/vs/base/browser/canIUse.ts index a759f7085db..c126a33b45b 100644 --- a/src/vs/base/browser/canIUse.ts +++ b/src/vs/base/browser/canIUse.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as browser from 'vs/base/browser/browser'; +import { mainWindow } from 'vs/base/browser/window'; import * as platform from 'vs/base/common/platform'; export const enum KeyboardSupport { @@ -41,6 +42,6 @@ export const BrowserFeatures = { // 'ontouchstart' in window always evaluates to true with typescript's modern typings. This causes `window` to be // `never` later in `window.navigator`. That's why we need the explicit `window as Window` cast - touch: 'ontouchstart' in window || navigator.maxTouchPoints > 0, - pointerEvents: window.PointerEvent && ('ontouchstart' in window || (window as Window).navigator.maxTouchPoints > 0 || navigator.maxTouchPoints > 0) + touch: 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0, + pointerEvents: mainWindow.PointerEvent && ('ontouchstart' in mainWindow || navigator.maxTouchPoints > 0 || navigator.maxTouchPoints > 0) }; diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 0d6a8f3709b..59c5aad6a10 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -17,10 +17,7 @@ import { FileAccess, RemoteAuthorities, Schemas } from 'vs/base/common/network'; import * as platform from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { hash } from 'vs/base/common/hash'; - -export type CodeWindow = Window & typeof globalThis & { - readonly vscodeWindowId: number; -}; +import { CodeWindow, mainWindow, $window } from 'vs/base/browser/window'; interface IRegisteredCodeWindow { readonly window: CodeWindow; @@ -30,9 +27,8 @@ interface IRegisteredCodeWindow { export const { registerWindow, getWindows, getWindowsCount, getWindowId, onDidRegisterWindow, onWillUnregisterWindow, onDidUnregisterWindow } = (function () { const windows = new Map(); - const mainWindow = window as CodeWindow; if (typeof mainWindow.vscodeWindowId !== 'number') { - Object.defineProperty(window, 'vscodeWindowId', { + Object.defineProperty(mainWindow, 'vscodeWindowId', { get: () => 1 }); } @@ -803,7 +799,7 @@ export function getActiveDocument(): Document { export function getActiveWindow(): CodeWindow { const document = getActiveDocument(); - return (document.defaultView?.window ?? window) as CodeWindow; + return (document.defaultView?.window ?? mainWindow) as CodeWindow; } export function getWindow(element: Node | undefined | null): CodeWindow; @@ -819,7 +815,7 @@ export function getWindow(e: unknown): CodeWindow { return candidateEvent.view.window as CodeWindow; } - return window as CodeWindow; + return mainWindow; } export function focusWindow(element: Node): void { @@ -844,7 +840,7 @@ export function createStyleSheet(container: HTMLElement = document.head, beforeA // to support auxiliary windows to clone the stylesheet. if (container === document.head) { for (const { window: targetWindow, disposables } of getWindows()) { - if (targetWindow === window) { + if (targetWindow === mainWindow) { continue; // main window is already tracked } @@ -1183,7 +1179,7 @@ class FocusTracker extends Disposable implements IFocusTracker { const onBlur = () => { if (hasFocus) { loosingFocus = true; - window.setTimeout(() => { + (element instanceof HTMLElement ? getWindow(element) : element).setTimeout(() => { if (loosingFocus) { loosingFocus = false; hasFocus = false; @@ -1441,7 +1437,7 @@ export function windowOpenNoOpener(url: string): void { // See https://developer.mozilla.org/en-US/docs/Web/API/Window/open#noopener // However, this also doesn't allow us to realize if the browser blocked // the creation of the window. - window.open(url, '_blank', 'noopener'); + $window.open(url, '_blank', 'noopener'); } /** @@ -1457,9 +1453,9 @@ export function windowOpenNoOpener(url: string): void { */ const popupWidth = 780, popupHeight = 640; export function windowOpenPopup(url: string): void { - const left = Math.floor(window.screenLeft + window.innerWidth / 2 - popupWidth / 2); - const top = Math.floor(window.screenTop + window.innerHeight / 2 - popupHeight / 2); - window.open( + const left = Math.floor($window.screenLeft + $window.innerWidth / 2 - popupWidth / 2); + const top = Math.floor($window.screenTop + $window.innerHeight / 2 - popupHeight / 2); + $window.open( url, '_blank', `width=${popupWidth},height=${popupHeight},top=${top},left=${left}` @@ -1482,7 +1478,7 @@ export function windowOpenPopup(url: string): void { * @returns boolean indicating if the {@link window.open} call succeeded */ export function windowOpenWithSuccess(url: string, noOpener = true): boolean { - const newTab = window.open(); + const newTab = $window.open(); if (newTab) { if (noOpener) { // see `windowOpenNoOpener` for details on why this is important @@ -1504,7 +1500,7 @@ export function animate(fn: () => void, targetWindow: Window): IDisposable { return toDisposable(() => stepDisposable.dispose()); } -RemoteAuthorities.setPreferredWebSchema(/^https:/.test(window.location.href) ? 'https' : 'http'); +RemoteAuthorities.setPreferredWebSchema(/^https:/.test(mainWindow.location.href) ? 'https' : 'http'); /** * returns url('...') @@ -1628,7 +1624,7 @@ export function detectFullscreen(): IDetectedFullscreen | null { // height and comparing that to window height, we can guess // it though. - if (window.innerHeight === screen.height) { + if ($window.innerHeight === screen.height) { // if the height of the window matches the screen height, we can // safely assume that the browser is fullscreen because no browser // chrome is taking height away (e.g. like toolbars). @@ -1637,7 +1633,7 @@ export function detectFullscreen(): IDetectedFullscreen | null { if (platform.isMacintosh || platform.isLinux) { // macOS and Linux do not properly report `innerHeight`, only Windows does - if (window.outerHeight === screen.height && window.outerWidth === screen.width) { + if ($window.outerHeight === screen.height && $window.outerWidth === screen.width) { // if the height of the browser matches the screen height, we can // only guess that we are in fullscreen. It is also possible that // the user has turned off taskbars in the OS and the browser is @@ -1842,7 +1838,7 @@ export class ModifierKeyEmitter extends event.Emitter { metaKey: false }; - this._subscriptions.add(event.Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposables }) => this.registerListeners(window, disposables), { window, disposables: this._subscriptions })); + this._subscriptions.add(event.Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposables }) => this.registerListeners(window, disposables), { window: mainWindow, disposables: this._subscriptions })); } private registerListeners(window: Window, disposables: DisposableStore): void { diff --git a/src/vs/base/browser/iframe.ts b/src/vs/base/browser/iframe.ts index 2a32decc492..9de541e0e31 100644 --- a/src/vs/base/browser/iframe.ts +++ b/src/vs/base/browser/iframe.ts @@ -3,6 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { $window } from 'vs/base/browser/window'; + /** * Represents a window in a possible chain of iframes */ @@ -51,7 +53,7 @@ export class IframeUtils { public static getSameOriginWindowChain(): IWindowChainElement[] { if (!sameOriginWindowChainCache) { sameOriginWindowChainCache = []; - let w: Window | null = window; + let w: Window | null = $window; let parent: Window | null; do { parent = getParentWindowIfSameOrigin(w); diff --git a/src/vs/base/browser/indexedDB.ts b/src/vs/base/browser/indexedDB.ts index e04e5c8a62a..867525c0982 100644 --- a/src/vs/base/browser/indexedDB.ts +++ b/src/vs/base/browser/indexedDB.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { mainWindow } from 'vs/base/browser/window'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { getErrorMessage } from 'vs/base/common/errors'; import { mark } from 'vs/base/common/performance'; @@ -54,7 +55,7 @@ export class IndexedDB { private static doOpenDatabase(name: string, version: number | undefined, stores: string[]): Promise { return new Promise((c, e) => { - const request = window.indexedDB.open(name, version); + const request = mainWindow.indexedDB.open(name, version); request.onerror = () => e(request.error); request.onsuccess = () => { const db = request.result; @@ -84,7 +85,7 @@ export class IndexedDB { indexedDB.close(); // Delete the db - const deleteRequest = window.indexedDB.deleteDatabase(indexedDB.name); + const deleteRequest = mainWindow.indexedDB.deleteDatabase(indexedDB.name); deleteRequest.onerror = (err) => e(deleteRequest.error); deleteRequest.onsuccess = () => c(); }); diff --git a/src/vs/base/browser/mouseEvent.ts b/src/vs/base/browser/mouseEvent.ts index bdfbf2ed661..d1f172433a6 100644 --- a/src/vs/base/browser/mouseEvent.ts +++ b/src/vs/base/browser/mouseEvent.ts @@ -5,6 +5,7 @@ import * as browser from 'vs/base/browser/browser'; import { IframeUtils } from 'vs/base/browser/iframe'; +import { $window } from 'vs/base/browser/window'; import * as platform from 'vs/base/common/platform'; export interface IMouseEvent { @@ -74,7 +75,7 @@ export class StandardMouseEvent implements IMouseEvent { } // Find the position of the iframe this code is executing in relative to the iframe where the event was captured. - const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(window, e.view); + const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow($window, e.view); this.posx -= iframeOffsets.left; this.posy -= iframeOffsets.top; } diff --git a/src/vs/base/browser/touch.ts b/src/vs/base/browser/touch.ts index 23607237cd2..bee0173f746 100644 --- a/src/vs/base/browser/touch.ts +++ b/src/vs/base/browser/touch.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as DomUtils from 'vs/base/browser/dom'; +import { mainWindow } from 'vs/base/browser/window'; import * as arrays from 'vs/base/common/arrays'; import { memoize } from 'vs/base/common/decorators'; import { Event as EventUtils } from 'vs/base/common/event'; @@ -95,7 +96,7 @@ export class Gesture extends Disposable { disposables.add(DomUtils.addDisposableListener(window.document, 'touchstart', (e: TouchEvent) => this.onTouchStart(e), { passive: false })); disposables.add(DomUtils.addDisposableListener(window.document, 'touchend', (e: TouchEvent) => this.onTouchEnd(window, e))); disposables.add(DomUtils.addDisposableListener(window.document, 'touchmove', (e: TouchEvent) => this.onTouchMove(e), { passive: false })); - }, { window, disposables: this._store })); + }, { window: mainWindow, disposables: this._store })); } public static addTarget(element: HTMLElement): IDisposable { @@ -126,7 +127,7 @@ export class Gesture extends Disposable { static isTouchDevice(): boolean { // `'ontouchstart' in window` always evaluates to true with typescript's modern typings. This causes `window` to be // `never` later in `window.navigator`. That's why we need the explicit `window as Window` cast - return 'ontouchstart' in window || navigator.maxTouchPoints > 0; + return 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0; } public override dispose(): void { diff --git a/src/vs/base/browser/trustedTypes.ts b/src/vs/base/browser/trustedTypes.ts index 4503f210481..48c02ca8c97 100644 --- a/src/vs/base/browser/trustedTypes.ts +++ b/src/vs/base/browser/trustedTypes.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { mainWindow } from 'vs/base/browser/window'; import { onUnexpectedError } from 'vs/base/common/errors'; export function createTrustedTypesPolicy( @@ -27,7 +28,7 @@ export function createTrustedTypesPolicy implements IListView { item.row.domNode.style.width = 'fit-content'; item.width = getContentWidth(item.row.domNode); - const style = window.getComputedStyle(item.row.domNode); + const style = getWindow(item.row.domNode).getComputedStyle(item.row.domNode); if (style.paddingLeft) { item.width += parseFloat(style.paddingLeft); diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 60f2ee87f1e..3e9303d586d 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IDragAndDropData } from 'vs/base/browser/dnd'; -import { asCssValueWithDefault, createStyleSheet, Dimension, EventHelper, getActiveElement, isActiveElement, isMouseEvent } from 'vs/base/browser/dom'; +import { asCssValueWithDefault, createStyleSheet, Dimension, EventHelper, getActiveElement, getWindow, isActiveElement, isMouseEvent } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { Gesture } from 'vs/base/browser/touch'; @@ -618,7 +618,7 @@ class DOMFocusController implements IDisposable { return; } - const style = window.getComputedStyle(tabIndexElement); + const style = getWindow(tabIndexElement).getComputedStyle(tabIndexElement); if (style.visibility === 'hidden' || style.display === 'none') { return; } diff --git a/src/vs/base/browser/ui/splitview/paneview.ts b/src/vs/base/browser/ui/splitview/paneview.ts index 2747c01eff2..0b519e43411 100644 --- a/src/vs/base/browser/ui/splitview/paneview.ts +++ b/src/vs/base/browser/ui/splitview/paneview.ts @@ -5,7 +5,7 @@ import { isFirefox } from 'vs/base/browser/browser'; import { DataTransfers } from 'vs/base/browser/dnd'; -import { $, addDisposableListener, append, clearNode, EventHelper, EventType, trackFocus } from 'vs/base/browser/dom'; +import { $, addDisposableListener, append, clearNode, EventHelper, EventType, getWindow, trackFocus } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { Gesture, EventType as TouchEventType } from 'vs/base/browser/touch'; @@ -175,11 +175,11 @@ export abstract class Pane extends Disposable implements IView { } if (typeof this.animationTimer === 'number') { - clearTimeout(this.animationTimer); + getWindow(this.element).clearTimeout(this.animationTimer); } append(this.element, this.body); } else { - this.animationTimer = window.setTimeout(() => { + this.animationTimer = getWindow(this.element).setTimeout(() => { this.body.remove(); }, 200); } @@ -636,12 +636,12 @@ export class PaneView extends Disposable { private setupAnimation(): void { if (typeof this.animationTimer === 'number') { - window.clearTimeout(this.animationTimer); + getWindow(this.element).clearTimeout(this.animationTimer); } this.element.classList.add('animated'); - this.animationTimer = window.setTimeout(() => { + this.animationTimer = getWindow(this.element).setTimeout(() => { this.animationTimer = undefined; this.element.classList.remove('animated'); }, 200); diff --git a/src/vs/base/browser/window.ts b/src/vs/base/browser/window.ts new file mode 100644 index 00000000000..dde39958ff4 --- /dev/null +++ b/src/vs/base/browser/window.ts @@ -0,0 +1,18 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export type CodeWindow = Window & typeof globalThis & { + readonly vscodeWindowId: number; +}; + +// eslint-disable-next-line no-restricted-globals +export const mainWindow = window as CodeWindow; + +/** + * @deprecated to support multi-window scenarios, use `DOM.mainWindow` + * if you target the main global window or use helpers such as `DOM.getWindow()` + * or `DOM.getActiveWindow()` to obtain the correct window for the context you are in. + */ +export const $window = mainWindow; diff --git a/src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts b/src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts index cd6ea8fa3b2..bc2bfd17892 100644 --- a/src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts +++ b/src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { mainWindow } from 'vs/base/browser/window'; import { Event } from 'vs/base/common/event'; import { generateUuid } from 'vs/base/common/uuid'; import { ipcMessagePort, ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals'; @@ -28,8 +29,8 @@ export async function acquirePort(requestChannel: string | undefined, responseCh // Wait until the main side has returned the `MessagePort` // We need to filter by the `nonce` to ensure we listen // to the right response. - const onMessageChannelResult = Event.fromDOMEventEmitter(window, 'message', (e: MessageEvent) => ({ nonce: e.data, port: e.ports[0], source: e.source })); - const { port } = await Event.toPromise(Event.once(Event.filter(onMessageChannelResult, e => e.nonce === nonce && e.source === window))); + const onMessageChannelResult = Event.fromDOMEventEmitter(mainWindow, 'message', (e: MessageEvent) => ({ nonce: e.data, port: e.ports[0], source: e.source })); + const { port } = await Event.toPromise(Event.once(Event.filter(onMessageChannelResult, e => e.nonce === nonce && e.source === mainWindow))); return port; } diff --git a/src/vs/code/browser/workbench/callback.html b/src/vs/code/browser/workbench/callback.html index cd12754b170..4f54d4d1c97 100644 --- a/src/vs/code/browser/workbench/callback.html +++ b/src/vs/code/browser/workbench/callback.html @@ -61,7 +61,7 @@ uri.fragment = fragment; } - window.localStorage.setItem(`vscode-web.url-callbacks[${id}]`, JSON.stringify(uri)); + localStorage.setItem(`vscode-web.url-callbacks[${id}]`, JSON.stringify(uri)); diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index addc28f0c4d..700231f0357 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -45,7 +45,7 @@ const nlsConfig = {}; // Normalize locale to lowercase because translationServiceUrl is case-sensitive. // ref: https://github.com/microsoft/vscode/issues/187795 - const locale = window.localStorage.getItem('vscode.nls.locale') || navigator.language.toLowerCase(); + const locale = localStorage.getItem('vscode.nls.locale') || navigator.language.toLowerCase(); if (!locale.startsWith('en')) { nlsConfig['vs/nls'] = { availableLanguages: { diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts index 962e2f4c314..0a6b1d6d4e9 100644 --- a/src/vs/code/browser/workbench/workbench.ts +++ b/src/vs/code/browser/workbench/workbench.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { isStandalone } from 'vs/base/browser/browser'; +import { mainWindow } from 'vs/base/browser/window'; import { VSBuffer, decodeBase64, encodeBase64 } from 'vs/base/common/buffer'; import { Emitter } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; @@ -56,18 +57,18 @@ class ServerKeyedAESCrypto implements ISecretStorageCrypto { async seal(data: string): Promise { // Get a new key and IV on every change, to avoid the risk of reusing the same key and IV pair with AES-GCM // (see also: https://developer.mozilla.org/en-US/docs/Web/API/AesGcmParams#properties) - const iv = window.crypto.getRandomValues(new Uint8Array(AESConstants.IV_LENGTH)); + const iv = mainWindow.crypto.getRandomValues(new Uint8Array(AESConstants.IV_LENGTH)); // crypto.getRandomValues isn't a good-enough PRNG to generate crypto keys, so we need to use crypto.subtle.generateKey and export the key instead - const clientKeyObj = await window.crypto.subtle.generateKey( + const clientKeyObj = await mainWindow.crypto.subtle.generateKey( { name: AESConstants.ALGORITHM as const, length: AESConstants.KEY_LENGTH as const }, true, ['encrypt', 'decrypt'] ); - const clientKey = new Uint8Array(await window.crypto.subtle.exportKey('raw', clientKeyObj)); + const clientKey = new Uint8Array(await mainWindow.crypto.subtle.exportKey('raw', clientKeyObj)); const key = await this.getKey(clientKey); const dataUint8Array = new TextEncoder().encode(data); - const cipherText: ArrayBuffer = await window.crypto.subtle.encrypt( + const cipherText: ArrayBuffer = await mainWindow.crypto.subtle.encrypt( { name: AESConstants.ALGORITHM as const, iv }, key, dataUint8Array @@ -95,7 +96,7 @@ class ServerKeyedAESCrypto implements ISecretStorageCrypto { // Do the decryption and parse the result as JSON const key = await this.getKey(clientKey.buffer); - const decrypted = await window.crypto.subtle.decrypt( + const decrypted = await mainWindow.crypto.subtle.decrypt( { name: AESConstants.ALGORITHM as const, iv: iv.buffer }, key, cipherText.buffer @@ -120,7 +121,7 @@ class ServerKeyedAESCrypto implements ISecretStorageCrypto { keyData[i] = clientKey[i]! ^ serverKey[i]!; } - return window.crypto.subtle.importKey( + return mainWindow.crypto.subtle.importKey( 'raw', keyData, { @@ -179,7 +180,7 @@ export class LocalStorageSecretStorageProvider implements ISecretStorageProvider private async load(): Promise> { const record = this.loadAuthSessionFromElement(); // Get the secrets from localStorage - const encrypted = window.localStorage.getItem(this._storageKey); + const encrypted = localStorage.getItem(this._storageKey); if (encrypted) { try { const decrypted = JSON.parse(await this.crypto.unseal(encrypted)); @@ -187,7 +188,7 @@ export class LocalStorageSecretStorageProvider implements ISecretStorageProvider } catch (err) { // TODO: send telemetry console.error('Failed to decrypt secrets from localStorage', err); - window.localStorage.removeItem(this._storageKey); + localStorage.removeItem(this._storageKey); } } @@ -249,7 +250,7 @@ export class LocalStorageSecretStorageProvider implements ISecretStorageProvider private async save(): Promise { try { const encrypted = await this.crypto.seal(JSON.stringify(await this._secretsPromise)); - window.localStorage.setItem(this._storageKey, encrypted); + localStorage.setItem(this._storageKey, encrypted); } catch (err) { console.error(err); } @@ -298,13 +299,13 @@ class LocalStorageURLCallbackProvider extends Disposable implements IURLCallback // https://github.com/microsoft/vscode/blob/159479eb5ae451a66b5dac3c12d564f32f454796/extensions/github-authentication/src/githubServer.ts#L50-L50 if (!(options.authority === 'vscode.github-authentication' && options.path === '/dummy')) { const key = `vscode-web.url-callbacks[${id}]`; - window.localStorage.removeItem(key); + localStorage.removeItem(key); this.pendingCallbacks.add(id); this.startListening(); } - return URI.parse(window.location.href).with({ path: this._callbackRoute, query: queryParams.join('&') }); + return URI.parse(mainWindow.location.href).with({ path: this._callbackRoute, query: queryParams.join('&') }); } private startListening(): void { @@ -313,8 +314,8 @@ class LocalStorageURLCallbackProvider extends Disposable implements IURLCallback } const fn = () => this.onDidChangeLocalStorage(); - window.addEventListener('storage', fn); - this.onDidChangeLocalStorageDisposable = { dispose: () => window.removeEventListener('storage', fn) }; + mainWindow.addEventListener('storage', fn); + this.onDidChangeLocalStorageDisposable = { dispose: () => mainWindow.removeEventListener('storage', fn) }; } private stopListening(): void { @@ -342,7 +343,7 @@ class LocalStorageURLCallbackProvider extends Disposable implements IURLCallback for (const id of this.pendingCallbacks) { const key = `vscode-web.url-callbacks[${id}]`; - const result = window.localStorage.getItem(key); + const result = localStorage.getItem(key); if (result !== null) { try { @@ -353,7 +354,7 @@ class LocalStorageURLCallbackProvider extends Disposable implements IURLCallback pendingCallbacks = pendingCallbacks ?? new Set(this.pendingCallbacks); pendingCallbacks.delete(id); - window.localStorage.removeItem(key); + localStorage.removeItem(key); } } @@ -459,14 +460,14 @@ class WorkspaceProvider implements IWorkspaceProvider { const targetHref = this.createTargetUrl(workspace, options); if (targetHref) { if (options?.reuse) { - window.location.href = targetHref; + mainWindow.location.href = targetHref; return true; } else { let result; if (isStandalone()) { - result = window.open(targetHref, '_blank', 'toolbar=no'); // ensures to open another 'standalone' window! + result = mainWindow.open(targetHref, '_blank', 'toolbar=no'); // ensures to open another 'standalone' window! } else { - result = window.open(targetHref); + result = mainWindow.open(targetHref); } return !!result; diff --git a/src/vs/code/electron-sandbox/issue/issueReporterService.ts b/src/vs/code/electron-sandbox/issue/issueReporterService.ts index afb7a654c09..58761964f6a 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterService.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterService.ts @@ -5,6 +5,7 @@ import { $, createStyleSheet, reset, windowOpenNoOpener } from 'vs/base/browser/dom'; import { Button, unthemedButtonStyles } from 'vs/base/browser/ui/button/button'; import { renderIcon } from 'vs/base/browser/ui/iconLabel/iconLabels'; +import { mainWindow } from 'vs/base/browser/window'; import { Delayer, RunOnceScheduler } from 'vs/base/common/async'; import { Codicon } from 'vs/base/common/codicons'; import { groupBy } from 'vs/base/common/collections'; @@ -107,7 +108,7 @@ export class IssueReporter extends Disposable { }); } - if (window.document.documentElement.lang !== 'en') { + if (mainWindow.document.documentElement.lang !== 'en') { show(this.getElementById('english')); } @@ -569,7 +570,7 @@ export class IssueReporter extends Disposable { const query = `is:issue+repo:${repo}+${title}`; const similarIssues = this.getElementById('similar-issues')!; - window.fetch(`https://api.github.com/search/issues?q=${query}`).then((response) => { + fetch(`https://api.github.com/search/issues?q=${query}`).then((response) => { response.json().then(result => { similarIssues.innerText = ''; if (result && result.items) { @@ -612,7 +613,7 @@ export class IssueReporter extends Disposable { }) }; - window.fetch(url, init).then((response) => { + fetch(url, init).then((response) => { response.json().then(result => { this.clearSearchResults(); @@ -868,7 +869,7 @@ export class IssueReporter extends Disposable { }) }; - const response = await window.fetch(url, init); + const response = await fetch(url, init); if (!response.ok) { return false; } diff --git a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts index b6d0fc503f7..1d5a3567fd8 100644 --- a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts @@ -25,6 +25,7 @@ import { getIconsStyleSheet } from 'vs/platform/theme/browser/iconsStyleSheet'; import { applyZoom, zoomIn, zoomOut } from 'vs/platform/window/electron-sandbox/window'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; +import { mainWindow } from 'vs/base/browser/window'; const DEBUG_FLAGS_PATTERN = /\s--inspect(?:-brk|port)?=(?\d+)?/; const DEBUG_PORT_PATTERN = /\s--inspect-port=(?\d+)/; @@ -262,7 +263,7 @@ class ProcessExplorer { await this.createProcessTree(processRoots); } else { this.tree.setInput({ processes: { processRoots } }); - this.tree.layout(window.innerHeight, window.innerWidth); + this.tree.layout(mainWindow.innerHeight, mainWindow.innerWidth); } this.requestProcessList(0); @@ -342,7 +343,7 @@ class ProcessExplorer { }); this.tree.setInput({ processes: { processRoots } }); - this.tree.layout(window.innerHeight, window.innerWidth); + this.tree.layout(mainWindow.innerHeight, mainWindow.innerWidth); this.tree.onKeyDown(e => { const event = new StandardKeyboardEvent(e); if (event.keyCode === KeyCode.KeyE && event.altKey) { @@ -356,11 +357,11 @@ class ProcessExplorer { } }); - container.style.height = `${window.innerHeight}px`; + container.style.height = `${mainWindow.innerHeight}px`; - window.addEventListener('resize', () => { - container.style.height = `${window.innerHeight}px`; - this.tree?.layout(window.innerHeight, window.innerWidth); + mainWindow.addEventListener('resize', () => { + container.style.height = `${mainWindow.innerHeight}px`; + this.tree?.layout(mainWindow.innerHeight, mainWindow.innerWidth); }); } diff --git a/src/vs/editor/browser/config/fontMeasurements.ts b/src/vs/editor/browser/config/fontMeasurements.ts index 952c207f209..64a5057aea9 100644 --- a/src/vs/editor/browser/config/fontMeasurements.ts +++ b/src/vs/editor/browser/config/fontMeasurements.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as browser from 'vs/base/browser/browser'; +import { $window } from 'vs/base/browser/window'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { CharWidthRequest, CharWidthRequestType, readCharWidths } from 'vs/editor/browser/config/charWidthReader'; @@ -50,7 +51,7 @@ export class FontMeasurementsImpl extends Disposable { public override dispose(): void { if (this._evictUntrustedReadingsTimeout !== -1) { - window.clearTimeout(this._evictUntrustedReadingsTimeout); + $window.clearTimeout(this._evictUntrustedReadingsTimeout); this._evictUntrustedReadingsTimeout = -1; } super.dispose(); @@ -69,7 +70,7 @@ export class FontMeasurementsImpl extends Disposable { if (!value.isTrusted && this._evictUntrustedReadingsTimeout === -1) { // Try reading again after some time - this._evictUntrustedReadingsTimeout = window.setTimeout(() => { + this._evictUntrustedReadingsTimeout = $window.setTimeout(() => { this._evictUntrustedReadingsTimeout = -1; this._evictUntrustedReadings(); }, 5000); diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index 4c57874ba42..9f09b02f397 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -20,6 +20,7 @@ import * as dom from 'vs/base/browser/dom'; import { AtomicTabMoveOperations, Direction } from 'vs/editor/common/cursor/cursorAtomicMoveOperations'; import { PositionAffinity } from 'vs/editor/common/model'; import { InjectedText } from 'vs/editor/common/modelLineProjectionData'; +import { $window } from 'vs/base/browser/window'; const enum HitTestResultType { Unknown, @@ -1046,12 +1047,12 @@ function shadowCaretRangeFromPoint(shadowRoot: ShadowRoot, x: number, y: number) const rect = el.getBoundingClientRect(); // And its font (the computed shorthand font property might be empty, see #3217) - const fontStyle = window.getComputedStyle(el, null).getPropertyValue('font-style'); - const fontVariant = window.getComputedStyle(el, null).getPropertyValue('font-variant'); - const fontWeight = window.getComputedStyle(el, null).getPropertyValue('font-weight'); - const fontSize = window.getComputedStyle(el, null).getPropertyValue('font-size'); - const lineHeight = window.getComputedStyle(el, null).getPropertyValue('line-height'); - const fontFamily = window.getComputedStyle(el, null).getPropertyValue('font-family'); + const fontStyle = $window.getComputedStyle(el, null).getPropertyValue('font-style'); + const fontVariant = $window.getComputedStyle(el, null).getPropertyValue('font-variant'); + const fontWeight = $window.getComputedStyle(el, null).getPropertyValue('font-weight'); + const fontSize = $window.getComputedStyle(el, null).getPropertyValue('font-size'); + const lineHeight = $window.getComputedStyle(el, null).getPropertyValue('line-height'); + const fontFamily = $window.getComputedStyle(el, null).getPropertyValue('font-family'); const font = `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize}/${lineHeight} ${fontFamily}`; // And also its txt content diff --git a/src/vs/editor/browser/controller/pointerHandler.ts b/src/vs/editor/browser/controller/pointerHandler.ts index fc7103855a3..b21e9fb821b 100644 --- a/src/vs/editor/browser/controller/pointerHandler.ts +++ b/src/vs/editor/browser/controller/pointerHandler.ts @@ -15,6 +15,7 @@ import { ViewContext } from 'vs/editor/common/viewModel/viewContext'; import { BrowserFeatures } from 'vs/base/browser/canIUse'; import { TextAreaSyntethicEvents } from 'vs/editor/browser/controller/textAreaInput'; import { NavigationCommandRevealType } from 'vs/editor/browser/coreCommands'; +import { mainWindow } from 'vs/base/browser/window'; /** * Currently only tested on iOS 13/ iPadOS. @@ -138,7 +139,7 @@ export class PointerHandler extends Disposable { super(); if ((platform.isIOS && BrowserFeatures.pointerEvents)) { this.handler = this._register(new PointerEventHandler(context, viewController, viewHelper)); - } else if (window.TouchEvent) { + } else if (mainWindow.TouchEvent) { this.handler = this._register(new TouchHandler(context, viewController, viewHelper)); } else { this.handler = this._register(new MouseHandler(context, viewController, viewHelper)); diff --git a/src/vs/editor/browser/controller/textAreaInput.ts b/src/vs/editor/browser/controller/textAreaInput.ts index f548b74c04f..cc8c58ebbd4 100644 --- a/src/vs/editor/browser/controller/textAreaInput.ts +++ b/src/vs/editor/browser/controller/textAreaInput.ts @@ -8,6 +8,7 @@ import * as dom from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { inputLatency } from 'vs/base/browser/performance'; +import { $window } from 'vs/base/browser/window'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -791,7 +792,7 @@ export class TextAreaWrapper extends Disposable implements ICompleteTextAreaWrap if (currentIsFocused && currentSelectionStart === selectionStart && currentSelectionEnd === selectionEnd) { // No change // Firefox iframe bug https://github.com/microsoft/monaco-editor/issues/643#issuecomment-367871377 - if (browser.isFirefox && window.parent !== window) { + if (browser.isFirefox && $window.parent !== $window) { textArea.focus(); } return; @@ -803,7 +804,7 @@ export class TextAreaWrapper extends Disposable implements ICompleteTextAreaWrap // No need to focus, only need to change the selection range this.setIgnoreSelectionChangeTime('setSelectionRange'); textArea.setSelectionRange(selectionStart, selectionEnd); - if (browser.isFirefox && window.parent !== window) { + if (browser.isFirefox && $window.parent !== $window) { textArea.focus(); } return; diff --git a/src/vs/editor/browser/editorDom.ts b/src/vs/editor/browser/editorDom.ts index e533d4d13ca..24360c0385b 100644 --- a/src/vs/editor/browser/editorDom.ts +++ b/src/vs/editor/browser/editorDom.ts @@ -11,6 +11,7 @@ import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecyc import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { asCssVariable } from 'vs/platform/theme/common/colorRegistry'; import { ThemeColor } from 'vs/base/common/themables'; +import { $window } from 'vs/base/browser/window'; /** * Coordinates relative to the whole document (e.g. mouse event's pageX and pageY) @@ -24,7 +25,7 @@ export class PageCoordinates { ) { } public toClientCoordinates(): ClientCoordinates { - return new ClientCoordinates(this.x - window.scrollX, this.y - window.scrollY); + return new ClientCoordinates(this.x - $window.scrollX, this.y - $window.scrollY); } } @@ -44,7 +45,7 @@ export class ClientCoordinates { ) { } public toPageCoordinates(): PageCoordinates { - return new PageCoordinates(this.clientX + window.scrollX, this.clientY + window.scrollY); + return new PageCoordinates(this.clientX + $window.scrollX, this.clientY + $window.scrollY); } } diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index e329d0eea4d..5e63ede1f3f 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as dom from 'vs/base/browser/dom'; +import { mainWindow } from 'vs/base/browser/window'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IDisposable } from 'vs/base/common/lifecycle'; import { LinkedList } from 'vs/base/common/linkedList'; @@ -122,7 +123,7 @@ export class OpenerService implements IOpenerService { if (matchesSomeScheme(href, Schemas.http, Schemas.https)) { dom.windowOpenNoOpener(href); } else { - window.location.href = href; + mainWindow.location.href = href; } return true; } diff --git a/src/vs/editor/standalone/browser/standaloneLayoutService.ts b/src/vs/editor/standalone/browser/standaloneLayoutService.ts index ae901c68b41..77cb82585a8 100644 --- a/src/vs/editor/standalone/browser/standaloneLayoutService.ts +++ b/src/vs/editor/standalone/browser/standaloneLayoutService.ts @@ -9,6 +9,7 @@ import { ILayoutService, ILayoutOffsetInfo } from 'vs/platform/layout/browser/la import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { coalesce } from 'vs/base/common/arrays'; +import { mainWindow } from 'vs/base/browser/window'; class StandaloneLayoutService implements ILayoutService { declare readonly _serviceBrand: undefined; @@ -20,7 +21,7 @@ class StandaloneLayoutService implements ILayoutService { private _dimension?: dom.IDimension; get mainContainerDimension(): dom.IDimension { if (!this._dimension) { - this._dimension = dom.getClientArea(window.document.body); + this._dimension = dom.getClientArea(mainWindow.document.body); } return this._dimension; diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index 01f2c6987ac..1b01cd7d6af 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -92,6 +92,7 @@ import { LogService } from 'vs/platform/log/common/logService'; import { getEditorFeatures } from 'vs/editor/common/editorFeatures'; import { onUnexpectedError } from 'vs/base/common/errors'; import { ExtensionKind, IEnvironmentService, IExtensionHostDebugParams } from 'vs/platform/environment/common/environment'; +import { mainWindow } from 'vs/base/browser/window'; class SimpleModel implements IResolvedTextEditorModel { @@ -257,7 +258,7 @@ class StandaloneDialogService implements IDialogService { messageText = messageText + '\n\n' + detail; } - return window.confirm(messageText); + return mainWindow.confirm(messageText); } prompt(prompt: IPromptWithCustomCancel): Promise>; diff --git a/src/vs/editor/standalone/browser/standaloneThemeService.ts b/src/vs/editor/standalone/browser/standaloneThemeService.ts index cac2e96a01f..0d1810873da 100644 --- a/src/vs/editor/standalone/browser/standaloneThemeService.ts +++ b/src/vs/editor/standalone/browser/standaloneThemeService.ts @@ -19,6 +19,7 @@ import { Extensions as ThemingExtensions, ICssStyleCollector, IFileIconTheme, IP import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { ColorScheme, isDark, isHighContrast } from 'vs/platform/theme/common/theme'; import { getIconsStyleSheet, UnthemedProductIconTheme } from 'vs/platform/theme/browser/iconsStyleSheet'; +import { mainWindow } from 'vs/base/browser/window'; export const VS_LIGHT_THEME_NAME = 'vs'; export const VS_DARK_THEME_NAME = 'vs-dark'; @@ -353,7 +354,7 @@ export class StandaloneThemeService extends Disposable implements IStandaloneThe private _onOSSchemeChanged() { if (this._autoDetectHighContrast) { - const wantsHighContrast = window.matchMedia(`(forced-colors: active)`).matches; + const wantsHighContrast = mainWindow.matchMedia(`(forced-colors: active)`).matches; if (wantsHighContrast !== isHighContrast(this._theme.type)) { // switch to high contrast or non-high contrast but stick to dark or light let newThemeName; diff --git a/src/vs/platform/accessibility/browser/accessibilityService.ts b/src/vs/platform/accessibility/browser/accessibilityService.ts index 409619555ec..97cd8b57de9 100644 --- a/src/vs/platform/accessibility/browser/accessibilityService.ts +++ b/src/vs/platform/accessibility/browser/accessibilityService.ts @@ -5,6 +5,7 @@ import { addDisposableListener } from 'vs/base/browser/dom'; import { alert } from 'vs/base/browser/ui/aria/aria'; +import { mainWindow } from 'vs/base/browser/window'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { AccessibilitySupport, CONTEXT_ACCESSIBILITY_MODE_ENABLED, IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; @@ -45,7 +46,7 @@ export class AccessibilityService extends Disposable implements IAccessibilitySe updateContextKey(); this._register(this.onDidChangeScreenReaderOptimized(() => updateContextKey())); - const reduceMotionMatcher = window.matchMedia(`(prefers-reduced-motion: reduce)`); + const reduceMotionMatcher = mainWindow.matchMedia(`(prefers-reduced-motion: reduce)`); this._systemMotionReduced = reduceMotionMatcher.matches; this._configMotionReduced = this._configurationService.getValue<'auto' | 'on' | 'off'>('workbench.reduceMotion'); diff --git a/src/vs/platform/dnd/browser/dnd.ts b/src/vs/platform/dnd/browser/dnd.ts index 2046ddb1143..1bd55afefaf 100644 --- a/src/vs/platform/dnd/browser/dnd.ts +++ b/src/vs/platform/dnd/browser/dnd.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { DataTransfers } from 'vs/base/browser/dnd'; +import { mainWindow } from 'vs/base/browser/window'; import { DragMouseEvent } from 'vs/base/browser/mouseEvent'; import { coalesce } from 'vs/base/common/arrays'; import { DeferredPromise } from 'vs/base/common/async'; @@ -182,7 +183,7 @@ interface IFileTransferData { async function extractFilesDropData(accessor: ServicesAccessor, event: DragEvent): Promise { // Try to extract via `FileSystemHandle` - if (WebFileSystemAccess.supported(window)) { + if (WebFileSystemAccess.supported(mainWindow)) { const items = event.dataTransfer?.items; if (items) { return extractFileTransferData(accessor, items); diff --git a/src/vs/platform/log/browser/log.ts b/src/vs/platform/log/browser/log.ts index 246805d1e54..0abfdaa677b 100644 --- a/src/vs/platform/log/browser/log.ts +++ b/src/vs/platform/log/browser/log.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { mainWindow } from 'vs/base/browser/window'; import { relativePath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -75,7 +76,7 @@ export class ConsoleLogInAutomationLogger extends AdapterLogger implements ILogg } private consoleLog(type: string, args: any[]): void { - const automatedWindow = window as unknown as IAutomatedWindow; + const automatedWindow = mainWindow as unknown as IAutomatedWindow; if (typeof automatedWindow.codeAutomationLog === 'function') { try { automatedWindow.codeAutomationLog(type, args); diff --git a/src/vs/platform/quickinput/browser/quickInputController.ts b/src/vs/platform/quickinput/browser/quickInputController.ts index a2f2e4cb1b9..135ece927b5 100644 --- a/src/vs/platform/quickinput/browser/quickInputController.ts +++ b/src/vs/platform/quickinput/browser/quickInputController.ts @@ -22,6 +22,7 @@ import { QuickInputList, QuickInputListFocus } from 'vs/platform/quickinput/brow import { QuickInputUI, Writeable, IQuickInputStyles, IQuickInputOptions, QuickPick, backButton, InputBox, Visibilities, QuickWidget } from 'vs/platform/quickinput/browser/quickInput'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { mainWindow } from 'vs/base/browser/window'; const $ = dom.$; @@ -58,7 +59,7 @@ export class QuickInputController extends Disposable { this.idPrefix = options.idPrefix; this.parentElement = options.container; this.styles = options.styles; - this._register(Event.runAndSubscribe(dom.onDidRegisterWindow, ({ window, disposables }) => this.registerKeyModsListeners(window, disposables), { window, disposables: this._store })); + this._register(Event.runAndSubscribe(dom.onDidRegisterWindow, ({ window, disposables }) => this.registerKeyModsListeners(window, disposables), { window: mainWindow, disposables: this._store })); this._register(dom.onWillUnregisterWindow(window => { if (this.ui && dom.getWindow(this.ui.container) === window) { // The window this quick input is contained in is about to diff --git a/src/vs/platform/remote/browser/browserSocketFactory.ts b/src/vs/platform/remote/browser/browserSocketFactory.ts index 765b2f3fa6f..e8d40cb8ecc 100644 --- a/src/vs/platform/remote/browser/browserSocketFactory.ts +++ b/src/vs/platform/remote/browser/browserSocketFactory.ts @@ -11,6 +11,7 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { ISocket, SocketCloseEvent, SocketCloseEventType, SocketDiagnostics, SocketDiagnosticsEventType } from 'vs/base/parts/ipc/common/ipc.net'; import { ISocketFactory } from 'vs/platform/remote/common/remoteSocketFactoryService'; import { RemoteAuthorityResolverError, RemoteAuthorityResolverErrorCode, RemoteConnectionType, WebSocketRemoteConnection } from 'vs/platform/remote/common/remoteAuthorityResolver'; +import { mainWindow } from 'vs/base/browser/window'; export interface IWebSocketFactory { create(url: string, debugLabel: string): IWebSocket; @@ -154,7 +155,7 @@ class BrowserWebSocket extends Disposable implements IWebSocket { this._isClosed = true; if (pendingErrorEvent) { - if (!window.navigator.onLine) { + if (!navigator.onLine) { // The browser is offline => this is a temporary error which might resolve itself sendErrorNow(new RemoteAuthorityResolverError('Browser is offline', RemoteAuthorityResolverErrorCode.TemporarilyNotAvailable, e)); } else { @@ -279,7 +280,7 @@ export class BrowserSocketFactory implements ISocketFactory { return new Promise((resolve, reject) => { - const webSocketSchema = (/^https:/.test(window.location.href) ? 'wss' : 'ws'); + const webSocketSchema = (/^https:/.test(mainWindow.location.href) ? 'wss' : 'ws'); const socket = this._webSocketFactory.create(`${webSocketSchema}://${(/:/.test(host) && !/\[/.test(host)) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel); const errorListener = socket.onError(reject); socket.onOpen(() => { diff --git a/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts b/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts index 2db24441fb6..529d9d74999 100644 --- a/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts +++ b/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { mainWindow } from 'vs/base/browser/window'; import { DeferredPromise } from 'vs/base/common/async'; import * as errors from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; @@ -84,7 +85,7 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot const connectionToken = await Promise.resolve(this._connectionTokens.get(authority) || this._connectionToken); performance.mark(`code/didResolveConnectionToken/${authorityPrefix}`); this._logService.info(`Resolved connection token (${authorityPrefix}) after ${sw.elapsed()} ms`); - const defaultPort = (/^https:/.test(window.location.href) ? 443 : 80); + const defaultPort = (/^https:/.test(mainWindow.location.href) ? 443 : 80); const { host, port } = parseAuthorityWithOptionalPort(authority, defaultPort); const result: ResolverResult = { authority: { authority, connectTo: new WebSocketRemoteConnection(host, port), connectionToken } }; RemoteAuthorities.set(authority, host, port); diff --git a/src/vs/platform/telemetry/test/browser/telemetryService.test.ts b/src/vs/platform/telemetry/test/browser/telemetryService.test.ts index cbfd8554437..f20eb00d58a 100644 --- a/src/vs/platform/telemetry/test/browser/telemetryService.test.ts +++ b/src/vs/platform/telemetry/test/browser/telemetryService.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import * as sinonTest from 'sinon-test'; +import { mainWindow } from 'vs/base/browser/window'; import * as Errors from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; @@ -269,14 +270,14 @@ suite('TelemetryService', () => { test('Handle global errors', sinonTestFn(function (this: any) { const errorStub = sinon.stub(); - window.onerror = errorStub; + mainWindow.onerror = errorStub; const testAppender = new TestTelemetryAppender(); const service = new TestErrorTelemetryService({ appenders: [testAppender] }); const errorTelemetry = new ErrorTelemetry(service); const testError = new Error('test'); - (window.onerror)('Error Message', 'file.js', 2, 42, testError); + (mainWindow.onerror)('Error Message', 'file.js', 2, 42, testError); this.clock.tick(ErrorTelemetry.ERROR_FLUSH_TIMEOUT); assert.strictEqual(errorStub.alwaysCalledWithExactly('Error Message', 'file.js', 2, 42, testError), true); @@ -297,7 +298,7 @@ suite('TelemetryService', () => { test('Error Telemetry removes PII from filename with spaces', sinonTestFn(function (this: any) { const errorStub = sinon.stub(); - window.onerror = errorStub; + mainWindow.onerror = errorStub; const settings = new ErrorTestingSettings(); const testAppender = new TestTelemetryAppender(); const service = new TestErrorTelemetryService({ appenders: [testAppender] }); @@ -306,7 +307,7 @@ suite('TelemetryService', () => { const personInfoWithSpaces = settings.personalInfo.slice(0, 2) + ' ' + settings.personalInfo.slice(2); const dangerousFilenameError: any = new Error('dangerousFilename'); dangerousFilenameError.stack = settings.stack; - (window.onerror)('dangerousFilename', settings.dangerousPathWithImportantInfo.replace(settings.personalInfo, personInfoWithSpaces) + '/test.js', 2, 42, dangerousFilenameError); + (mainWindow.onerror)('dangerousFilename', settings.dangerousPathWithImportantInfo.replace(settings.personalInfo, personInfoWithSpaces) + '/test.js', 2, 42, dangerousFilenameError); this.clock.tick(ErrorTelemetry.ERROR_FLUSH_TIMEOUT); assert.strictEqual(errorStub.callCount, 1); @@ -321,7 +322,7 @@ suite('TelemetryService', () => { test('Uncaught Error Telemetry removes PII from filename', sinonTestFn(function (this: any) { const clock = this.clock; const errorStub = sinon.stub(); - window.onerror = errorStub; + mainWindow.onerror = errorStub; const settings = new ErrorTestingSettings(); const testAppender = new TestTelemetryAppender(); const service = new TestErrorTelemetryService({ appenders: [testAppender] }); @@ -329,14 +330,14 @@ suite('TelemetryService', () => { let dangerousFilenameError: any = new Error('dangerousFilename'); dangerousFilenameError.stack = settings.stack; - (window.onerror)('dangerousFilename', settings.dangerousPathWithImportantInfo + '/test.js', 2, 42, dangerousFilenameError); + (mainWindow.onerror)('dangerousFilename', settings.dangerousPathWithImportantInfo + '/test.js', 2, 42, dangerousFilenameError); clock.tick(ErrorTelemetry.ERROR_FLUSH_TIMEOUT); assert.strictEqual(errorStub.callCount, 1); assert.strictEqual(testAppender.events[0].data.file.indexOf(settings.dangerousPathWithImportantInfo), -1); dangerousFilenameError = new Error('dangerousFilename'); dangerousFilenameError.stack = settings.stack; - (window.onerror)('dangerousFilename', settings.dangerousPathWithImportantInfo + '/test.js', 2, 42, dangerousFilenameError); + (mainWindow.onerror)('dangerousFilename', settings.dangerousPathWithImportantInfo + '/test.js', 2, 42, dangerousFilenameError); clock.tick(ErrorTelemetry.ERROR_FLUSH_TIMEOUT); assert.strictEqual(errorStub.callCount, 2); assert.strictEqual(testAppender.events[0].data.file.indexOf(settings.dangerousPathWithImportantInfo), -1); @@ -379,7 +380,7 @@ suite('TelemetryService', () => { test('Uncaught Error Telemetry removes PII', sinonTestFn(function (this: any) { const errorStub = sinon.stub(); - window.onerror = errorStub; + mainWindow.onerror = errorStub; const settings = new ErrorTestingSettings(); const testAppender = new TestTelemetryAppender(); const service = new TestErrorTelemetryService({ appenders: [testAppender] }); @@ -387,7 +388,7 @@ suite('TelemetryService', () => { const dangerousPathWithoutImportantInfoError: any = new Error('dangerousPathWithoutImportantInfo'); dangerousPathWithoutImportantInfoError.stack = settings.stack; - (window.onerror)(settings.dangerousPathWithoutImportantInfo, 'test.js', 2, 42, dangerousPathWithoutImportantInfoError); + (mainWindow.onerror)(settings.dangerousPathWithoutImportantInfo, 'test.js', 2, 42, dangerousPathWithoutImportantInfoError); this.clock.tick(ErrorTelemetry.ERROR_FLUSH_TIMEOUT); assert.strictEqual(errorStub.callCount, 1); @@ -441,7 +442,7 @@ suite('TelemetryService', () => { test('Uncaught Error Telemetry removes PII but preserves Code file path', sinonTestFn(function (this: any) { const errorStub = sinon.stub(); - window.onerror = errorStub; + mainWindow.onerror = errorStub; const settings = new ErrorTestingSettings(); const testAppender = new TestTelemetryAppender(); const service = new TestErrorTelemetryService({ appenders: [testAppender] }); @@ -449,7 +450,7 @@ suite('TelemetryService', () => { const dangerousPathWithImportantInfoError: any = new Error('dangerousPathWithImportantInfo'); dangerousPathWithImportantInfoError.stack = settings.stack; - (window.onerror)(settings.dangerousPathWithImportantInfo, 'test.js', 2, 42, dangerousPathWithImportantInfoError); + (mainWindow.onerror)(settings.dangerousPathWithImportantInfo, 'test.js', 2, 42, dangerousPathWithImportantInfoError); this.clock.tick(ErrorTelemetry.ERROR_FLUSH_TIMEOUT); assert.strictEqual(errorStub.callCount, 1); @@ -540,7 +541,7 @@ suite('TelemetryService', () => { test('Uncaught Error Telemetry removes PII but preserves Code file path when PIIPath is configured', sinonTestFn(function (this: any) { const errorStub = sinon.stub(); - window.onerror = errorStub; + mainWindow.onerror = errorStub; const settings = new ErrorTestingSettings(); const testAppender = new TestTelemetryAppender(); const service = new TestErrorTelemetryService({ appenders: [testAppender], piiPaths: [settings.personalInfo + '/resources/app/'] }); @@ -548,7 +549,7 @@ suite('TelemetryService', () => { const dangerousPathWithImportantInfoError: any = new Error('dangerousPathWithImportantInfo'); dangerousPathWithImportantInfoError.stack = settings.stack; - (window.onerror)(settings.dangerousPathWithImportantInfo, 'test.js', 2, 42, dangerousPathWithImportantInfoError); + (mainWindow.onerror)(settings.dangerousPathWithImportantInfo, 'test.js', 2, 42, dangerousPathWithImportantInfoError); this.clock.tick(ErrorTelemetry.ERROR_FLUSH_TIMEOUT); assert.strictEqual(errorStub.callCount, 1); @@ -604,7 +605,7 @@ suite('TelemetryService', () => { test('Uncaught Error Telemetry removes PII but preserves Missing Model error message', sinonTestFn(function (this: any) { const errorStub = sinon.stub(); - window.onerror = errorStub; + mainWindow.onerror = errorStub; const settings = new ErrorTestingSettings(); const testAppender = new TestTelemetryAppender(); const service = new TestErrorTelemetryService({ appenders: [testAppender] }); @@ -612,7 +613,7 @@ suite('TelemetryService', () => { const missingModelError: any = new Error('missingModelMessage'); missingModelError.stack = settings.stack; - (window.onerror)(settings.missingModelMessage, 'test.js', 2, 42, missingModelError); + (mainWindow.onerror)(settings.missingModelMessage, 'test.js', 2, 42, missingModelError); this.clock.tick(ErrorTelemetry.ERROR_FLUSH_TIMEOUT); assert.strictEqual(errorStub.callCount, 1); @@ -673,7 +674,7 @@ suite('TelemetryService', () => { try { const errorStub = sinon.stub(); - window.onerror = errorStub; + mainWindow.onerror = errorStub; const settings = new ErrorTestingSettings(); const testAppender = new TestTelemetryAppender(); const service = new TestErrorTelemetryService({ appenders: [testAppender] }); @@ -681,7 +682,7 @@ suite('TelemetryService', () => { const noSuchFileError: any = new Error('noSuchFileMessage'); noSuchFileError.stack = settings.stack; - (window.onerror)(settings.noSuchFileMessage, 'test.js', 2, 42, noSuchFileError); + (mainWindow.onerror)(settings.noSuchFileMessage, 'test.js', 2, 42, noSuchFileError); this.clock.tick(ErrorTelemetry.ERROR_FLUSH_TIMEOUT); assert.strictEqual(errorStub.callCount, 1); diff --git a/src/vs/platform/userDataProfile/browser/userDataProfile.ts b/src/vs/platform/userDataProfile/browser/userDataProfile.ts index 044e7ee5888..7af957185d2 100644 --- a/src/vs/platform/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/browser/userDataProfile.ts @@ -67,7 +67,7 @@ export class BrowserUserDataProfilesService extends UserDataProfilesService impl protected override getStoredProfiles(): StoredUserDataProfile[] { try { - const value = window.localStorage.getItem(UserDataProfilesService.PROFILES_KEY); + const value = localStorage.getItem(UserDataProfilesService.PROFILES_KEY); if (value) { return revive(JSON.parse(value)); } @@ -84,19 +84,19 @@ export class BrowserUserDataProfilesService extends UserDataProfilesService impl } protected override saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void { - window.localStorage.setItem(UserDataProfilesService.PROFILES_KEY, JSON.stringify(storedProfiles)); + localStorage.setItem(UserDataProfilesService.PROFILES_KEY, JSON.stringify(storedProfiles)); } protected override getStoredProfileAssociations(): StoredProfileAssociations { const migrateKey = 'profileAssociationsMigration'; try { - const value = window.localStorage.getItem(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY); + const value = localStorage.getItem(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY); if (value) { let associations: StoredProfileAssociations = JSON.parse(value); - if (!window.localStorage.getItem(migrateKey)) { + if (!localStorage.getItem(migrateKey)) { associations = this.migrateStoredProfileAssociations(associations); this.saveStoredProfileAssociations(associations); - window.localStorage.setItem(migrateKey, 'true'); + localStorage.setItem(migrateKey, 'true'); } return associations; } @@ -108,7 +108,7 @@ export class BrowserUserDataProfilesService extends UserDataProfilesService impl } protected override saveStoredProfileAssociations(storedProfileAssociations: StoredProfileAssociations): void { - window.localStorage.setItem(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY, JSON.stringify(storedProfileAssociations)); + localStorage.setItem(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY, JSON.stringify(storedProfileAssociations)); } } diff --git a/src/vs/platform/window/electron-sandbox/window.ts b/src/vs/platform/window/electron-sandbox/window.ts index 692dbb9e44c..55c34942677 100644 --- a/src/vs/platform/window/electron-sandbox/window.ts +++ b/src/vs/platform/window/electron-sandbox/window.ts @@ -5,6 +5,7 @@ import { getZoomLevel, setZoomFactor, setZoomLevel } from 'vs/base/browser/browser'; import { getWindows } from 'vs/base/browser/dom'; +import { mainWindow } from 'vs/base/browser/window'; import { ISandboxGlobals, ipcRenderer, webFrame } from 'vs/base/parts/sandbox/electron-sandbox/globals'; import { zoomLevelToZoomFactor } from 'vs/platform/window/common/window'; @@ -21,7 +22,7 @@ export function applyZoom(zoomLevel: number): void { } function getGlobals(win: Window): ISandboxGlobals | undefined { - if (win === window) { + if (win === mainWindow) { // main window return { ipcRenderer, webFrame }; } else { diff --git a/src/vs/workbench/browser/actions/windowActions.ts b/src/vs/workbench/browser/actions/windowActions.ts index 2466178ff12..14c7b8aa01f 100644 --- a/src/vs/workbench/browser/actions/windowActions.ts +++ b/src/vs/workbench/browser/actions/windowActions.ts @@ -35,6 +35,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { isFolderBackupInfo, isWorkspaceBackupInfo } from 'vs/platform/backup/common/backup'; import { getActiveElement, getActiveWindow } from 'vs/base/browser/dom'; +import { mainWindow } from 'vs/base/browser/window'; export const inRecentFilesPickerContextKey = 'inRecentFilesPicker'; @@ -335,7 +336,7 @@ export class ReloadWindowAction extends Action2 { override async run(accessor: ServicesAccessor): Promise { const hostService = accessor.get(IHostService); - if (getActiveWindow() === window) { + if (getActiveWindow() === mainWindow) { return hostService.reload(); // only supported for main window } } diff --git a/src/vs/workbench/browser/contextkeys.ts b/src/vs/workbench/browser/contextkeys.ts index 190ba3a1d9e..ae859cf8ea4 100644 --- a/src/vs/workbench/browser/contextkeys.ts +++ b/src/vs/workbench/browser/contextkeys.ts @@ -26,6 +26,7 @@ import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAcce import { IProductService } from 'vs/platform/product/common/productService'; import { FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files'; import { getTitleBarStyle } from 'vs/platform/window/common/window'; +import { mainWindow } from 'vs/base/browser/window'; export class WorkbenchContextKeysHandler extends Disposable { private inputFocusedContext: IContextKey; @@ -112,7 +113,7 @@ export class WorkbenchContextKeysHandler extends Disposable { this.updateWorkspaceContextKeys(); // Capabilities - HasWebFileSystemAccess.bindTo(this.contextKeyService).set(WebFileSystemAccess.supported(window)); + HasWebFileSystemAccess.bindTo(this.contextKeyService).set(WebFileSystemAccess.supported(mainWindow)); // Development const isDevelopment = !this.environmentService.isBuilt || this.environmentService.isExtensionDevelopment; @@ -240,7 +241,7 @@ export class WorkbenchContextKeysHandler extends Disposable { this._register(this.editorGroupService.onDidChangeEditorPartOptions(() => this.updateEditorAreaContextKeys())); - this._register(Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposables }) => disposables.add(addDisposableListener(window, EventType.FOCUS_IN, () => this.updateInputContextKeys(window.document), true)), { window, disposables: this._store })); + this._register(Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposables }) => disposables.add(addDisposableListener(window, EventType.FOCUS_IN, () => this.updateInputContextKeys(window.document), true)), { window: mainWindow, disposables: this._store })); this._register(this.contextService.onDidChangeWorkbenchState(() => this.updateWorkbenchStateContextKey())); this._register(this.contextService.onDidChangeWorkspaceFolders(() => { diff --git a/src/vs/workbench/browser/parts/editor/editorPanes.ts b/src/vs/workbench/browser/parts/editor/editorPanes.ts index 571f0224217..7cd98a8ed3f 100644 --- a/src/vs/workbench/browser/parts/editor/editorPanes.ts +++ b/src/vs/workbench/browser/parts/editor/editorPanes.ts @@ -28,6 +28,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { IDialogService, IPromptButton, IPromptCancelButton } from 'vs/platform/dialogs/common/dialogs'; import { IBoundarySashes } from 'vs/base/browser/ui/sash/sash'; import { IHostService } from 'vs/workbench/services/host/browser/host'; +import { mainWindow } from 'vs/base/browser/window'; export interface IOpenEditorResult { @@ -131,7 +132,7 @@ export class EditorPanes extends Disposable { // Assert the `EditorInputCapabilities.AuxWindowUnsupported` condition // TODO@bpasero revisit this once all editors can support aux windows - if (getWindow(this.editorPanesParent) !== window && editor.hasCapability(EditorInputCapabilities.AuxWindowUnsupported)) { + if (getWindow(this.editorPanesParent) !== mainWindow && editor.hasCapability(EditorInputCapabilities.AuxWindowUnsupported)) { return await this.doShowError(createEditorOpenError(localize('editorUnsupportedInAuxWindow', "This type of editor cannot be opened in floating windows yet."), [ toAction({ id: 'workbench.editor.action.closeEditor', label: localize('openFolder', "Close Editor"), run: async () => { diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index d019690429b..330cdc3eec4 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -55,6 +55,7 @@ import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { TabFocus } from 'vs/editor/browser/config/tabFocus'; +import { mainWindow } from 'vs/base/browser/window'; class SideBySideEditorEncodingSupport implements IEncodingSupport { constructor(private primary: IEncodingSupport, private secondary: IEncodingSupport) { } @@ -334,7 +335,6 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { private toRender: StateChange | undefined = undefined; private editorService: IEditorService; - private targetWindow = window; constructor( @IEditorService editorService: IEditorService, @@ -570,7 +570,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { if (toRender) { this.doRenderNow(); } - }, this.targetWindow); + }, mainWindow); } else { this.toRender.combine(changed); } diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 552e59959ab..46c8de7dbd7 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -41,6 +41,7 @@ import { OpenRecentAction } from 'vs/workbench/browser/actions/windowActions'; import { isICommandActionToggleInfo } from 'vs/platform/action/common/action'; import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { defaultMenuStyles } from 'vs/platform/theme/browser/defaultStyles'; +import { mainWindow } from 'vs/base/browser/window'; export type IOpenRecentAction = IAction & { uri: URI; remoteAuthority?: string }; @@ -789,7 +790,7 @@ export class CustomMenubarControl extends MenubarControl { protected override registerListeners(): void { super.registerListeners(); - this._register(addDisposableListener(window, EventType.RESIZE, () => { + this._register(addDisposableListener(mainWindow, EventType.RESIZE, () => { if (this.menubar && !(isIOS && BrowserFeatures.pointerEvents)) { this.menubar.blur(); } diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 2e34ebb58ef..57fd944883f 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -51,6 +51,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ResolvedKeybinding } from 'vs/base/common/keybindings'; import { EditorCommandsContextActionRunner } from 'vs/workbench/browser/parts/editor/editorTabsControl'; import { IEditorCommandsContext, IToolbarActions } from 'vs/workbench/common/editor'; +import { mainWindow } from 'vs/base/browser/window'; export class TitlebarPart extends Part implements ITitleService { @@ -125,7 +126,7 @@ export class TitlebarPart extends Part implements ITitleService { @IKeybindingService private readonly keybindingService: IKeybindingService, ) { super(Parts.TITLEBAR_PART, { hasTitle: false }, themeService, storageService, layoutService); - this.windowTitle = this._register(instantiationService.createInstance(WindowTitle, window, 'main')); + this.windowTitle = this._register(instantiationService.createInstance(WindowTitle, mainWindow, 'main')); this.titleBarStyle = getTitleBarStyle(this.configurationService); diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index c1ec79928ae..10b6141ce9c 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -95,6 +95,7 @@ import { EncryptionService } from 'vs/workbench/services/encryption/browser/encr import { IEncryptionService } from 'vs/platform/encryption/common/encryptionService'; import { ISecretStorageService } from 'vs/platform/secrets/common/secrets'; import { TunnelSource } from 'vs/workbench/services/remote/common/tunnelModel'; +import { mainWindow } from 'vs/base/browser/window'; export class BrowserMain extends Disposable { @@ -467,7 +468,7 @@ export class BrowserMain extends Disposable { fileService.registerProvider(Schemas.vscodeUserData, userDataProvider); // Local file access (if supported by browser) - if (WebFileSystemAccess.supported(window)) { + if (WebFileSystemAccess.supported(mainWindow)) { fileService.registerProvider(Schemas.file, new HTMLFileSystemProvider(indexedDB, handlesStore, logService)); } diff --git a/src/vs/workbench/browser/window.ts b/src/vs/workbench/browser/window.ts index 94b46dd7381..eb0305eb86a 100644 --- a/src/vs/workbench/browser/window.ts +++ b/src/vs/workbench/browser/window.ts @@ -27,6 +27,7 @@ import { BrowserLifecycleService } from 'vs/workbench/services/lifecycle/browser import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { registerWindowDriver } from 'vs/workbench/services/driver/browser/driver'; +import { mainWindow } from 'vs/base/browser/window'; export class BrowserWindow extends Disposable { @@ -53,13 +54,13 @@ export class BrowserWindow extends Disposable { this._register(this.lifecycleService.onWillShutdown(() => this.onWillShutdown())); // Layout - const viewport = isIOS && window.visualViewport ? window.visualViewport /** Visual viewport */ : window /** Layout viewport */; + const viewport = isIOS && mainWindow.visualViewport ? mainWindow.visualViewport /** Visual viewport */ : mainWindow /** Layout viewport */; this._register(addDisposableListener(viewport, EventType.RESIZE, () => { this.layoutService.layout(); // Sometimes the keyboard appearing scrolls the whole workbench out of view, as a workaround scroll back into view #121206 if (isIOS) { - window.scrollTo(0, 0); + mainWindow.scrollTo(0, 0); } })); @@ -108,7 +109,7 @@ export class BrowserWindow extends Disposable { buttons: [ { label: localize({ key: 'reload', comment: ['&& denotes a mnemonic'] }, "&&Reload"), - run: () => window.location.reload() // do not use any services at this point since they are likely not functional at this point + run: () => mainWindow.location.reload() // do not use any services at this point since they are likely not functional at this point } ] }); @@ -191,7 +192,7 @@ export class BrowserWindow extends Disposable { // handling explicitly to prevent the workbench from going down. else { const invokeProtocolHandler = () => { - this.lifecycleService.withExpectedShutdown({ disableShutdownHandling: true }, () => window.location.href = href); + this.lifecycleService.withExpectedShutdown({ disableShutdownHandling: true }, () => mainWindow.location.href = href); }; invokeProtocolHandler(); diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index d1a308a9f49..4a13d94c66a 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -41,6 +41,7 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia import { Layout } from 'vs/workbench/browser/layout'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { mainWindow } from 'vs/base/browser/window'; export interface IWorkbenchOptions { @@ -75,7 +76,7 @@ export class Workbench extends Layout { private registerErrorHandler(logService: ILogService): void { // Listen on unhandled rejection events - this._register(addDisposableListener(window, 'unhandledrejection', event => { + this._register(addDisposableListener(mainWindow, 'unhandledrejection', event => { // See https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent onUnexpectedError(event.reason); @@ -102,8 +103,8 @@ export class Workbench extends Layout { } type AnnotatedError = AnnotatedLoadingError | AnnotatedFactoryError | AnnotatedValidationError; - if (typeof window.require?.config === 'function') { - window.require.config({ + if (typeof mainWindow.require?.config === 'function') { + mainWindow.require.config({ onError: (err: AnnotatedError) => { if (err.phase === 'loading') { onUnexpectedError(new Error(localize('loaderErrorNative', "Failed to load a required file. Please restart the application to try again. Details: {0}", JSON.stringify(err)))); diff --git a/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts b/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts index 2593f25e9ac..6c498870ddd 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts @@ -23,6 +23,7 @@ import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { Event } from 'vs/base/common/event'; import { addDisposableListener, onDidRegisterWindow } from 'vs/base/browser/dom'; +import { mainWindow } from 'vs/base/browser/window'; const transientWordWrapState = 'transientWordWrapState'; const isWordWrapMinifiedKey = 'isWordWrapMinified'; @@ -273,7 +274,7 @@ class EditorWordWrapContextKeyTracker extends Disposable implements IWorkbenchCo this._register(Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposables }) => { disposables.add(addDisposableListener(window, 'focus', () => this._update(), true)); disposables.add(addDisposableListener(window, 'blur', () => this._update(), true)); - }, { window, disposables: this._store })); + }, { window: mainWindow, disposables: this._store })); this._editorService.onDidActiveEditorChange(() => this._update()); this._canToggleWordWrap = CAN_TOGGLE_WORD_WRAP.bindTo(this._contextService); this._editorWordWrap = EDITOR_WORD_WRAP.bindTo(this._contextService); diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index 2c8712b26c4..8e4c0b250d0 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { mainWindow } from 'vs/base/browser/window'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { distinct } from 'vs/base/common/arrays'; import { Queue, RunOnceScheduler } from 'vs/base/common/async'; @@ -1018,7 +1019,7 @@ export class DebugSession implements IDebugSession, IDisposable { } if (this.configurationService.getValue('debug').focusWindowOnBreak && !this.workbenchEnvironmentService.extensionTestsLocationURI) { - await this.hostService.focus(window, { force: true /* Application may not be active */ }); + await this.hostService.focus(mainWindow, { force: true /* Application may not be active */ }); } } } diff --git a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts index 397f5414af1..9d5e50d78e5 100644 --- a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts +++ b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts @@ -38,6 +38,7 @@ import * as icons from 'vs/workbench/contrib/debug/browser/debugIcons'; import { CONTEXT_DEBUG_STATE, CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_FOCUSED_SESSION_IS_NO_DEBUG, CONTEXT_IN_DEBUG_MODE, CONTEXT_MULTI_SESSION_DEBUG, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_SUSPEND_DEBUGGEE_SUPPORTED, CONTEXT_TERMINATE_DEBUGGEE_SUPPORTED, IDebugConfiguration, IDebugService, State, VIEWLET_ID } from 'vs/workbench/contrib/debug/common/debug'; import { EditorTabsMode, IWorkbenchLayoutService, LayoutSettings, Parts } from 'vs/workbench/services/layout/browser/layoutService'; import { Codicon } from 'vs/base/common/codicons'; +import { mainWindow } from 'vs/base/browser/window'; const DEBUG_TOOLBAR_POSITION_KEY = 'debug.actionswidgetposition'; const DEBUG_TOOLBAR_Y_KEY = 'debug.actionswidgety'; @@ -147,14 +148,14 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution { // log in telemetry this.telemetryService.publicLog2('workbenchActionExecuted', { id: e.action.id, from: 'debugActionsWidget' }); })); - this._register(dom.addDisposableListener(window, dom.EventType.RESIZE, () => this.setCoordinates())); + this._register(dom.addDisposableListener(mainWindow, dom.EventType.RESIZE, () => this.setCoordinates())); this._register(dom.addDisposableGenericMouseUpListener(this.dragArea, (event: MouseEvent) => { const mouseClickEvent = new StandardMouseEvent(event); if (mouseClickEvent.detail === 2) { // double click on debug bar centers it again #8250 const widgetWidth = this.$el.clientWidth; - this.setCoordinates(0.5 * window.innerWidth - 0.5 * widgetWidth, 0); + this.setCoordinates(0.5 * mainWindow.innerWidth - 0.5 * widgetWidth, 0); this.storePosition(); } })); @@ -162,7 +163,7 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution { this._register(dom.addDisposableGenericMouseDownListener(this.dragArea, (event: MouseEvent) => { this.dragArea.classList.add('dragged'); - const mouseMoveListener = dom.addDisposableGenericMouseMoveListener(window, (e: MouseEvent) => { + const mouseMoveListener = dom.addDisposableGenericMouseMoveListener(mainWindow, (e: MouseEvent) => { const mouseMoveEvent = new StandardMouseEvent(e); // Prevent default to stop editor selecting text #8524 mouseMoveEvent.preventDefault(); @@ -170,7 +171,7 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution { this.setCoordinates(mouseMoveEvent.posx - 14, mouseMoveEvent.posy - 14); }); - const mouseUpListener = dom.addDisposableGenericMouseUpListener(window, (e: MouseEvent) => { + const mouseUpListener = dom.addDisposableGenericMouseUpListener(mainWindow, (e: MouseEvent) => { this.storePosition(); this.dragArea.classList.remove('dragged'); @@ -186,7 +187,7 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution { private storePosition(): void { const left = dom.getComputedStyle(this.$el).left; if (left) { - const position = parseFloat(left) / window.innerWidth; + const position = parseFloat(left) / mainWindow.innerWidth; this.storageService.store(DEBUG_TOOLBAR_POSITION_KEY, position, StorageScope.PROFILE, StorageTarget.MACHINE); } if (this.yCoordinate) { @@ -224,10 +225,10 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution { const widgetWidth = this.$el.clientWidth; if (x === undefined) { const positionPercentage = this.storageService.get(DEBUG_TOOLBAR_POSITION_KEY, StorageScope.PROFILE); - x = positionPercentage !== undefined ? parseFloat(positionPercentage) * window.innerWidth : (0.5 * window.innerWidth - 0.5 * widgetWidth); + x = positionPercentage !== undefined ? parseFloat(positionPercentage) * mainWindow.innerWidth : (0.5 * mainWindow.innerWidth - 0.5 * widgetWidth); } - x = Math.max(0, Math.min(x, window.innerWidth - widgetWidth)); // do not allow the widget to overflow on the right + x = Math.max(0, Math.min(x, mainWindow.innerWidth - widgetWidth)); // do not allow the widget to overflow on the right this.$el.style.left = `${x}px`; if (y === undefined) { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 55c422a9310..f7fe57a1760 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -51,6 +51,7 @@ import { ILocaleService } from 'vs/workbench/services/localization/common/locale import { TelemetryTrustedValue } from 'vs/platform/telemetry/common/telemetryUtils'; import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { mainWindow } from 'vs/base/browser/window'; interface IExtensionStateProvider { (extension: Extension): T; @@ -1928,7 +1929,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension [extension] = await this.getExtensions([{ id: extensionId }], { source: 'uri' }, CancellationToken.None); } if (extension) { - await this.hostService.focus(window); + await this.hostService.focus(mainWindow); await this.open(extension); } }).then(undefined, error => this.onError(error)); diff --git a/src/vs/workbench/contrib/files/browser/fileImportExport.ts b/src/vs/workbench/contrib/files/browser/fileImportExport.ts index 10a1453fd05..efb8b50534c 100644 --- a/src/vs/workbench/contrib/files/browser/fileImportExport.ts +++ b/src/vs/workbench/contrib/files/browser/fileImportExport.ts @@ -36,6 +36,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAccess'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { $window } from 'vs/base/browser/window'; //#region Browser File Upload (drag and drop, input element) @@ -654,9 +655,9 @@ export class FileDownload { const preferFileSystemAccessWebApis = stat.isDirectory || stat.size > maxBlobDownloadSize; // Folder: use FS APIs to download files and folders if available and preferred - if (preferFileSystemAccessWebApis && WebFileSystemAccess.supported(window)) { + if (preferFileSystemAccessWebApis && WebFileSystemAccess.supported($window)) { try { - const parentFolder: FileSystemDirectoryHandle = await window.showDirectoryPicker(); + const parentFolder: FileSystemDirectoryHandle = await $window.showDirectoryPicker(); const operation: IDownloadOperation = { startTime: Date.now(), progressScheduler: new RunOnceWorker(steps => { progress.report(steps[steps.length - 1]); }, 1000), diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 4ab203190e3..486cf8cbdc2 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -66,6 +66,7 @@ import { IHoverDelegate, IHoverDelegateOptions, IHoverWidget } from 'vs/base/bro import { IHoverService } from 'vs/workbench/services/hover/browser/hover'; import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget'; import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { mainWindow } from 'vs/base/browser/window'; export class ExplorerDelegate implements IListVirtualDelegate { @@ -1262,9 +1263,9 @@ export class FileDragAndDrop implements ITreeDragAndDrop { // External file DND (Import/Upload file) if (data instanceof NativeDragAndDropData) { // Use local file import when supported - if (!isWeb || (isTemporaryWorkspace(this.contextService.getWorkspace()) && WebFileSystemAccess.supported(window))) { + if (!isWeb || (isTemporaryWorkspace(this.contextService.getWorkspace()) && WebFileSystemAccess.supported(mainWindow))) { const fileImport = this.instantiationService.createInstance(ExternalFileImport); - await fileImport.import(resolvedTarget, originalEvent, window); + await fileImport.import(resolvedTarget, originalEvent, mainWindow); } // Otherwise fallback to browser based file upload else { diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index d08e8d92b43..0494ecabb75 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -52,6 +52,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands'; import { Schemas } from 'vs/base/common/network'; import { extUriIgnorePathCase } from 'vs/base/common/resources'; import { ILocalizedString } from 'vs/platform/action/common/action'; +import { mainWindow } from 'vs/base/browser/window'; const $ = dom.$; @@ -733,7 +734,7 @@ class OpenEditorsDragAndDrop implements IListDragAndDrop group, () => group.focus(), { index }); + this.dropHandler.handleDrop(originalEvent, mainWindow, () => group, () => group.focus(), { index }); } } diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts b/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts index e0c09afffbc..ea51ae067ca 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts @@ -262,13 +262,13 @@ class NotebookFindWidget extends SimpleFindReplaceWidget implements INotebookEdi if (this._showTimeout === null) { if (this._hideTimeout !== null) { - window.clearTimeout(this._hideTimeout); + DOM.getWindow(this.getDomNode()).clearTimeout(this._hideTimeout); this._hideTimeout = null; this._notebookEditor.removeClassName(FIND_HIDE_TRANSITION); } this._notebookEditor.addClassName(FIND_SHOW_TRANSITION); - this._showTimeout = window.setTimeout(() => { + this._showTimeout = DOM.getWindow(this.getDomNode()).setTimeout(() => { this._notebookEditor.removeClassName(FIND_SHOW_TRANSITION); this._showTimeout = null; }, 200); @@ -284,13 +284,13 @@ class NotebookFindWidget extends SimpleFindReplaceWidget implements INotebookEdi if (this._showTimeout === null) { if (this._hideTimeout !== null) { - window.clearTimeout(this._hideTimeout); + DOM.getWindow(this.getDomNode()).clearTimeout(this._hideTimeout); this._hideTimeout = null; this._notebookEditor.removeClassName(FIND_HIDE_TRANSITION); } this._notebookEditor.addClassName(FIND_SHOW_TRANSITION); - this._showTimeout = window.setTimeout(() => { + this._showTimeout = DOM.getWindow(this.getDomNode()).setTimeout(() => { this._notebookEditor.removeClassName(FIND_SHOW_TRANSITION); this._showTimeout = null; }, 200); @@ -308,12 +308,12 @@ class NotebookFindWidget extends SimpleFindReplaceWidget implements INotebookEdi if (this._hideTimeout === null) { if (this._showTimeout !== null) { - window.clearTimeout(this._showTimeout); + DOM.getWindow(this.getDomNode()).clearTimeout(this._showTimeout); this._showTimeout = null; this._notebookEditor.removeClassName(FIND_SHOW_TRANSITION); } this._notebookEditor.addClassName(FIND_HIDE_TRANSITION); - this._hideTimeout = window.setTimeout(() => { + this._hideTimeout = DOM.getWindow(this.getDomNode()).setTimeout(() => { this._notebookEditor.removeClassName(FIND_HIDE_TRANSITION); }, 200); } else { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 2ca6b9cda0f..acdf0c25e45 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import type * as DOM from 'vs/base/browser/window'; import type { Event } from 'vs/base/common/event'; import type { IDisposable } from 'vs/base/common/lifecycle'; import type * as webviewMessages from 'vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages'; @@ -87,6 +88,8 @@ declare function cancelIdleCallback(handle: number): void; declare function __import(path: string): Promise; async function webviewPreloads(ctx: PreloadContext) { + // eslint-disable-next-line no-restricted-globals + const $window = window as typeof DOM.$window; const textEncoder = new TextEncoder(); const textDecoder = new TextDecoder(); @@ -389,7 +392,7 @@ async function webviewPreloads(ctx: PreloadContext) { if (shouldUpdatePadding) { // Do not update dimension in resize observer - window.requestAnimationFrame(() => { + $window.requestAnimationFrame(() => { if (newHeight !== 0) { entry.target.style.padding = `${ctx.style.outputNodePadding}px ${ctx.style.outputNodePadding}px ${ctx.style.outputNodePadding}px ${ctx.style.outputNodeLeftPadding}px`; } else { @@ -457,7 +460,7 @@ async function webviewPreloads(ctx: PreloadContext) { } // if the node is not scrollable, we can continue. We don't check the computed style always as it's expensive - if (window.getComputedStyle(node).overflowY === 'hidden' || window.getComputedStyle(node).overflowY === 'visible') { + if ($window.getComputedStyle(node).overflowY === 'hidden' || $window.getComputedStyle(node).overflowY === 'visible') { continue; } @@ -671,7 +674,7 @@ async function webviewPreloads(ctx: PreloadContext) { } function selectRange(_range: ICommonRange) { - const sel = window.getSelection(); + const sel = $window.getSelection(); if (sel) { try { sel.removeAllRanges(); @@ -704,8 +707,8 @@ async function webviewPreloads(ctx: PreloadContext) { } }; } else { - window.document.execCommand('hiliteColor', false, matchColor); - const cloneRange = window.getSelection()!.getRangeAt(0).cloneRange(); + $window.document.execCommand('hiliteColor', false, matchColor); + const cloneRange = $window.getSelection()!.getRangeAt(0).cloneRange(); const _range = { collapsed: cloneRange.collapsed, commonAncestorContainer: cloneRange.commonAncestorContainer, @@ -722,7 +725,7 @@ async function webviewPreloads(ctx: PreloadContext) { document.designMode = 'On'; document.execCommand('removeFormat', false, undefined); document.designMode = 'Off'; - window.getSelection()?.removeAllRanges(); + $window.getSelection()?.removeAllRanges(); } catch (e) { console.log(e); } @@ -732,9 +735,9 @@ async function webviewPreloads(ctx: PreloadContext) { try { document.designMode = 'On'; document.execCommand('removeFormat', false, undefined); - window.document.execCommand('hiliteColor', false, color); + $window.document.execCommand('hiliteColor', false, color); document.designMode = 'Off'; - window.getSelection()?.removeAllRanges(); + $window.getSelection()?.removeAllRanges(); } catch (e) { console.log(e); } @@ -906,12 +909,12 @@ async function webviewPreloads(ctx: PreloadContext) { const onDidReceiveKernelMessage = createEmitter(); - const ttPolicy = window.trustedTypes?.createPolicy('notebookRenderer', { + const ttPolicy = $window.trustedTypes?.createPolicy('notebookRenderer', { createHTML: value => value, // CodeQL [SM03712] The rendered content is provided by renderer extensions, which are responsible for sanitizing their content themselves. The notebook webview is also sandboxed. createScript: value => value, // CodeQL [SM03712] The rendered content is provided by renderer extensions, which are responsible for sanitizing their content themselves. The notebook webview is also sandboxed. }); - window.addEventListener('wheel', handleWheel); + $window.addEventListener('wheel', handleWheel); interface IFindMatch { type: 'preview' | 'output'; @@ -945,8 +948,8 @@ async function webviewPreloads(ctx: PreloadContext) { currentMatchIndex: number; } - const matchColor = window.getComputedStyle(document.getElementById('_defaultColorPalatte')!).color; - const currentMatchColor = window.getComputedStyle(document.getElementById('_defaultColorPalatte')!).backgroundColor; + const matchColor = $window.getComputedStyle(document.getElementById('_defaultColorPalatte')!).color; + const currentMatchColor = $window.getComputedStyle(document.getElementById('_defaultColorPalatte')!).backgroundColor; class JSHighlighter implements IHighlighter { private _activeHighlightInfo: Map; @@ -992,7 +995,7 @@ async function webviewPreloads(ctx: PreloadContext) { const match = highlightInfo.matches[index]; highlightInfo.currentMatchIndex = index; - const sel = window.getSelection(); + const sel = $window.getSelection(); if (!!match && !!sel && match.highlightResult) { let offset = 0; try { @@ -1237,7 +1240,7 @@ async function webviewPreloads(ctx: PreloadContext) { const range = document.createRange(); range.selectNodeContents(document.getElementById('findStart')!); - const sel = window.getSelection(); + const sel = $window.getSelection(); sel?.removeAllRanges(); sel?.addRange(range); @@ -1247,7 +1250,7 @@ async function webviewPreloads(ctx: PreloadContext) { document.designMode = 'On'; while (find && matches.length < 500) { - find = (window as any).find(query, /* caseSensitive*/ !!options.caseSensitive, + find = ($window as any).find(query, /* caseSensitive*/ !!options.caseSensitive, /* backwards*/ false, /* wrapAround*/ false, /* wholeWord */ !!options.wholeWord, @@ -1255,7 +1258,7 @@ async function webviewPreloads(ctx: PreloadContext) { false); if (find) { - const selection = window.getSelection(); + const selection = $window.getSelection(); if (!selection) { console.log('no selection'); break; @@ -1415,7 +1418,7 @@ async function webviewPreloads(ctx: PreloadContext) { } }; - window.addEventListener('message', async rawEvent => { + $window.addEventListener('message', async rawEvent => { const event = rawEvent as ({ data: webviewMessages.ToWebviewMessage }); switch (event.data.type) { @@ -2816,9 +2819,9 @@ async function webviewPreloads(ctx: PreloadContext) { cellId: cellId, dragOffsetY: this.currentDrag.clientY, }); - requestAnimationFrame(trySendDragUpdate); + $window.requestAnimationFrame(trySendDragUpdate); }; - requestAnimationFrame(trySendDragUpdate); + $window.requestAnimationFrame(trySendDragUpdate); } updateDrag(e: DragEvent, cellId: string) { diff --git a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts index 83e168989e4..582978e9052 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts @@ -48,6 +48,7 @@ import { ThemeIcon } from 'vs/base/common/themables'; import { infoIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { URI } from 'vs/base/common/uri'; +import { mainWindow } from 'vs/base/browser/window'; type ActionGroup = [string, Array]; @@ -274,8 +275,8 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr // Online / Offline changes (web only) if (isWeb) { this._register(Event.any( - this._register(new DomEmitter(window, 'online')).event, - this._register(new DomEmitter(window, 'offline')).event + this._register(new DomEmitter(mainWindow, 'online')).event, + this._register(new DomEmitter(mainWindow, 'offline')).event )(() => this.setNetworkState(navigator.onLine ? 'online' : 'offline'))); } diff --git a/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts b/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts index 1b4ad1bc098..91a902f4b20 100644 --- a/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts +++ b/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts @@ -26,6 +26,7 @@ import { hash } from 'vs/base/common/hash'; import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite'; import { ViewContainerLocation } from 'vs/workbench/common/views'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { mainWindow } from 'vs/base/browser/window'; type TelemetryData = { mimeType: TelemetryTrustedValue; @@ -108,7 +109,7 @@ export class TelemetryContribution extends Disposable implements IWorkbenchContr }; telemetryService.publicLog2('workspaceLoad', { - windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth }, + windowSize: { innerHeight: mainWindow.innerHeight, innerWidth: mainWindow.innerWidth, outerHeight: mainWindow.outerHeight, outerWidth: mainWindow.outerWidth }, emptyWorkbench: contextService.getWorkbenchState() === WorkbenchState.EMPTY, 'workbench.filesToOpenOrCreate': filesToOpenOrCreate && filesToOpenOrCreate.length || 0, 'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0, diff --git a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts index 552d69c615e..44271b827be 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts @@ -20,6 +20,7 @@ import { IXtermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private' import { IShellLaunchConfig } from 'vs/platform/terminal/common/terminal'; import { isLinux, isWindows } from 'vs/base/common/platform'; import { Disposable } from 'vs/base/common/lifecycle'; +import { $window } from 'vs/base/browser/window'; const enum FontConstants { MinimumFontSize = 6, @@ -142,10 +143,10 @@ export class TerminalConfigHelper extends Disposable implements IBrowserTerminal if (this.config.gpuAcceleration === 'off') { this._lastFontMeasurement.charWidth = rect.width; } else { - const deviceCharWidth = Math.floor(rect.width * window.devicePixelRatio); + const deviceCharWidth = Math.floor(rect.width * $window.devicePixelRatio); const deviceCellWidth = deviceCharWidth + Math.round(letterSpacing); - const cssCellWidth = deviceCellWidth / window.devicePixelRatio; - this._lastFontMeasurement.charWidth = cssCellWidth - Math.round(letterSpacing) / window.devicePixelRatio; + const cssCellWidth = deviceCellWidth / $window.devicePixelRatio; + this._lastFontMeasurement.charWidth = cssCellWidth - Math.round(letterSpacing) / $window.devicePixelRatio; } } @@ -200,7 +201,7 @@ export class TerminalConfigHelper extends Disposable implements IBrowserTerminal letterSpacing, lineHeight, charHeight: cellDims.height / lineHeight, - charWidth: cellDims.width - Math.round(letterSpacing) / window.devicePixelRatio + charWidth: cellDims.width - Math.round(letterSpacing) / $window.devicePixelRatio }; } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 4345fac23a4..e7af9dfee16 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -88,6 +88,7 @@ import { ISimpleSelectedSuggestion } from 'vs/workbench/services/suggest/browser import type { IMarker, Terminal as XTermTerminal } from '@xterm/xterm'; import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands'; import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; +import { $window } from 'vs/base/browser/window'; const enum Constants { /** @@ -535,13 +536,13 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // Clear out initial data events after 10 seconds, hopefully extension hosts are up and // running at that point. - let initialDataEventsTimeout: number | undefined = window.setTimeout(() => { + let initialDataEventsTimeout: number | undefined = dom.getWindow(this._container).setTimeout(() => { initialDataEventsTimeout = undefined; this._initialDataEvents = undefined; }, 10000); this._register(toDisposable(() => { if (initialDataEventsTimeout) { - window.clearTimeout(initialDataEventsTimeout); + dom.getWindow(this._container).clearTimeout(initialDataEventsTimeout); } })); @@ -611,7 +612,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { return; } - const computedStyle = window.getComputedStyle(this._container); + const computedStyle = dom.getWindow(this._container).getComputedStyle(this._container); const width = parseInt(computedStyle.width); const height = parseInt(computedStyle.height); @@ -675,7 +676,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { if (!this.xterm?.raw.element) { return undefined; } - const computedStyle = window.getComputedStyle(this.xterm.raw.element); + const computedStyle = dom.getWindow(this.xterm.raw.element).getComputedStyle(this.xterm.raw.element); const horizontalPadding = parseInt(computedStyle.paddingLeft) + parseInt(computedStyle.paddingRight); const verticalPadding = parseInt(computedStyle.paddingTop) + parseInt(computedStyle.paddingBottom); TerminalInstance._lastKnownCanvasDimensions = new dom.Dimension( @@ -1210,7 +1211,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { if (!this.xterm) { return; } - if (force || !window.getSelection()?.toString()) { + if (force || !$window.getSelection()?.toString()) { this.xterm.raw.focus(); this._onDidRequestFocus.fire(); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index b1add9a6c84..c39f5ef43b9 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -39,6 +39,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IEnvironmentVariableCollection, IMergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; import { generateUuid } from 'vs/base/common/uuid'; import { runWhenIdle } from 'vs/base/common/async'; +import { $window } from 'vs/base/browser/window'; const enum ProcessConstants { /** @@ -748,7 +749,7 @@ class SeamlessRelaunchDataFilter extends Disposable { this.triggerSwap(); } - this._swapTimeout = window.setTimeout(() => this.triggerSwap(), SeamlessRelaunchConstants.SwapWaitMaximumDuration); + this._swapTimeout = $window.setTimeout(() => this.triggerSwap(), SeamlessRelaunchConstants.SwapWaitMaximumDuration); // Pause all outgoing data events this._dataListener?.dispose(); @@ -773,7 +774,7 @@ class SeamlessRelaunchDataFilter extends Disposable { triggerSwap() { // Clear the swap timeout if it exists if (this._swapTimeout) { - window.clearTimeout(this._swapTimeout); + $window.clearTimeout(this._swapTimeout); this._swapTimeout = undefined; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalStatusList.ts b/src/vs/workbench/contrib/terminal/browser/terminalStatusList.ts index 897d9184586..246ad9ec2f2 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalStatusList.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalStatusList.ts @@ -13,6 +13,7 @@ import { listErrorForeground, listWarningForeground } from 'vs/platform/theme/co import { spinningLoading } from 'vs/platform/theme/common/iconRegistry'; import { ThemeIcon } from 'vs/base/common/themables'; import { ITerminalStatus } from 'vs/workbench/contrib/terminal/common/terminal'; +import { $window } from 'vs/base/browser/window'; /** * The set of _internal_ terminal statuses, other components building on the terminal should put @@ -84,11 +85,11 @@ export class TerminalStatusList extends Disposable implements ITerminalStatusLis status = this._applyAnimationSetting(status); const outTimeout = this._statusTimeouts.get(status.id); if (outTimeout) { - window.clearTimeout(outTimeout); + $window.clearTimeout(outTimeout); this._statusTimeouts.delete(status.id); } if (duration && duration > 0) { - const timeout = window.setTimeout(() => this.remove(status), duration); + const timeout = $window.setTimeout(() => this.remove(status), duration); this._statusTimeouts.set(status.id, timeout); } const existingStatus = this._statuses.get(status.id); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalTabbedView.ts b/src/vs/workbench/contrib/terminal/browser/terminalTabbedView.ts index 4ce64354ac6..72d43e61419 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalTabbedView.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalTabbedView.ts @@ -201,7 +201,7 @@ export class TerminalTabbedView extends Disposable { offscreenCanvas.height = 1; const ctx = offscreenCanvas.getContext('2d'); if (ctx) { - const style = window.getComputedStyle(this._tabListElement); + const style = dom.getWindow(this._tabListElement).getComputedStyle(this._tabListElement); ctx.font = `${style.fontStyle} ${style.fontSize} ${style.fontFamily}`; const maxInstanceWidth = this._terminalGroupService.instances.reduce((p, c) => { return Math.max(p, ctx.measureText(c.title + (c.description || '')).width + this._getAdditionalWidth(c)); @@ -288,12 +288,12 @@ export class TerminalTabbedView extends Disposable { let interval: number; this._sashDisposables = [ this._splitView.sashes[0].onDidStart(e => { - interval = window.setInterval(() => { + interval = dom.getWindow(this._splitView.el).setInterval(() => { this.rerenderTabs(); }, 100); }), this._splitView.sashes[0].onDidEnd(e => { - window.clearInterval(interval); + dom.getWindow(this._splitView.el).clearInterval(interval); interval = 0; }) ]; diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index 4963c4f95b6..fb7572a512a 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -45,6 +45,7 @@ import { MouseWheelClassifier } from 'vs/base/browser/ui/scrollbar/scrollableEle import { IMouseWheelEvent, StandardWheelEvent } from 'vs/base/browser/mouseEvent'; import { AccessibleNotificationEvent, IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; +import { $window } from 'vs/base/browser/window'; const enum RenderConstants { /** @@ -979,13 +980,13 @@ export function getXtermScaledDimensions(font: ITerminalFont, width: number, hei // the use of canvas, window.devicePixelRatio needs to be used here in // order to be precise. font.charWidth/charHeight alone as insufficient // when window.devicePixelRatio changes. - const scaledWidthAvailable = width * window.devicePixelRatio; + const scaledWidthAvailable = width * $window.devicePixelRatio; - const scaledCharWidth = font.charWidth * window.devicePixelRatio + font.letterSpacing; + const scaledCharWidth = font.charWidth * $window.devicePixelRatio + font.letterSpacing; const cols = Math.max(Math.floor(scaledWidthAvailable / scaledCharWidth), 1); - const scaledHeightAvailable = height * window.devicePixelRatio; - const scaledCharHeight = Math.ceil(font.charHeight * window.devicePixelRatio); + const scaledHeightAvailable = height * $window.devicePixelRatio; + const scaledCharHeight = Math.ceil(font.charHeight * $window.devicePixelRatio); const scaledLineHeight = Math.floor(scaledCharHeight * font.lineHeight); const rows = Math.max(Math.floor(scaledHeightAvailable / scaledLineHeight), 1); diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLink.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLink.ts index e221a2e999a..3ed2f05ef08 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLink.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLink.ts @@ -13,6 +13,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TerminalLinkType } from 'vs/workbench/contrib/terminalContrib/links/browser/links'; import { IHoverAction } from 'vs/workbench/services/hover/browser/hover'; +import { $window } from 'vs/base/browser/window'; export class TerminalLink extends DisposableStore implements ILink { decorations: ILinkDecorations; @@ -110,7 +111,7 @@ export class TerminalLink extends DisposableStore implements ILink { } // Reset the scheduler if the mouse moves too much - if (Math.abs(e.pageX - origin.x) > window.devicePixelRatio * 2 || Math.abs(e.pageY - origin.y) > window.devicePixelRatio * 2) { + if (Math.abs(e.pageX - origin.x) > $window.devicePixelRatio * 2 || Math.abs(e.pageY - origin.y) > $window.devicePixelRatio * 2) { origin.x = e.pageX; origin.y = e.pageY; this._tooltipScheduler?.schedule(); diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkResolver.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkResolver.ts index 75bf93bf994..4d217fde4af 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkResolver.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkResolver.ts @@ -12,6 +12,7 @@ import { isWindows, OperatingSystem, OS } from 'vs/base/common/platform'; import { IFileService } from 'vs/platform/files/common/files'; import { IPath, posix, win32 } from 'vs/base/common/path'; import { ITerminalBackend } from 'vs/platform/terminal/common/terminal'; +import { $window } from 'vs/base/browser/window'; export class TerminalLinkResolver implements ITerminalLinkResolver { declare _serviceBrand: undefined; @@ -169,9 +170,9 @@ class LinkCache { set(link: string | URI, value: ResolvedLink) { // Reset cached link TTL on any set if (this._cacheTilTimeout) { - window.clearTimeout(this._cacheTilTimeout); + $window.clearTimeout(this._cacheTilTimeout); } - this._cacheTilTimeout = window.setTimeout(() => this._cache.clear(), LinkCacheConstants.TTL); + this._cacheTilTimeout = $window.setTimeout(() => this._cache.clear(), LinkCacheConstants.TTL); this._cache.set(this._getKey(link), value); } diff --git a/src/vs/workbench/contrib/themes/browser/themes.contribution.ts b/src/vs/workbench/contrib/themes/browser/themes.contribution.ts index 090221014d8..aef2eca7dc7 100644 --- a/src/vs/workbench/contrib/themes/browser/themes.contribution.ts +++ b/src/vs/workbench/contrib/themes/browser/themes.contribution.ts @@ -44,6 +44,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag import { isWeb } from 'vs/base/common/platform'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IHostService } from 'vs/workbench/services/host/browser/host'; +import { $window } from 'vs/base/browser/window'; export const manageExtensionIcon = registerIcon('theme-selection-manage-extension', Codicon.gear, localize('manageExtensionIcon', 'Icon for the \'Manage\' action in the theme selection quick pick.')); @@ -306,7 +307,7 @@ class InstalledThemesPicker { if (selectThemeTimeout) { clearTimeout(selectThemeTimeout); } - selectThemeTimeout = window.setTimeout(() => { + selectThemeTimeout = $window.setTimeout(() => { selectThemeTimeout = undefined; const newTheme = (theme ?? currentTheme) as IWorkbenchTheme; this.setTheme(newTheme, applyTheme ? 'auto' : 'preview').then(undefined, @@ -701,7 +702,7 @@ registerAction2(class extends Action2 { if (selectThemeTimeout) { clearTimeout(selectThemeTimeout); } - selectThemeTimeout = window.setTimeout(() => { + selectThemeTimeout = $window.setTimeout(() => { selectThemeTimeout = undefined; const newTheme = (theme ?? currentTheme) as IWorkbenchTheme; themeService.setColorTheme(newTheme as IWorkbenchColorTheme, applyTheme ? 'auto' : 'preview').then(undefined, diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index a860270eca9..bd319b67288 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -37,6 +37,7 @@ import { WebviewFindDelegate, WebviewFindWidget } from 'vs/workbench/contrib/web import { FromWebviewMessage, KeyEvent, ToWebviewMessage } from 'vs/workbench/contrib/webview/browser/webviewMessages'; import { decodeAuthority, webviewGenericCspSource, webviewRootResourceAuthority } from 'vs/workbench/contrib/webview/common/webview'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { $window } from 'vs/base/browser/window'; interface WebviewContent { readonly html: string; @@ -159,7 +160,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD this.providedViewType = initInfo.providedViewType; this.origin = initInfo.origin ?? this.id; - this._encodedWebviewOriginPromise = parentOriginHash(window.origin, this.origin).then(id => this._encodedWebviewOrigin = id); + this._encodedWebviewOriginPromise = parentOriginHash($window.origin, this.origin).then(id => this._encodedWebviewOrigin = id); this._options = initInfo.options; this.extension = initInfo.extension; @@ -180,7 +181,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD this._element = this._createElement(initInfo.options, initInfo.contentOptions); - const subscription = this._register(addDisposableListener(window, 'message', (e: MessageEvent) => { + const subscription = this._register(addDisposableListener($window, 'message', (e: MessageEvent) => { if (!this._encodedWebviewOrigin || e?.data?.target !== this.id) { return; } @@ -461,7 +462,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD extensionId: extension?.id.value ?? '', platform: this.platform, 'vscode-resource-base-authority': webviewRootResourceAuthority, - parentOrigin: window.origin, + parentOrigin: $window.origin, }; if (this._options.disableServiceWorker) { @@ -501,7 +502,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD })); } - for (const node of [element, window]) { + for (const node of [element, $window]) { this._register(addDisposableListener(node, EventType.DRAG_END, () => { this._stopBlockingIframeDragEvents(); })); @@ -684,7 +685,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD get: () => this.element, }); // And re-dispatch - window.dispatchEvent(emulatedKeyboardEvent); + $window.dispatchEvent(emulatedKeyboardEvent); } windowDidDragStart(): void { diff --git a/src/vs/workbench/contrib/webview/browser/webviewWindowDragMonitor.ts b/src/vs/workbench/contrib/webview/browser/webviewWindowDragMonitor.ts index e7afcb8cd5c..f71664e2288 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewWindowDragMonitor.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewWindowDragMonitor.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as DOM from 'vs/base/browser/dom'; +import { $window } from 'vs/base/browser/window'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWebview } from 'vs/workbench/contrib/webview/browser/webview'; @@ -17,7 +18,7 @@ export class WebviewWindowDragMonitor extends Disposable { constructor(getWebview: () => IWebview | undefined) { super(); - this._register(DOM.addDisposableListener(window, DOM.EventType.DRAG_START, () => { + this._register(DOM.addDisposableListener($window, DOM.EventType.DRAG_START, () => { getWebview()?.windowDidDragStart(); })); @@ -25,8 +26,8 @@ export class WebviewWindowDragMonitor extends Disposable { getWebview()?.windowDidDragEnd(); }; - this._register(DOM.addDisposableListener(window, DOM.EventType.DRAG_END, onDragEnd)); - this._register(DOM.addDisposableListener(window, DOM.EventType.MOUSE_MOVE, currentEvent => { + this._register(DOM.addDisposableListener($window, DOM.EventType.DRAG_END, onDragEnd)); + this._register(DOM.addDisposableListener($window, DOM.EventType.MOUSE_MOVE, currentEvent => { if (currentEvent.buttons === 0) { onDragEnd(); } diff --git a/src/vs/workbench/electron-sandbox/desktop.main.ts b/src/vs/workbench/electron-sandbox/desktop.main.ts index 58292e4fd43..941ba9f85e2 100644 --- a/src/vs/workbench/electron-sandbox/desktop.main.ts +++ b/src/vs/workbench/electron-sandbox/desktop.main.ts @@ -60,6 +60,7 @@ import { RemoteSocketFactoryService, IRemoteSocketFactoryService } from 'vs/plat import { ElectronRemoteResourceLoader } from 'vs/platform/remote/electron-sandbox/electronRemoteResourceLoader'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { applyZoom } from 'vs/platform/window/electron-sandbox/window'; +import { mainWindow } from 'vs/base/browser/window'; export class DesktopMain extends Disposable { @@ -109,7 +110,7 @@ export class DesktopMain extends Disposable { async open(): Promise { // Init services and wait for DOM to be ready in parallel - const [services] = await Promise.all([this.initServices(), domContentLoaded(window)]); + const [services] = await Promise.all([this.initServices(), domContentLoaded(mainWindow)]); // Apply zoom level early once we have a configuration service // and before the workbench is created to prevent flickering. diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts index db5f3d06305..5623d25571b 100644 --- a/src/vs/workbench/electron-sandbox/window.ts +++ b/src/vs/workbench/electron-sandbox/window.ts @@ -71,6 +71,7 @@ import { IPreferencesService } from 'vs/workbench/services/preferences/common/pr import { IUtilityProcessWorkerWorkbenchService } from 'vs/workbench/services/utilityProcess/electron-sandbox/utilityProcessWorkerWorkbenchService'; import { registerWindowDriver } from 'vs/workbench/services/driver/electron-sandbox/driver'; import { IAuxiliaryWindowService } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService'; +import { mainWindow } from 'vs/base/browser/window'; export class NativeWindow extends Disposable { @@ -139,14 +140,14 @@ export class NativeWindow extends Disposable { private registerListeners(): void { // Layout - this._register(addDisposableListener(window, EventType.RESIZE, () => this.layoutService.layout())); + this._register(addDisposableListener(mainWindow, EventType.RESIZE, () => this.layoutService.layout())); // React to editor input changes this._register(this.editorService.onDidActiveEditorChange(() => this.updateTouchbarMenu())); // Prevent opening a real URL inside the window for (const event of [EventType.DRAG_OVER, EventType.DROP]) { - this._register(addDisposableListener(window.document.body, event, (e: DragEvent) => { + this._register(addDisposableListener(mainWindow.document.body, event, (e: DragEvent) => { EventHelper.stop(e); })); } @@ -696,11 +697,11 @@ export class NativeWindow extends Disposable { // asking the main process to focus the window. // https://github.com/electron/electron/issues/25578 const that = this; - const originalWindowFocus = window.focus.bind(window); - window.focus = function () { + const originalWindowFocus = mainWindow.focus.bind(mainWindow); + mainWindow.focus = function () { originalWindowFocus(); - if (getActiveWindow() !== window) { + if (getActiveWindow() !== mainWindow) { that.nativeHostService.focusWindow({ targetWindowId: that.nativeHostService.windowId }); } }; diff --git a/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts b/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts index ecf390dda1b..0b8fa575a16 100644 --- a/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts +++ b/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts @@ -6,7 +6,8 @@ import { localize } from 'vs/nls'; import { mark } from 'vs/base/common/performance'; import { Emitter, Event } from 'vs/base/common/event'; -import { CodeWindow, Dimension, EventHelper, EventType, addDisposableListener, cloneGlobalStylesheets, copyAttributes, createMetaElement, getActiveWindow, getClientArea, getWindowId, isGlobalStylesheet, position, registerWindow, sharedMutationObserver, size, trackAttributes } from 'vs/base/browser/dom'; +import { Dimension, EventHelper, EventType, addDisposableListener, cloneGlobalStylesheets, copyAttributes, createMetaElement, getActiveWindow, getClientArea, getWindowId, isGlobalStylesheet, position, registerWindow, sharedMutationObserver, size, trackAttributes } from 'vs/base/browser/dom'; +import { CodeWindow, mainWindow } from 'vs/base/browser/window'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; @@ -47,7 +48,7 @@ export interface IAuxiliaryWindow extends IDisposable { } export function isAuxiliaryWindow(obj: Window): obj is CodeWindow { - if (obj === window) { + if (obj === mainWindow) { return false; } @@ -62,7 +63,7 @@ export class BrowserAuxiliaryWindowService extends Disposable implements IAuxili private static readonly DEFAULT_SIZE = { width: 800, height: 600 }; - private static WINDOW_IDS = getWindowId(window) + 1; // start from the main window ID + 1 + private static WINDOW_IDS = getWindowId(mainWindow) + 1; // start from the main window ID + 1 private readonly _onDidOpenAuxiliaryWindow = this._register(new Emitter()); readonly onDidOpenAuxiliaryWindow = this._onDidOpenAuxiliaryWindow.event; @@ -125,7 +126,7 @@ export class BrowserAuxiliaryWindowService extends Disposable implements IAuxili }; } - const auxiliaryWindow = window.open('about:blank', undefined, `popup=yes,left=${position.x},top=${position.y},width=${position.width},height=${position.height}`); + const auxiliaryWindow = mainWindow.open('about:blank', undefined, `popup=yes,left=${position.x},top=${position.y},width=${position.width},height=${position.height}`); if (!auxiliaryWindow && isWeb) { return (await this.dialogService.prompt({ type: Severity.Warning, diff --git a/src/vs/workbench/services/auxiliaryWindow/electron-sandbox/auxiliaryWindowService.ts b/src/vs/workbench/services/auxiliaryWindow/electron-sandbox/auxiliaryWindowService.ts index 6934b10aa85..537a16ce61a 100644 --- a/src/vs/workbench/services/auxiliaryWindow/electron-sandbox/auxiliaryWindowService.ts +++ b/src/vs/workbench/services/auxiliaryWindow/electron-sandbox/auxiliaryWindowService.ts @@ -12,7 +12,8 @@ import { IWindowsConfiguration } from 'vs/platform/window/common/window'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { INativeHostService } from 'vs/platform/native/common/native'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { CodeWindow, getActiveWindow } from 'vs/base/browser/dom'; +import { getActiveWindow } from 'vs/base/browser/dom'; +import { CodeWindow } from 'vs/base/browser/window'; type NativeAuxiliaryWindow = CodeWindow & { readonly vscode: ISandboxGlobals; diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 4630065bccf..981df901c9a 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -75,7 +75,7 @@ export class DefaultConfiguration extends BaseDefaultConfiguration { this.initiaizeCachedConfigurationDefaultsOverridesPromise = (async () => { try { // Read only when the cache exists - if (window.localStorage.getItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY)) { + if (localStorage.getItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY)) { const content = await this.configurationCache.read(this.cacheKey); if (content) { this.cachedConfigurationDefaultsOverrides = JSON.parse(content); @@ -108,10 +108,10 @@ export class DefaultConfiguration extends BaseDefaultConfiguration { } try { if (Object.keys(cachedConfigurationDefaultsOverrides).length) { - window.localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); + localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); await this.configurationCache.write(this.cacheKey, JSON.stringify(cachedConfigurationDefaultsOverrides)); } else { - window.localStorage.removeItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY); + localStorage.removeItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY); await this.configurationCache.remove(this.cacheKey); } } catch (error) {/* Ignore error */ } diff --git a/src/vs/workbench/services/configuration/test/browser/configuration.test.ts b/src/vs/workbench/services/configuration/test/browser/configuration.test.ts index 1b9393eb4c8..58736785a95 100644 --- a/src/vs/workbench/services/configuration/test/browser/configuration.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configuration.test.ts @@ -59,7 +59,7 @@ suite('DefaultConfiguration', () => { }); test('configuration default overrides are read from cache', async () => { - window.localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); + localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); await configurationCache.write(cacheKey, JSON.stringify({ 'test.configurationDefaultsOverride': 'overrideValue' })); const testObject = disposables.add(new DefaultConfiguration(configurationCache, TestEnvironmentService)); @@ -70,7 +70,7 @@ suite('DefaultConfiguration', () => { }); test('configuration default overrides are not read from cache when model is read before initialize', async () => { - window.localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); + localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); await configurationCache.write(cacheKey, JSON.stringify({ 'test.configurationDefaultsOverride': 'overrideValue' })); const testObject = disposables.add(new DefaultConfiguration(configurationCache, TestEnvironmentService)); assert.deepStrictEqual(testObject.configurationModel.getValue('test.configurationDefaultsOverride'), undefined); @@ -78,7 +78,7 @@ suite('DefaultConfiguration', () => { test('configuration default overrides read from cache override environment', async () => { const environmentService = new BrowserWorkbenchEnvironmentService('', joinPath(URI.file('tests').with({ scheme: 'vscode-tests' }), 'logs'), { configurationDefaults: { 'test.configurationDefaultsOverride': 'envOverrideValue' } }, TestProductService); - window.localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); + localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); await configurationCache.write(cacheKey, JSON.stringify({ 'test.configurationDefaultsOverride': 'overrideValue' })); const testObject = disposables.add(new DefaultConfiguration(configurationCache, environmentService)); @@ -88,7 +88,7 @@ suite('DefaultConfiguration', () => { }); test('configuration default overrides are read from cache when default configuration changed', async () => { - window.localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); + localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); await configurationCache.write(cacheKey, JSON.stringify({ 'test.configurationDefaultsOverride': 'overrideValue' })); const testObject = disposables.add(new DefaultConfiguration(configurationCache, TestEnvironmentService)); await testObject.initialize(); @@ -110,7 +110,7 @@ suite('DefaultConfiguration', () => { }); test('configuration default overrides are not read from cache after reload', async () => { - window.localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); + localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); await configurationCache.write(cacheKey, JSON.stringify({ 'test.configurationDefaultsOverride': 'overrideValue' })); const testObject = disposables.add(new DefaultConfiguration(configurationCache, TestEnvironmentService)); @@ -121,7 +121,7 @@ suite('DefaultConfiguration', () => { }); test('cache is reset after reload', async () => { - window.localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); + localStorage.setItem(DefaultConfiguration.DEFAULT_OVERRIDES_CACHE_EXISTS_KEY, 'yes'); await configurationCache.write(cacheKey, JSON.stringify({ 'test.configurationDefaultsOverride': 'overrideValue' })); const testObject = disposables.add(new DefaultConfiguration(configurationCache, TestEnvironmentService)); diff --git a/src/vs/workbench/services/dialogs/browser/fileDialogService.ts b/src/vs/workbench/services/dialogs/browser/fileDialogService.ts index f37d110ad02..6c1a5f23341 100644 --- a/src/vs/workbench/services/dialogs/browser/fileDialogService.ts +++ b/src/vs/workbench/services/dialogs/browser/fileDialogService.ts @@ -19,6 +19,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { extractFileListData } from 'vs/platform/dnd/browser/dnd'; import { Iterable } from 'vs/base/common/iterator'; import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAccess'; +import { $window } from 'vs/base/browser/window'; export class FileDialogService extends AbstractFileDialogService implements IFileDialogService { @@ -57,13 +58,13 @@ export class FileDialogService extends AbstractFileDialogService implements IFil return super.pickFileAndOpenSimplified(schema, options, false); } - if (!WebFileSystemAccess.supported(window)) { + if (!WebFileSystemAccess.supported($window)) { return this.showUnsupportedBrowserWarning('open'); } let fileHandle: FileSystemHandle | undefined = undefined; try { - ([fileHandle] = await window.showOpenFilePicker({ multiple: false })); + ([fileHandle] = await $window.showOpenFilePicker({ multiple: false })); } catch (error) { return; // `showOpenFilePicker` will throw an error when the user cancels } @@ -116,7 +117,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil return super.pickFileToSaveSimplified(schema, options); } - if (!WebFileSystemAccess.supported(window)) { + if (!WebFileSystemAccess.supported($window)) { return this.showUnsupportedBrowserWarning('save'); } @@ -124,7 +125,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil const startIn = Iterable.first(this.fileSystemProvider.directories); try { - fileHandle = await window.showSaveFilePicker({ types: this.getFilePickerTypes(options.filters), ...{ suggestedName: basename(defaultUri), startIn } }); + fileHandle = await $window.showSaveFilePicker({ types: this.getFilePickerTypes(options.filters), ...{ suggestedName: basename(defaultUri), startIn } }); } catch (error) { return; // `showSaveFilePicker` will throw an error when the user cancels } @@ -157,7 +158,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil return super.showSaveDialogSimplified(schema, options); } - if (!WebFileSystemAccess.supported(window)) { + if (!WebFileSystemAccess.supported($window)) { return this.showUnsupportedBrowserWarning('save'); } @@ -165,7 +166,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil const startIn = Iterable.first(this.fileSystemProvider.directories); try { - fileHandle = await window.showSaveFilePicker({ types: this.getFilePickerTypes(options.filters), ...options.defaultUri ? { suggestedName: basename(options.defaultUri) } : undefined, ...{ startIn } }); + fileHandle = await $window.showSaveFilePicker({ types: this.getFilePickerTypes(options.filters), ...options.defaultUri ? { suggestedName: basename(options.defaultUri) } : undefined, ...{ startIn } }); } catch (error) { return undefined; // `showSaveFilePicker` will throw an error when the user cancels } @@ -184,7 +185,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil return super.showOpenDialogSimplified(schema, options); } - if (!WebFileSystemAccess.supported(window)) { + if (!WebFileSystemAccess.supported($window)) { return this.showUnsupportedBrowserWarning('open'); } @@ -193,12 +194,12 @@ export class FileDialogService extends AbstractFileDialogService implements IFil try { if (options.canSelectFiles) { - const handle = await window.showOpenFilePicker({ multiple: false, types: this.getFilePickerTypes(options.filters), ...{ startIn } }); + const handle = await $window.showOpenFilePicker({ multiple: false, types: this.getFilePickerTypes(options.filters), ...{ startIn } }); if (handle.length === 1 && WebFileSystemAccess.isFileSystemFileHandle(handle[0])) { uri = await this.fileSystemProvider.registerFileHandle(handle[0]); } } else { - const handle = await window.showDirectoryPicker({ ...{ startIn } }); + const handle = await $window.showDirectoryPicker({ ...{ startIn } }); uri = await this.fileSystemProvider.registerDirectoryHandle(handle); } } catch (error) { diff --git a/src/vs/workbench/services/driver/browser/driver.ts b/src/vs/workbench/services/driver/browser/driver.ts index 9d28065ff9d..bd7bb10afb7 100644 --- a/src/vs/workbench/services/driver/browser/driver.ts +++ b/src/vs/workbench/services/driver/browser/driver.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { getClientArea, getTopLeftOffset } from 'vs/base/browser/dom'; +import { mainWindow } from 'vs/base/browser/window'; import { coalesce } from 'vs/base/common/arrays'; import { language, locale } from 'vs/base/common/platform'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -221,5 +222,5 @@ export class BrowserWindowDriver implements IWindowDriver { } export function registerWindowDriver(instantiationService: IInstantiationService): void { - Object.assign(window, { driver: instantiationService.createInstance(BrowserWindowDriver) }); + Object.assign(mainWindow, { driver: instantiationService.createInstance(BrowserWindowDriver) }); } diff --git a/src/vs/workbench/services/driver/electron-sandbox/driver.ts b/src/vs/workbench/services/driver/electron-sandbox/driver.ts index 0e22f452451..ced26ec0ad5 100644 --- a/src/vs/workbench/services/driver/electron-sandbox/driver.ts +++ b/src/vs/workbench/services/driver/electron-sandbox/driver.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { mainWindow } from 'vs/base/browser/window'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -30,5 +31,5 @@ class NativeWindowDriver extends BrowserWindowDriver { } export function registerWindowDriver(instantiationService: IInstantiationService, helper: INativeWindowDriverHelper): void { - Object.assign(window, { driver: instantiationService.createInstance(NativeWindowDriver, helper) }); + Object.assign(mainWindow, { driver: instantiationService.createInstance(NativeWindowDriver, helper) }); } diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index 25885c7c4f9..a181772e8c4 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { mainWindow } from 'vs/base/browser/window'; import { Schemas } from 'vs/base/common/network'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; @@ -201,7 +202,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten this._doStopExtensionHosts(); // If we are running extension tests, forward logs and exit code - const automatedWindow = window as unknown as IAutomatedWindow; + const automatedWindow = mainWindow as unknown as IAutomatedWindow; if (typeof automatedWindow.codeAutomationExit === 'function') { automatedWindow.codeAutomationExit(code, await getLogs(this._fileService, this._environmentService)); } diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts index 8360a183c26..74aec081fa4 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts @@ -5,6 +5,7 @@ import * as dom from 'vs/base/browser/dom'; import { parentOriginHash } from 'vs/base/browser/iframe'; +import { $window } from 'vs/base/browser/window'; import { Barrier } from 'vs/base/common/async'; import { VSBuffer } from 'vs/base/common/buffer'; import { canceled, onUnexpectedError } from 'vs/base/common/errors'; @@ -97,7 +98,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost stableOriginUUID = generateUuid(); this._storageService.store(key, stableOriginUUID, StorageScope.WORKSPACE, StorageTarget.MACHINE); } - const hash = await parentOriginHash(window.origin, stableOriginUUID); + const hash = await parentOriginHash($window.origin, stableOriginUUID); const baseUrl = ( webEndpointUrlTemplate .replace('{{uuid}}', `v--${hash}`) // using `v--` as a marker to require `parentOrigin`/`salt` verification @@ -106,7 +107,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost ); const res = new URL(`${baseUrl}/out/${iframeModulePath}${suffix}`); - res.searchParams.set('parentOrigin', window.origin); + res.searchParams.set('parentOrigin', $window.origin); res.searchParams.set('salt', stableOriginUUID); return res.toString(); } @@ -165,7 +166,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost console.warn(`The Web Worker Extension Host did not start in 60s, that might be a problem.`); }, 60000); - this._register(dom.addDisposableListener(window, 'message', (event) => { + this._register(dom.addDisposableListener($window, 'message', (event) => { if (event.source !== iframe.contentWindow) { return; } diff --git a/src/vs/workbench/services/host/browser/browserHostService.ts b/src/vs/workbench/services/host/browser/browserHostService.ts index 691f04878de..930c6d76734 100644 --- a/src/vs/workbench/services/host/browser/browserHostService.ts +++ b/src/vs/workbench/services/host/browser/browserHostService.ts @@ -39,6 +39,7 @@ import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/c import { coalesce } from 'vs/base/common/arrays'; import { disposableInterval } from 'vs/base/common/async'; import { isAuxiliaryWindow } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService'; +import { mainWindow } from 'vs/base/browser/window'; /** * A workspace to open in the workbench can either be: @@ -192,7 +193,7 @@ export class BrowserHostService extends Disposable implements IHostService { Event.map(focusTracker.onDidBlur, () => this.hasFocus, disposables), Event.map(visibilityTracker.event, () => this.hasFocus, disposables), ), undefined, disposables)(focus => emitter.fire(focus)); - }, { window, disposables: this._store })); + }, { window: mainWindow, disposables: this._store })); return emitter.event; } @@ -238,7 +239,7 @@ export class BrowserHostService extends Disposable implements IHostService { return hasFocus; }, 100, 20)); } - }, { window, disposables: this._store })); + }, { window: mainWindow, disposables: this._store })); return Event.map(Event.latch(emitter.event, undefined, this._store), () => undefined, this._store); } @@ -553,13 +554,13 @@ export class BrowserHostService extends Disposable implements IHostService { async reload(): Promise { await this.handleExpectedShutdown(ShutdownReason.RELOAD); - window.location.reload(); + mainWindow.location.reload(); } async close(): Promise { await this.handleExpectedShutdown(ShutdownReason.CLOSE); - window.close(); + mainWindow.close(); } async withExpectedShutdown(expectedShutdownTask: () => Promise): Promise { diff --git a/src/vs/workbench/services/hover/browser/hoverService.ts b/src/vs/workbench/services/hover/browser/hoverService.ts index 85d660e0aca..f82473e813d 100644 --- a/src/vs/workbench/services/hover/browser/hoverService.ts +++ b/src/vs/workbench/services/hover/browser/hoverService.ts @@ -19,6 +19,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ResultKind } from 'vs/platform/keybinding/common/keybindingResolver'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; +import { mainWindow } from 'vs/base/browser/window'; export class HoverService implements IHoverService { declare readonly _serviceBrand: undefined; @@ -81,7 +82,7 @@ export class HoverService implements IHoverService { // Set the container explicitly to enable aux window support if (!options.container) { const targetElement = options.target instanceof HTMLElement ? options.target : options.target.targetElements[0]; - options.container = this._layoutService.getContainer(targetElement.ownerDocument.defaultView || window); + options.container = this._layoutService.getContainer(targetElement.ownerDocument.defaultView || mainWindow); } const provider = this._contextViewService as IContextViewProvider; provider.showContextView( @@ -112,7 +113,7 @@ export class HoverService implements IHoverService { } } - if ('IntersectionObserver' in window) { + if ('IntersectionObserver' in mainWindow) { const observer = new IntersectionObserver(e => this._intersectionChange(e, hover), { threshold: 0 }); const firstTargetElement = 'targetElements' in options.target ? options.target.targetElements[0] : options.target; observer.observe(firstTargetElement); diff --git a/src/vs/workbench/services/hover/browser/hoverWidget.ts b/src/vs/workbench/services/hover/browser/hoverWidget.ts index 68064146348..9cb6db70e2a 100644 --- a/src/vs/workbench/services/hover/browser/hoverWidget.ts +++ b/src/vs/workbench/services/hover/browser/hoverWidget.ts @@ -22,6 +22,7 @@ import { localize } from 'vs/nls'; import { isMacintosh } from 'vs/base/common/platform'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { status } from 'vs/base/browser/ui/aria/aria'; +import { $window, mainWindow } from 'vs/base/browser/window'; const $ = dom.$; type TargetRect = { @@ -60,7 +61,7 @@ export class HoverWidget extends Widget { private _addedFocusTrap: boolean = false; private get _targetWindow(): Window { - return this._target.targetElements?.[0].ownerDocument.defaultView || window; + return this._target.targetElements?.[0].ownerDocument.defaultView || mainWindow; } private get _targetDocumentElement(): HTMLElement { return this._target.targetElements?.[0].ownerDocument.documentElement; @@ -660,12 +661,12 @@ class CompositeMouseTracker extends Widget { this._clearEvaluateMouseStateTimeout(); // Evaluate whether the mouse is still outside asynchronously such that other mouse targets // have the opportunity to first their mouse in event. - this._mouseTimeout = window.setTimeout(() => this._fireIfMouseOutside(), 0); + this._mouseTimeout = $window.setTimeout(() => this._fireIfMouseOutside(), 0); } private _clearEvaluateMouseStateTimeout(): void { if (this._mouseTimeout) { - clearTimeout(this._mouseTimeout); + $window.clearTimeout(this._mouseTimeout); this._mouseTimeout = undefined; } } diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index ceb42385327..fb13ac6c764 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -22,6 +22,7 @@ import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecyc import * as objects from 'vs/base/common/objects'; import { isMacintosh, OperatingSystem, OS } from 'vs/base/common/platform'; import { dirname } from 'vs/base/common/resources'; +import { mainWindow } from 'vs/base/browser/window'; // platform import { MenuRegistry } from 'vs/platform/actions/common/actions'; @@ -42,6 +43,8 @@ import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { Registry } from 'vs/platform/registry/common/platform'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { ILocalizedString, isLocalizedString } from 'vs/platform/action/common/action'; // workbench import { commandsExtensionPoint } from 'vs/workbench/services/actions/common/menusExtensionPoint'; @@ -52,8 +55,6 @@ import { IKeyboard, INavigatorWithKeyboard } from 'vs/workbench/services/keybind import { getAllUnboundCommands } from 'vs/workbench/services/keybinding/browser/unboundCommands'; import { IUserKeybindingItem, KeybindingIO, OutputBuilder } from 'vs/workbench/services/keybinding/common/keybindingIO'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { ILocalizedString, isLocalizedString } from 'vs/platform/action/common/action'; interface ContributedKeyBinding { command: string; @@ -238,7 +239,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { this.updateKeybindingsJsonSchema(); this._register(extensionService.onDidRegisterExtensions(() => this.updateKeybindingsJsonSchema())); - this._register(Event.runAndSubscribe(dom.onDidRegisterWindow, ({ window, disposables }) => disposables.add(this._registerKeyListeners(window)), { window, disposables: this._store })); + this._register(Event.runAndSubscribe(dom.onDidRegisterWindow, ({ window, disposables }) => disposables.add(this._registerKeyListeners(window)), { window: mainWindow, disposables: this._store })); this._register(browser.onDidChangeFullscreen(() => { const keyboard: IKeyboard | null = (navigator).keyboard; diff --git a/src/vs/workbench/services/lifecycle/browser/lifecycleService.ts b/src/vs/workbench/services/lifecycle/browser/lifecycleService.ts index 407f87427be..c257d6ccc42 100644 --- a/src/vs/workbench/services/lifecycle/browser/lifecycleService.ts +++ b/src/vs/workbench/services/lifecycle/browser/lifecycleService.ts @@ -12,6 +12,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { addDisposableListener, EventType } from 'vs/base/browser/dom'; import { IStorageService, WillSaveStateReason } from 'vs/platform/storage/common/storage'; import { CancellationToken } from 'vs/base/common/cancellation'; +import { mainWindow } from 'vs/base/browser/window'; export class BrowserLifecycleService extends AbstractLifecycleService { @@ -34,14 +35,14 @@ export class BrowserLifecycleService extends AbstractLifecycleService { private registerListeners(): void { // Listen to `beforeUnload` to support to veto - this.beforeUnloadListener = addDisposableListener(window, EventType.BEFORE_UNLOAD, (e: BeforeUnloadEvent) => this.onBeforeUnload(e)); + this.beforeUnloadListener = addDisposableListener(mainWindow, EventType.BEFORE_UNLOAD, (e: BeforeUnloadEvent) => this.onBeforeUnload(e)); // Listen to `pagehide` to support orderly shutdown // We explicitly do not listen to `unload` event // which would disable certain browser caching. // We currently do not handle the `persisted` property // (https://github.com/microsoft/vscode/issues/136216) - this.unloadListener = addDisposableListener(window, EventType.PAGE_HIDE, () => this.onUnload()); + this.unloadListener = addDisposableListener(mainWindow, EventType.PAGE_HIDE, () => this.onUnload()); } private onBeforeUnload(event: BeforeUnloadEvent): void { @@ -162,7 +163,7 @@ export class BrowserLifecycleService extends AbstractLifecycleService { this.didUnload = true; // Register a late `pageshow` listener specifically on unload - this._register(addDisposableListener(window, EventType.PAGE_SHOW, (e: PageTransitionEvent) => this.onLoadAfterUnload(e))); + this._register(addDisposableListener(mainWindow, EventType.PAGE_SHOW, (e: PageTransitionEvent) => this.onLoadAfterUnload(e))); // First indicate will-shutdown const logService = this.logService; @@ -197,7 +198,7 @@ export class BrowserLifecycleService extends AbstractLifecycleService { // currently can only reload the window // Docs: https://web.dev/bfcache/#optimize-your-pages-for-bfcache // Refs: https://github.com/microsoft/vscode/issues/136035 - this.withExpectedShutdown({ disableShutdownHandling: true }, () => window.location.reload()); + this.withExpectedShutdown({ disableShutdownHandling: true }, () => mainWindow.location.reload()); } } diff --git a/src/vs/workbench/services/localization/browser/localeService.ts b/src/vs/workbench/services/localization/browser/localeService.ts index 37a95777261..0d9c51c72cf 100644 --- a/src/vs/workbench/services/localization/browser/localeService.ts +++ b/src/vs/workbench/services/localization/browser/localeService.ts @@ -32,13 +32,13 @@ export class WebLocaleService implements ILocaleService { return; } if (locale) { - window.localStorage.setItem(WebLocaleService._LOCAL_STORAGE_LOCALE_KEY, locale); + localStorage.setItem(WebLocaleService._LOCAL_STORAGE_LOCALE_KEY, locale); if (languagePackItem.extensionId) { - window.localStorage.setItem(WebLocaleService._LOCAL_STORAGE_EXTENSION_ID_KEY, languagePackItem.extensionId); + localStorage.setItem(WebLocaleService._LOCAL_STORAGE_EXTENSION_ID_KEY, languagePackItem.extensionId); } } else { - window.localStorage.removeItem(WebLocaleService._LOCAL_STORAGE_LOCALE_KEY); - window.localStorage.removeItem(WebLocaleService._LOCAL_STORAGE_EXTENSION_ID_KEY); + localStorage.removeItem(WebLocaleService._LOCAL_STORAGE_LOCALE_KEY); + localStorage.removeItem(WebLocaleService._LOCAL_STORAGE_EXTENSION_ID_KEY); } const restartDialog = await this.dialogService.confirm({ @@ -54,8 +54,8 @@ export class WebLocaleService implements ILocaleService { } async clearLocalePreference(): Promise { - window.localStorage.removeItem(WebLocaleService._LOCAL_STORAGE_LOCALE_KEY); - window.localStorage.removeItem(WebLocaleService._LOCAL_STORAGE_EXTENSION_ID_KEY); + localStorage.removeItem(WebLocaleService._LOCAL_STORAGE_LOCALE_KEY); + localStorage.removeItem(WebLocaleService._LOCAL_STORAGE_EXTENSION_ID_KEY); if (Language.value() === navigator.language.toLowerCase()) { return; @@ -87,7 +87,7 @@ class WebActiveLanguagePackService implements IActiveLanguagePackService { if (language === LANGUAGE_DEFAULT) { return undefined; } - const extensionId = window.localStorage.getItem(WebLocaleService._LOCAL_STORAGE_EXTENSION_ID_KEY); + const extensionId = localStorage.getItem(WebLocaleService._LOCAL_STORAGE_EXTENSION_ID_KEY); if (extensionId) { return extensionId; } @@ -102,7 +102,7 @@ class WebActiveLanguagePackService implements IActiveLanguagePackService { // Only install extensions that are published by Microsoft and start with vscode-language-pack for extra certainty const extensionToInstall = tagResult.firstPage.find(e => e.publisher === 'MS-CEINTL' && e.name.startsWith('vscode-language-pack')); if (extensionToInstall) { - window.localStorage.setItem(WebLocaleService._LOCAL_STORAGE_EXTENSION_ID_KEY, extensionToInstall.identifier.id); + localStorage.setItem(WebLocaleService._LOCAL_STORAGE_EXTENSION_ID_KEY, extensionToInstall.identifier.id); return extensionToInstall.identifier.id; } diff --git a/src/vs/workbench/services/themes/browser/browserHostColorSchemeService.ts b/src/vs/workbench/services/themes/browser/browserHostColorSchemeService.ts index 09cabf53111..ac32b57b136 100644 --- a/src/vs/workbench/services/themes/browser/browserHostColorSchemeService.ts +++ b/src/vs/workbench/services/themes/browser/browserHostColorSchemeService.ts @@ -8,6 +8,7 @@ import { addMatchMediaChangeListener } from 'vs/base/browser/browser'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { Disposable } from 'vs/base/common/lifecycle'; import { IHostColorSchemeService } from 'vs/workbench/services/themes/common/hostColorSchemeService'; +import { mainWindow } from 'vs/base/browser/window'; export class BrowserHostColorSchemeService extends Disposable implements IHostColorSchemeService { @@ -37,16 +38,16 @@ export class BrowserHostColorSchemeService extends Disposable implements IHostCo } get dark(): boolean { - if (window.matchMedia(`(prefers-color-scheme: light)`).matches) { + if (mainWindow.matchMedia(`(prefers-color-scheme: light)`).matches) { return false; - } else if (window.matchMedia(`(prefers-color-scheme: dark)`).matches) { + } else if (mainWindow.matchMedia(`(prefers-color-scheme: dark)`).matches) { return true; } return false; } get highContrast(): boolean { - if (window.matchMedia(`(forced-colors: active)`).matches) { + if (mainWindow.matchMedia(`(forced-colors: active)`).matches) { return true; } return false; diff --git a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts index ed92048b244..228ff00394c 100644 --- a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts +++ b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts @@ -14,6 +14,7 @@ import { asCSSUrl } from 'vs/base/browser/dom'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IExtensionResourceLoaderService } from 'vs/platform/extensionResourceLoader/common/extensionResourceLoader'; import { ILanguageService } from 'vs/editor/common/languages/language'; +import { $window } from 'vs/base/browser/window'; export class FileIconThemeData implements IWorkbenchFileIconTheme { @@ -465,5 +466,5 @@ function handleParentFolder(key: string, selectors: string[]): string { function escapeCSS(str: string) { str = str.replace(/[\11\12\14\15\40]/g, '/'); // HTML class names can not contain certain whitespace characters, use / instead, which doesn't exist in file names. - return window.CSS.escape(str); + return $window.CSS.escape(str); } diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 546e3a6e360..a7c4ffa8ad4 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -167,6 +167,7 @@ import { IRemoteExtensionsScannerService } from 'vs/platform/remote/common/remot import { IRemoteSocketFactoryService, RemoteSocketFactoryService } from 'vs/platform/remote/common/remoteSocketFactoryService'; import { EditorParts } from 'vs/workbench/browser/parts/editor/editorParts'; import { TestAccessibleNotificationService } from 'vs/workbench/contrib/accessibility/browser/accessibleNotificationService'; +import { mainWindow } from 'vs/base/browser/window'; export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined, undefined, undefined, undefined); @@ -594,9 +595,9 @@ export class TestLayoutService implements IWorkbenchLayoutService { activeContainerOffset: ILayoutOffsetInfo = { top: 0, quickPickTop: 0 }; hasContainer = true; - container: HTMLElement = window.document.body; - containers = [window.document.body]; - activeContainer: HTMLElement = window.document.body; + container: HTMLElement = mainWindow.document.body; + containers = [mainWindow.document.body]; + activeContainer: HTMLElement = mainWindow.document.body; onDidChangeZenMode: Event = Event.None; onDidChangeCenteredLayout: Event = Event.None; From 9e2e552303c551fe519244c890a5e6c097f9c5fe Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Mon, 6 Nov 2023 09:36:29 -0800 Subject: [PATCH 028/240] Fix typo in chat code block action title (#197568) Fixes https://github.com/microsoft/vscode-copilot-release/issues/537 --- .../contrib/chat/browser/actions/chatCodeblockActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts index 4a5e08e11f5..c9f578dc2ec 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts @@ -353,8 +353,8 @@ export function registerChatCodeBlockActions() { super({ id: 'workbench.action.chat.insertIntoNewFile', title: { - value: localize('interactive.insertIntoNewFile.label', "Insert Into New File"), - original: 'Insert Into New File' + value: localize('interactive.insertIntoNewFile.label', "Insert into New File"), + original: 'Insert into New File' }, precondition: CONTEXT_PROVIDER_EXISTS, f1: true, From aa492a64c2d1dd2c5be8aea3a7fe35197144c3c2 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 09:55:05 -0800 Subject: [PATCH 029/240] add command finished listener for windows/screen reader --- .../common/capabilities/capabilities.ts | 1 + .../commandDetectionCapability.ts | 4 +++ .../terminal.accessibility.contribution.ts | 28 +++++++++++++------ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/vs/platform/terminal/common/capabilities/capabilities.ts b/src/vs/platform/terminal/common/capabilities/capabilities.ts index 3c3bec8dd6d..e4b57f8fdd0 100644 --- a/src/vs/platform/terminal/common/capabilities/capabilities.ts +++ b/src/vs/platform/terminal/common/capabilities/capabilities.ts @@ -167,6 +167,7 @@ export interface ICommandDetectionCapability { readonly executingCommandObject: ITerminalCommand | undefined; /** The current cwd at the cursor's position. */ readonly cwd: string | undefined; + get isWindowsPty(): boolean; /** * Whether a command is currently being input. If the a command is current not being input or * the state cannot reliably be detected the fallback of undefined will be used. diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index 720fdfa5bf4..79cd8aa0eeb 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -530,6 +530,10 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe this._onCommandExecuted.fire(); } + get isWindowsPty(): boolean { + return this._isWindowsPty; + } + private async _handleCommandExecutedWindows(): Promise { await this._commandStartedWindowsBarrier?.wait(); // On Windows, use the gathered cursor move markers to correct the command start and diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index d5a1082b647..7da5c5bee2e 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -6,7 +6,7 @@ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { localize } from 'vs/nls'; -import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; +import { CONTEXT_ACCESSIBILITY_MODE_ENABLED, IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; @@ -66,12 +66,13 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT private _bufferTracker: BufferContentTracker | undefined; private _bufferProvider: TerminalAccessibleBufferProvider | undefined; private _xterm: Pick & { raw: Terminal } | undefined; - private _onCommandExecutedShowListener: MutableDisposable = new MutableDisposable(); + private _onDidRunCommand: MutableDisposable = new MutableDisposable(); constructor( private readonly _instance: ITerminalInstance, processManager: ITerminalProcessManager, widgetManager: TerminalWidgetManager, + @IAccessibilityService private readonly _accessibilityService: IAccessibilityService, @IAccessibleViewService private readonly _accessibleViewService: IAccessibleViewService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @ITerminalService private readonly _terminalService: ITerminalService, @@ -129,18 +130,27 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT return; } if (!this._configurationService.getValue(TerminalSettingId.AccessibleViewFocusOnCommandExecution)) { - this._onCommandExecutedShowListener.clear(); + this._onDidRunCommand.clear(); return; - } else if (this._onCommandExecutedShowListener.value) { + } else if (this._onDidRunCommand.value) { return; } const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection)!; - this._onCommandExecutedShowListener.value = this._register(capability.onCommandExecuted(() => { - if (this._instance.hasFocus) { - this.show(); - } - })); + const hasCommandExecuted = capability.isWindowsPty && this._accessibilityService.isScreenReaderOptimized(); + if (hasCommandExecuted) { + this._onDidRunCommand.value = this._register(capability.onCommandExecuted(() => { + if (this._instance.hasFocus) { + this.show(); + } + })); + } else { + this._onDidRunCommand.value = this._register(capability.onCommandFinished(() => { + if (this._instance.hasFocus) { + this.show(); + } + })); + } } private _isTerminalAccessibleViewOpen(): boolean { From fc3eb50946f89c9641abe627cf15ffcaa4f80000 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 10:04:28 -0800 Subject: [PATCH 030/240] fix #197413 --- .../workbench/contrib/accessibility/browser/accessibleView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index b348ffd8111..f2300e1afaf 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -501,10 +501,10 @@ export class AccessibleView extends Disposable { this._updateToolbar(provider.actions, provider.options.type); const hide = (e: KeyboardEvent | IKeyboardEvent): void => { + provider.onClose(); e.stopPropagation(); this._contextViewService.hideContextView(); this._updateContextKeys(provider, false); - provider.onClose(); }; const disposableStore = new DisposableStore(); disposableStore.add(this._editorWidget.onKeyDown((e) => { From 770d3c13d445e38feea3d0c5aeb093f0d906fd5e Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 10:14:48 -0800 Subject: [PATCH 031/240] streamline --- .../terminal.accessibility.contribution.ts | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index 7da5c5bee2e..bb06e18fd5e 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -138,19 +138,11 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection)!; const hasCommandExecuted = capability.isWindowsPty && this._accessibilityService.isScreenReaderOptimized(); - if (hasCommandExecuted) { - this._onDidRunCommand.value = this._register(capability.onCommandExecuted(() => { - if (this._instance.hasFocus) { - this.show(); - } - })); - } else { - this._onDidRunCommand.value = this._register(capability.onCommandFinished(() => { - if (this._instance.hasFocus) { - this.show(); - } - })); - } + this._onDidRunCommand.value = this._register((hasCommandExecuted ? capability.onCommandExecuted : capability.onCommandFinished)(() => { + if (this._instance.hasFocus) { + this.show(); + } + })); } private _isTerminalAccessibleViewOpen(): boolean { From 3c96837d489495302cd3f6a05f333d34c3ff9870 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 10:33:49 -0800 Subject: [PATCH 032/240] add pre command finished listener --- .../common/capabilities/capabilities.ts | 1 + .../capabilities/commandDetectionCapability.ts | 3 +++ .../terminal.accessibility.contribution.ts | 18 +++++++++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/vs/platform/terminal/common/capabilities/capabilities.ts b/src/vs/platform/terminal/common/capabilities/capabilities.ts index e4b57f8fdd0..4c45d7a81ca 100644 --- a/src/vs/platform/terminal/common/capabilities/capabilities.ts +++ b/src/vs/platform/terminal/common/capabilities/capabilities.ts @@ -176,6 +176,7 @@ export interface ICommandDetectionCapability { readonly currentCommand: ICurrentPartialCommand | undefined; readonly onCommandStarted: Event; readonly onCommandFinished: Event; + readonly onPreCommandFinishedWindows: Event; readonly onCommandExecuted: Event; readonly onCommandInvalidated: Event; readonly onCurrentCommandInvalidated: Event; diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index 79cd8aa0eeb..9ebac86a310 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -109,6 +109,8 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe readonly onBeforeCommandFinished = this._onBeforeCommandFinished.event; private readonly _onCommandFinished = this._register(new Emitter()); readonly onCommandFinished = this._onCommandFinished.event; + private readonly _onPreCommandFinishedWindows = this._register(new Emitter()); + readonly onPreCommandFinishedWindows = this._onPreCommandFinishedWindows.event; private readonly _onCommandExecuted = this._register(new Emitter()); readonly onCommandExecuted = this._onCommandExecuted.event; private readonly _onCommandInvalidated = this._register(new Emitter()); @@ -625,6 +627,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe if (this._currentCommand.commandStartMarker) { this._commandMarkers.push(this._currentCommand.commandStartMarker); } + this._onPreCommandFinishedWindows.fire(); } this._evaluateCommandMarkersWindows(); } diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index bb06e18fd5e..c6b15059bd0 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -67,17 +67,18 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT private _bufferProvider: TerminalAccessibleBufferProvider | undefined; private _xterm: Pick & { raw: Terminal } | undefined; private _onDidRunCommand: MutableDisposable = new MutableDisposable(); + private _onDidPreCommandFinishWindows: MutableDisposable = new MutableDisposable(); constructor( private readonly _instance: ITerminalInstance, processManager: ITerminalProcessManager, widgetManager: TerminalWidgetManager, - @IAccessibilityService private readonly _accessibilityService: IAccessibilityService, @IAccessibleViewService private readonly _accessibleViewService: IAccessibleViewService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @ITerminalService private readonly _terminalService: ITerminalService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @IContextKeyService private readonly _contextKeyService: IContextKeyService) { + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IAccessibilityService private readonly _accessibilityService: IAccessibilityService) { super(); this._register(AccessibleViewAction.addImplementation(90, 'terminal', () => { if (this._terminalService.activeInstance !== this._instance) { @@ -132,17 +133,24 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT if (!this._configurationService.getValue(TerminalSettingId.AccessibleViewFocusOnCommandExecution)) { this._onDidRunCommand.clear(); return; - } else if (this._onDidRunCommand.value) { + } else if (this._onDidRunCommand.value && this._onDidPreCommandFinishWindows.value) { return; } const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection)!; - const hasCommandExecuted = capability.isWindowsPty && this._accessibilityService.isScreenReaderOptimized(); - this._onDidRunCommand.value = this._register((hasCommandExecuted ? capability.onCommandExecuted : capability.onCommandFinished)(() => { + this._onDidRunCommand.value = this._register(capability.onCommandExecuted(() => { if (this._instance.hasFocus) { this.show(); } })); + if (capability.isWindowsPty && this._accessibilityService.isScreenReaderOptimized()) { + // It's possible command executed never happens (for example if PSReadLine is disabled) + this._onDidPreCommandFinishWindows.value = this._register(capability.onCommandExecuted(() => { + if (this._instance.hasFocus) { + this.show(); + } + })); + } } private _isTerminalAccessibleViewOpen(): boolean { From 4618e70023c1ab654d6b7a554f0725e615bad68c Mon Sep 17 00:00:00 2001 From: Gary Ritchie Date: Mon, 6 Nov 2023 11:38:32 -0700 Subject: [PATCH 033/240] aria-hide search icon --- src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts b/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts index 71ea3a1aca2..6a50aff59a5 100644 --- a/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts @@ -142,6 +142,7 @@ class CommandCenterCenterViewItem extends BaseActionViewItem { // icon (search) const searchIcon = document.createElement('span'); + searchIcon.ariaHidden = 'true'; searchIcon.className = action.class ?? ''; searchIcon.classList.add('search-icon'); From f73d54d32f8d6259a67ca2bcbdd43fd435cc1f16 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Mon, 6 Nov 2023 10:41:51 -0800 Subject: [PATCH 034/240] rm accessibility service check --- .../browser/terminal.accessibility.contribution.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index c6b15059bd0..25474cd0173 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -6,7 +6,7 @@ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { localize } from 'vs/nls'; -import { CONTEXT_ACCESSIBILITY_MODE_ENABLED, IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; @@ -77,8 +77,7 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT @IInstantiationService private readonly _instantiationService: IInstantiationService, @ITerminalService private readonly _terminalService: ITerminalService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @IContextKeyService private readonly _contextKeyService: IContextKeyService, - @IAccessibilityService private readonly _accessibilityService: IAccessibilityService) { + @IContextKeyService private readonly _contextKeyService: IContextKeyService) { super(); this._register(AccessibleViewAction.addImplementation(90, 'terminal', () => { if (this._terminalService.activeInstance !== this._instance) { @@ -143,9 +142,9 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT this.show(); } })); - if (capability.isWindowsPty && this._accessibilityService.isScreenReaderOptimized()) { - // It's possible command executed never happens (for example if PSReadLine is disabled) - this._onDidPreCommandFinishWindows.value = this._register(capability.onCommandExecuted(() => { + if (capability.isWindowsPty) { + // It's possible command executed never happens (for example, if PSReadLine is disabled) + this._onDidPreCommandFinishWindows.value = this._register(capability.onPreCommandFinishedWindows(() => { if (this._instance.hasFocus) { this.show(); } From 22054c0fea1b10e82a47285135c18456c630a433 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 10:44:14 -0800 Subject: [PATCH 035/240] tweak conditions --- .../browser/terminal.accessibility.contribution.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index 25474cd0173..70f46c1bcab 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -131,8 +131,9 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT } if (!this._configurationService.getValue(TerminalSettingId.AccessibleViewFocusOnCommandExecution)) { this._onDidRunCommand.clear(); + this._onDidPreCommandFinishWindows.clear(); return; - } else if (this._onDidRunCommand.value && this._onDidPreCommandFinishWindows.value) { + } else if (this._onDidRunCommand.value || this._onDidPreCommandFinishWindows.value) { return; } From fa69fb5171d77b31e1e1cc798da9b530d53040f3 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 10:44:38 -0800 Subject: [PATCH 036/240] rm one condition --- .../browser/terminal.accessibility.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index 70f46c1bcab..e6596557ab0 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -133,7 +133,7 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT this._onDidRunCommand.clear(); this._onDidPreCommandFinishWindows.clear(); return; - } else if (this._onDidRunCommand.value || this._onDidPreCommandFinishWindows.value) { + } else if (this._onDidRunCommand.value) { return; } From 93541397f5dfb3f37b7cafda5ba6a8104b9c5f68 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 10:54:16 -0800 Subject: [PATCH 037/240] fix #197388 --- .../browser/parts/notifications/notificationsCommands.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts b/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts index d341f22ee65..c0cb078cbbc 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts @@ -164,11 +164,11 @@ export function registerNotificationCommands(center: INotificationsCenterControl KeybindingsRegistry.registerCommandAndKeybindingRule({ id: ACCEPT_PRIMARY_ACTION_NOTIFICATION, weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(NotificationFocusedContext), + when: ContextKeyExpr.or(NotificationFocusedContext, NotificationsToastsVisibleContext), primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyA, handler: (accessor) => { const actionRunner = accessor.get(IInstantiationService).createInstance(NotificationActionRunner); - const notification = getNotificationFromContext(accessor.get(IListService)); + const notification = getNotificationFromContext(accessor.get(IListService)) || firstOrDefault(model.notifications); if (!notification) { return; } From 38395b289d5827801f638e884c4fdabe7089360f Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 6 Nov 2023 10:58:33 -0800 Subject: [PATCH 038/240] Impl click to scroll, reuse from mark nav --- .../contrib/terminal/browser/terminal.ts | 14 ++++---- .../browser/xterm/markNavigationAddon.ts | 18 ++++++---- .../terminal/browser/xterm/xtermTerminal.ts | 6 +++- .../browser/media/stickyScroll.css | 19 ++++++++++- .../terminal.stickyScroll.contribution.ts | 34 +++++++++++++------ 5 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index c13ea3da3f7..797bc5612eb 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -20,12 +20,12 @@ import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { IEditableData } from 'vs/workbench/common/views'; import { ITerminalStatusList } from 'vs/workbench/contrib/terminal/browser/terminalStatusList'; -import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; import { XtermTerminal } from 'vs/workbench/contrib/terminal/browser/xterm/xtermTerminal'; import { IRegisterContributedProfileArgs, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalFont, ITerminalProcessExtHostProxy, ITerminalProcessInfo } from 'vs/workbench/contrib/terminal/common/terminal'; import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { ISimpleSelectedSuggestion } from 'vs/workbench/services/suggest/browser/simpleSuggestWidget'; import type { IMarker, ITheme, Terminal as RawXtermTerminal } from '@xterm/xterm'; +import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; export const ITerminalService = createDecorator('terminalService'); export const ITerminalEditorService = createDecorator('terminalEditorService'); @@ -107,6 +107,7 @@ export interface IMarkTracker { selectToNextLine(): void; clearMarker(): void; scrollToClosestMarker(startMarkerId: string, endMarkerId?: string, highlight?: boolean | undefined): void; + scrollToLine(line: number, position: ScrollPosition): void; } export interface ITerminalGroup { @@ -1114,12 +1115,13 @@ export interface IXtermTerminal extends IDisposable { */ focus(): void; - /** Scroll the terminal buffer down 1 line. */ scrollDownLine(): void; - /** Scroll the terminal buffer down 1 page. */ scrollDownPage(): void; + /** Scroll the terminal buffer down 1 line. */ scrollDownLine(): void; + /** Scroll the terminal buffer down 1 page. */ scrollDownPage(): void; /** Scroll the terminal buffer to the bottom. */ scrollToBottom(): void; - /** Scroll the terminal buffer up 1 line. */ scrollUpLine(): void; - /** Scroll the terminal buffer up 1 page. */ scrollUpPage(): void; - /** Scroll the terminal buffer to the top. */ scrollToTop(): void; + /** Scroll the terminal buffer up 1 line. */ scrollUpLine(): void; + /** Scroll the terminal buffer up 1 page. */ scrollUpPage(): void; + /** Scroll the terminal buffer to the top. */ scrollToTop(): void; + /** Scroll the terminal buffer to a set line */ scrollToLine(line: number, position?: ScrollPosition): void; /** * Clears the terminal buffer, leaving only the prompt line and moving it to the top of the diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts index 3ec8a0f746f..1d90c7a1f75 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts @@ -103,7 +103,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe let markerIndex; const currentLineY = typeof this._currentMarker === 'object' - ? this._getTargetScrollLine(this._terminal, this._currentMarker, scrollPosition) + ? this.getTargetScrollLine(this._currentMarker.line, scrollPosition) : Math.min(getLine(this._terminal, this._currentMarker), this._terminal.buffer.active.baseY); const viewportY = this._terminal.buffer.active.viewportY; if (typeof this._currentMarker === 'object' ? !this._isMarkerInViewport(this._terminal, this._currentMarker) : currentLineY !== viewportY) { @@ -149,7 +149,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe let markerIndex; const currentLineY = typeof this._currentMarker === 'object' - ? this._getTargetScrollLine(this._terminal, this._currentMarker, scrollPosition) + ? this.getTargetScrollLine(this._currentMarker.line, scrollPosition) : Math.min(getLine(this._terminal, this._currentMarker), this._terminal.buffer.active.baseY); const viewportY = this._terminal.buffer.active.viewportY; if (typeof this._currentMarker === 'object' ? !this._isMarkerInViewport(this._terminal, this._currentMarker) : currentLineY !== viewportY) { @@ -190,7 +190,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe return; } if (!this._isMarkerInViewport(this._terminal, marker)) { - const line = this._getTargetScrollLine(this._terminal, marker, position); + const line = this.getTargetScrollLine(marker.line, position); this._terminal.scrollToLine(line); } if (!hideDecoration) { @@ -256,13 +256,17 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe } } - private _getTargetScrollLine(terminal: Terminal, marker: IMarker, position: ScrollPosition) { + scrollToLine(line: number, position: ScrollPosition): void { + this._terminal?.scrollToLine(this.getTargetScrollLine(line, position)); + } + + getTargetScrollLine(line: number, position: ScrollPosition): number { // Middle is treated at 1/4 of the viewport's size because context below is almost always // more important than context above in the terminal. - if (position === ScrollPosition.Middle) { - return Math.max(marker.line - Math.floor(terminal.rows / 4), 0); + if (this._terminal && position === ScrollPosition.Middle) { + return Math.max(line - Math.floor(this._terminal.rows / 4), 0); } - return marker.line; + return line; } private _isMarkerInViewport(terminal: Terminal, marker: IMarker) { diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index 001c43f1992..c959b0cf5f8 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -24,7 +24,7 @@ import { LogLevel } from 'vs/platform/log/common/log'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { TerminalStorageKeys } from 'vs/workbench/contrib/terminal/common/terminalStorageKeys'; import { INotificationService, IPromptChoice, Severity } from 'vs/platform/notification/common/notification'; -import { MarkNavigationAddon } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; +import { MarkNavigationAddon, ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; import { localize } from 'vs/nls'; import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; @@ -591,6 +591,10 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach this.raw.scrollToTop(); } + scrollToLine(line: number, position: ScrollPosition = ScrollPosition.Top): void { + this.markTracker.scrollToLine(line, position); + } + clearBuffer(): void { this.raw.clear(); // xterm.js does not clear the first prompt, so trigger these to simulate diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css index 49d0f7bcc31..453350ffa28 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css @@ -8,14 +8,31 @@ left: 0; right: 0; top: 0; - background: red; z-index: 32; /* Must be higher than .xterm-viewport and decorations*/ /* TODO: Sticky scroll background key */ background: var(--vscode-terminal-background, var(--vscode-panel-background)); box-shadow: var(--vscode-scrollbar-shadow) 0 3px 2px -2px; } +.terminal-sticky-scroll:hover { + cursor: pointer !important; +} + .terminal-sticky-scroll .xterm { /* TODO: Remove !important */ position: relative !important; + pointer-events: none; +} + +.terminal-sticky-scroll .hover-overlay { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + cursor: pointer !important; +} + +.terminal-sticky-scroll .hover-overlay:hover { + background-color: var(--vscode-editorStickyScrollHover-background, #ffffff10); } diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index faaea85e909..3d57c6acc20 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -3,22 +3,23 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/css!./media/stickyScroll'; +import type { CanvasAddon as CanvasAddonType } from '@xterm/addon-canvas'; +import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; +import type { IMarker, Terminal as RawXtermTerminal } from '@xterm/xterm'; +import { importAMDNodeModule } from 'vs/amdX'; +import { $, addStandardDisposableListener, append, hide, setVisibility, show } from 'vs/base/browser/dom'; import { throttle } from 'vs/base/common/decorators'; import { DisposableStore } from 'vs/base/common/lifecycle'; +import 'vs/css!./media/stickyScroll'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { ITerminalContribution, ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; -import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; -import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; -import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; -import type { CanvasAddon as CanvasAddonType } from '@xterm/addon-canvas'; -import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; -import { hide, setVisibility, show } from 'vs/base/browser/dom'; import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { importAMDNodeModule } from 'vs/amdX'; +import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; +import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; +import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; let CanvasAddon: typeof CanvasAddonType; let SerializeAddon: typeof SerializeAddonType; @@ -33,6 +34,9 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi private _xterm?: IXtermTerminal & { raw: RawXtermTerminal }; private _element?: HTMLElement; private _stickyScrollOverlay?: RawXtermTerminal; + + private _currentStickyMarker?: IMarker; + private _serializeAddon?: SerializeAddonType; private _canvasAddon?: CanvasAddonType; @@ -84,6 +88,7 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi if (!this._xterm?.raw?.element) { return; } + this._currentStickyMarker = undefined; // TODO: Cache const commandDetection = this._instance.capabilities.get(TerminalCapability.CommandDetection); if (!commandDetection) { @@ -99,6 +104,7 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi if (!marker || marker.line === -1) { return; } + this._currentStickyMarker = marker; const element = this._ensureElement(); // element.textContent = this._xterm.raw.buffer.active.getLine(marker.line)?.translateToString(true) ?? ''; if (element.textContent === '') { @@ -134,10 +140,18 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi // // TODO: Safety this._xterm!.raw.element!.parentElement!.append(this._element); + const hoverOverlay = $('.hover-overlay'); + this.add(addStandardDisposableListener(hoverOverlay, 'click', e => { + if (this._xterm && this._currentStickyMarker) { + this._xterm.scrollToLine(this._currentStickyMarker.line, ScrollPosition.Middle); + } + })); // TODO: Add to a container outside the xterm instance? // TODO: Remove ! this._stickyScrollOverlay!.open(this._element); + + append(this._element, hoverOverlay); } return this._element; From 6afac1d3f7f671b321faf85e75d9509d93b4a04c Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Mon, 6 Nov 2023 09:43:57 -0800 Subject: [PATCH 039/240] fix stack trace linking --- .../notebook-renderers/src/stackTraceHelper.ts | 4 ++-- .../src/test/stackTraceHelper.test.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/extensions/notebook-renderers/src/stackTraceHelper.ts b/extensions/notebook-renderers/src/stackTraceHelper.ts index e72c3b8a88c..3ac30abaf6b 100644 --- a/extensions/notebook-renderers/src/stackTraceHelper.ts +++ b/extensions/notebook-renderers/src/stackTraceHelper.ts @@ -31,7 +31,7 @@ export function formatStackTrace(stack: string) { const formatSequence = /\u001b\[.+?m/g; const fileRegex = /File\s+(?:\u001b\[.+?m)?(.+):(\d+)/; -const lineNumberRegex = /((?:\u001b\[.+?m)?[ ->]*?)(\d+)(.*)/; +const lineNumberRegex = /^((?:\u001b\[.+?m)?[ ->]*?)(\d+)(.*)/; const cellRegex = /(?Cell\s+(?:\u001b\[.+?m)?In\s*\[(?\d+)\],\s*)(?line (?\d+)).*/; // older versions of IPython ~8.3.0 const inputRegex = /(?Input\s+?(?:\u001b\[.+?m)(?In\s*\[(?\d+)\]))(?.*)/; @@ -41,7 +41,7 @@ function isIpythonStackTrace(stack: string) { } function stripFormatting(text: string) { - return text.replace(formatSequence, ''); + return text.replace(formatSequence, '').trim(); } type cellLocation = { kind: 'cell'; path: string }; diff --git a/extensions/notebook-renderers/src/test/stackTraceHelper.test.ts b/extensions/notebook-renderers/src/test/stackTraceHelper.test.ts index e65efe3ee29..da7f9d0e2e4 100644 --- a/extensions/notebook-renderers/src/test/stackTraceHelper.test.ts +++ b/extensions/notebook-renderers/src/test/stackTraceHelper.test.ts @@ -88,4 +88,16 @@ suite('StackTraceHelper', () => { assert.ok(!/\d<\/a>/.test(formatted), formatted); }); + test('IPython stack without line numbers are not linkified', () => { + const stack = + '\u001b[1;36m Cell \u001b[1;32mIn[6], line 1\u001b[1;36m\u001b[0m\n' + + '\u001b[1;33m print(\u001b[0m\n' + + '\u001b[1;37m ^\u001b[0m\n' + + '\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m incomplete input\n'; + + const formattedLines = formatStackTrace(stack).split('\n'); + assert.ok(/ assert.ok(!//.test(line), 'line should not contain a link: ' + line)); + }); + }); From 8ba75dfdc854a4d1eed0c73a08bcb7fa9b48f4b9 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Mon, 6 Nov 2023 10:26:59 -0800 Subject: [PATCH 040/240] more strict on regex, fix special character --- extensions/notebook-renderers/src/stackTraceHelper.ts | 2 +- .../notebook-renderers/src/test/stackTraceHelper.test.ts | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/extensions/notebook-renderers/src/stackTraceHelper.ts b/extensions/notebook-renderers/src/stackTraceHelper.ts index 3ac30abaf6b..943877ad59d 100644 --- a/extensions/notebook-renderers/src/stackTraceHelper.ts +++ b/extensions/notebook-renderers/src/stackTraceHelper.ts @@ -31,7 +31,7 @@ export function formatStackTrace(stack: string) { const formatSequence = /\u001b\[.+?m/g; const fileRegex = /File\s+(?:\u001b\[.+?m)?(.+):(\d+)/; -const lineNumberRegex = /^((?:\u001b\[.+?m)?[ ->]*?)(\d+)(.*)/; +const lineNumberRegex = /^((?:\u001b\[.+?m)?[ \->]+?)(\d+)(?:\u001b\[0m)?( .*)/; const cellRegex = /(?Cell\s+(?:\u001b\[.+?m)?In\s*\[(?\d+)\],\s*)(?line (?\d+)).*/; // older versions of IPython ~8.3.0 const inputRegex = /(?Input\s+?(?:\u001b\[.+?m)(?In\s*\[(?\d+)\]))(?.*)/; diff --git a/extensions/notebook-renderers/src/test/stackTraceHelper.test.ts b/extensions/notebook-renderers/src/test/stackTraceHelper.test.ts index da7f9d0e2e4..c4e99179086 100644 --- a/extensions/notebook-renderers/src/test/stackTraceHelper.test.ts +++ b/extensions/notebook-renderers/src/test/stackTraceHelper.test.ts @@ -43,8 +43,6 @@ suite('StackTraceHelper', () => { assert.ok(formatted.indexOf('2') > 0, 'Missing frame link in ' + formatted); }); - - test('IPython stack line numbers are linkified for IPython 8.3', () => { // stack frames within functions do not list the line number, i.e. // 'Input In [1], in myfunc()' vs @@ -93,7 +91,11 @@ suite('StackTraceHelper', () => { '\u001b[1;36m Cell \u001b[1;32mIn[6], line 1\u001b[1;36m\u001b[0m\n' + '\u001b[1;33m print(\u001b[0m\n' + '\u001b[1;37m ^\u001b[0m\n' + - '\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m incomplete input\n'; + '\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m incomplete input\n' + + // contrived examples to check for more false positives + '1 print(\n' + + 'a 1 print(\n' + + ' 1a print(\n'; const formattedLines = formatStackTrace(stack).split('\n'); assert.ok(/ Date: Mon, 6 Nov 2023 11:05:00 -0800 Subject: [PATCH 041/240] Always run code lens implementations on semantic server (#197578) Fixes #197286 Already fixed this for references code lens. Just porting it to impl code lens now too --- .../languageFeatures/codeLens/implementationsCodeLens.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts b/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts index b0346c8572b..ca71495b345 100644 --- a/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts +++ b/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts @@ -13,6 +13,7 @@ import * as typeConverters from '../../typeConverters'; import { ClientCapability, ITypeScriptServiceClient } from '../../typescriptService'; import { conditionalRegistration, requireGlobalConfiguration, requireSomeCapability } from '../util/dependentRegistration'; import { ReferencesCodeLens, TypeScriptBaseCodeLensProvider, getSymbolRange } from './baseCodeLensProvider'; +import { ExecutionTarget } from '../../tsServer/server'; export default class TypeScriptImplementationsCodeLensProvider extends TypeScriptBaseCodeLensProvider { @@ -22,7 +23,11 @@ export default class TypeScriptImplementationsCodeLensProvider extends TypeScrip token: vscode.CancellationToken, ): Promise { const args = typeConverters.Position.toFileLocationRequestArgs(codeLens.file, codeLens.range.start); - const response = await this.client.execute('implementation', args, token, { lowPriority: true, cancelOnResourceChange: codeLens.document }); + const response = await this.client.execute('implementation', args, token, { + lowPriority: true, + executionTarget: ExecutionTarget.Semantic, + cancelOnResourceChange: codeLens.document, + }); if (response.type !== 'response' || !response.body) { codeLens.command = response.type === 'cancelled' ? TypeScriptBaseCodeLensProvider.cancelledCommand From 275a1a5fbc97eb2d15af33d737dde71bccba3d39 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 6 Nov 2023 11:06:35 -0800 Subject: [PATCH 042/240] React to scroll events --- .../browser/terminal.stickyScroll.contribution.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index 3d57c6acc20..7d4ccc99b7b 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -61,6 +61,7 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi // TODO: Skip these when hidden this.add(xterm.raw.onScroll(() => this._refresh())); this.add(xterm.raw.onLineFeed(() => this._refresh())); + this.add(addStandardDisposableListener(xterm.raw.element!.querySelector('.xterm-viewport')!, 'scroll', () => this._refresh())); // TODO: Disable in alt buffer TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { @@ -94,7 +95,10 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi if (!commandDetection) { return; } - const command = commandDetection.getCommandForLine(this._xterm.raw.buffer.active.viewportY); + // The command from viewportY + 1 is used because this one will not be obscured by sticky + // scroll. + const command = commandDetection.getCommandForLine(this._xterm.raw.buffer.active.viewportY + 1); + // TODO: Expose unified interface for fetching line content const marker = command && 'commandStartMarker' in command ? command.commandStartMarker @@ -106,7 +110,6 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi } this._currentStickyMarker = marker; const element = this._ensureElement(); - // element.textContent = this._xterm.raw.buffer.active.getLine(marker.line)?.translateToString(true) ?? ''; if (element.textContent === '') { hide(element); } else { @@ -123,8 +126,6 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi }); if (s) { const content = s.substring(0, s.indexOf('\r')); - - // const content = this._xterm.raw.buffer.active.getLine(marker.line)?.translateToString(true) ?? ''; if (content) { this._stickyScrollOverlay.write(content); } From 68a051f2e2335f0ebfd1f069152e018c1d0c652b Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 6 Nov 2023 20:10:52 +0100 Subject: [PATCH 043/240] Aux window: regression: editor global stylesheet does not work (fix #197564) (#197580) --- src/vs/base/browser/dom.ts | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 59c5aad6a10..171ba15ed13 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -825,6 +825,12 @@ export function focusWindow(element: Node): void { } } +const globalStylesheets = new Map>(); + +export function isGlobalStylesheet(node: Node): boolean { + return globalStylesheets.has(node as HTMLStyleElement); +} + export function createStyleSheet(container: HTMLElement = document.head, beforeAppend?: (style: HTMLStyleElement) => void, disposableStore?: DisposableStore): HTMLStyleElement { const style = document.createElement('style'); style.type = 'text/css'; @@ -839,37 +845,33 @@ export function createStyleSheet(container: HTMLElement = document.head, beforeA // With as container, the stylesheet becomes global and is tracked // to support auxiliary windows to clone the stylesheet. if (container === document.head) { + const globalStylesheetClones = new Set(); + globalStylesheets.set(style, globalStylesheetClones); + for (const { window: targetWindow, disposables } of getWindows()) { if (targetWindow === mainWindow) { continue; // main window is already tracked } - const cloneDisposable = disposables.add(cloneGlobalStyleSheet(style, targetWindow)); + const cloneDisposable = disposables.add(cloneGlobalStyleSheet(style, globalStylesheetClones, targetWindow)); disposableStore?.add(cloneDisposable); } - } return style; } -const globalStylesheets = new Map>(); - -export function isGlobalStylesheet(node: Node): boolean { - return globalStylesheets.has(node as HTMLStyleElement); -} - export function cloneGlobalStylesheets(targetWindow: Window): IDisposable { const disposables = new DisposableStore(); - for (const [globalStylesheet] of globalStylesheets) { - disposables.add(cloneGlobalStyleSheet(globalStylesheet, targetWindow)); + for (const [globalStylesheet, clonedGlobalStylesheets] of globalStylesheets) { + disposables.add(cloneGlobalStyleSheet(globalStylesheet, clonedGlobalStylesheets, targetWindow)); } return disposables; } -function cloneGlobalStyleSheet(globalStylesheet: HTMLStyleElement, targetWindow: Window): IDisposable { +function cloneGlobalStyleSheet(globalStylesheet: HTMLStyleElement, globalStylesheetClones: Set, targetWindow: Window): IDisposable { const disposables = new DisposableStore(); const clone = globalStylesheet.cloneNode(true) as HTMLStyleElement; @@ -884,13 +886,8 @@ function cloneGlobalStyleSheet(globalStylesheet: HTMLStyleElement, targetWindow: clone.textContent = globalStylesheet.textContent; })); - let clonedGlobalStylesheets = globalStylesheets.get(globalStylesheet); - if (!clonedGlobalStylesheets) { - clonedGlobalStylesheets = new Set(); - globalStylesheets.set(globalStylesheet, clonedGlobalStylesheets); - } - clonedGlobalStylesheets.add(clone); - disposables.add(toDisposable(() => clonedGlobalStylesheets?.delete(clone))); + globalStylesheetClones.add(clone); + disposables.add(toDisposable(() => globalStylesheetClones.delete(clone))); return disposables; } From d72005bfa7aa8e30432e3ba90d718db78aca4e2a Mon Sep 17 00:00:00 2001 From: Ronak Jain Date: Tue, 7 Nov 2023 01:16:09 +0530 Subject: [PATCH 044/240] Fix tsconfig resolution for navigation (#192851) * Fix tsconfig resolution * Resolve based on link type --- .../src/languageFeatures/tsconfig.ts | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts b/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts index 398c8c10ee2..85fe3f6de5f 100644 --- a/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts +++ b/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts @@ -17,9 +17,16 @@ function mapChildren(node: jsonc.Node | undefined, f: (x: jsonc.Node) => R): } const openExtendsLinkCommandId = '_typescript.openExtendsLink'; + +enum TsConfigLinkType { + Extends, + References +} + type OpenExtendsLinkCommandArgs = { readonly resourceUri: vscode.Uri; readonly extendsValue: string; + readonly linkType: TsConfigLinkType; }; @@ -43,7 +50,7 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider { private getExtendsLink(document: vscode.TextDocument, root: jsonc.Node): vscode.DocumentLink | undefined { const node = jsonc.findNodeAtLocation(root, ['extends']); - return node && this.tryCreateTsConfigLink(document, node); + return node && this.tryCreateTsConfigLink(document, node, TsConfigLinkType.Extends); } private getReferencesLinks(document: vscode.TextDocument, root: jsonc.Node) { @@ -51,18 +58,19 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider { jsonc.findNodeAtLocation(root, ['references']), child => { const pathNode = jsonc.findNodeAtLocation(child, ['path']); - return pathNode && this.tryCreateTsConfigLink(document, pathNode); + return pathNode && this.tryCreateTsConfigLink(document, pathNode, TsConfigLinkType.References); }); } - private tryCreateTsConfigLink(document: vscode.TextDocument, node: jsonc.Node): vscode.DocumentLink | undefined { + private tryCreateTsConfigLink(document: vscode.TextDocument, node: jsonc.Node, linkType: TsConfigLinkType): vscode.DocumentLink | undefined { if (!this.isPathValue(node)) { return undefined; } const args: OpenExtendsLinkCommandArgs = { resourceUri: { ...document.uri.toJSON(), $mid: undefined }, - extendsValue: node.value + extendsValue: node.value, + linkType }; const link = new vscode.DocumentLink( @@ -148,17 +156,18 @@ async function resolveNodeModulesPath(baseDirUri: vscode.Uri, pathCandidates: st } } -// Reference: https://github.com/microsoft/TypeScript/blob/febfd442cdba343771f478cf433b0892f213ad2f/src/compiler/commandLineParser.ts#L3005 +// Reference Extends:https://github.com/microsoft/TypeScript/blob/febfd442cdba343771f478cf433b0892f213ad2f/src/compiler/commandLineParser.ts#L3005 +// Reference Project References: https://github.com/microsoft/TypeScript/blob/7377f5cb9db19d79a6167065b323a45611c812b5/src/compiler/tsbuild.ts#L188C1-L194C2 /** * @returns Returns undefined in case of lack of result while trying to resolve from node_modules */ -async function getTsconfigPath(baseDirUri: vscode.Uri, pathValue: string): Promise { +async function getTsconfigPath(baseDirUri: vscode.Uri, pathValue: string, linkType: TsConfigLinkType): Promise { async function resolve(absolutePath: vscode.Uri): Promise { if (absolutePath.path.endsWith('.json') || await exists(absolutePath)) { return absolutePath; } return absolutePath.with({ - path: `${absolutePath.path}.json` + path: `${absolutePath.path}${linkType === TsConfigLinkType.References ? '/tsconfig.json' : '.json'}` }); } @@ -194,8 +203,8 @@ export function register() { .flat(); return vscode.Disposable.from( - vscode.commands.registerCommand(openExtendsLinkCommandId, async ({ resourceUri, extendsValue, }: OpenExtendsLinkCommandArgs) => { - const tsconfigPath = await getTsconfigPath(Utils.dirname(vscode.Uri.from(resourceUri)), extendsValue); + vscode.commands.registerCommand(openExtendsLinkCommandId, async ({ resourceUri, extendsValue, linkType }: OpenExtendsLinkCommandArgs) => { + const tsconfigPath = await getTsconfigPath(Utils.dirname(vscode.Uri.from(resourceUri)), extendsValue, linkType); if (tsconfigPath === undefined) { vscode.window.showErrorMessage(vscode.l10n.t("Failed to resolve {0} as module", extendsValue)); return; From fcf7d14571af93421bc2ecd3717d0fc16b1888e8 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Mon, 6 Nov 2023 11:18:13 -0800 Subject: [PATCH 045/240] remove unnecessary disposed check --- src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts index 330094b6da0..fd9e89a6536 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts @@ -302,10 +302,6 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread }), this._languageFeaturesService.multiDocumentHighlightProvider.register(selector, { provideMultiDocumentHighlights: (model: ITextModel, position: EditorPosition, otherModels: ITextModel[], token: CancellationToken): Promise> => { - if (model.isDisposed()) { - return Promise.resolve(new Map()); - } - const word = model.getWordAtPosition({ lineNumber: position.lineNumber, column: position.column From 3cfbb33383a798e9bc83dacc2d0882b368a7b739 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 6 Nov 2023 12:49:52 -0800 Subject: [PATCH 046/240] Fix most sticky scroll bg styles --- .../lib/stylelint/vscode-known-variables.json | 2 + .../contrib/terminal/browser/terminal.ts | 2 + .../browser/xterm/markNavigationAddon.ts | 4 +- .../browser/media/stickyScroll.css | 5 +- .../terminal.stickyScroll.contribution.ts | 47 +++++++++++++++++-- 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/build/lib/stylelint/vscode-known-variables.json b/build/lib/stylelint/vscode-known-variables.json index 0baec502572..ae34cab28c3 100644 --- a/build/lib/stylelint/vscode-known-variables.json +++ b/build/lib/stylelint/vscode-known-variables.json @@ -665,6 +665,8 @@ "--vscode-terminalCursor-foreground", "--vscode-terminalOverviewRuler-cursorForeground", "--vscode-terminalOverviewRuler-findMatchForeground", + "--vscode-terminalStickyScroll-background", + "--vscode-terminalStickyScrollHover-background", "--vscode-testing-iconErrored", "--vscode-testing-iconFailed", "--vscode-testing-iconPassed", diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 797bc5612eb..df79a49bcbd 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -107,7 +107,9 @@ export interface IMarkTracker { selectToNextLine(): void; clearMarker(): void; scrollToClosestMarker(startMarkerId: string, endMarkerId?: string, highlight?: boolean | undefined): void; + scrollToLine(line: number, position: ScrollPosition): void; + registerTemporaryDecoration(marker: IMarker, endMarker?: IMarker): void; } export interface ITerminalGroup { diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts index 1d90c7a1f75..3337c4d5f37 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts @@ -194,7 +194,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe this._terminal.scrollToLine(line); } if (!hideDecoration) { - this._registerTemporaryDecoration(marker, endMarker); + this.registerTemporaryDecoration(marker, endMarker); } } @@ -211,7 +211,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe } } - private _registerTemporaryDecoration(marker: IMarker, endMarker?: IMarker): void { + registerTemporaryDecoration(marker: IMarker, endMarker?: IMarker): void { if (!this._terminal) { return; } diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css index 453350ffa28..d53717b8992 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css @@ -10,7 +10,7 @@ top: 0; z-index: 32; /* Must be higher than .xterm-viewport and decorations*/ /* TODO: Sticky scroll background key */ - background: var(--vscode-terminal-background, var(--vscode-panel-background)); + background: var(--vscode-terminalStickyScroll-background, var(--vscode-terminal-background, var(--vscode-panel-background))); box-shadow: var(--vscode-scrollbar-shadow) 0 3px 2px -2px; } @@ -22,6 +22,7 @@ /* TODO: Remove !important */ position: relative !important; pointer-events: none; + padding-bottom: 0 !important; } .terminal-sticky-scroll .hover-overlay { @@ -34,5 +35,5 @@ } .terminal-sticky-scroll .hover-overlay:hover { - background-color: var(--vscode-editorStickyScrollHover-background, #ffffff10); + background-color: var(--vscode-terminalStickyScrollHover-background, transparent); } diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index 7d4ccc99b7b..e5d18878441 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -8,18 +8,24 @@ import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serializ import type { IMarker, Terminal as RawXtermTerminal } from '@xterm/xterm'; import { importAMDNodeModule } from 'vs/amdX'; import { $, addStandardDisposableListener, append, hide, setVisibility, show } from 'vs/base/browser/dom'; +import { Color } from 'vs/base/common/color'; import { throttle } from 'vs/base/common/decorators'; import { DisposableStore } from 'vs/base/common/lifecycle'; import 'vs/css!./media/stickyScroll'; +import { localize } from 'vs/nls'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { registerColor } from 'vs/platform/theme/common/colorRegistry'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; import { ITerminalContribution, ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; +import { TERMINAL_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; let CanvasAddon: typeof CanvasAddonType; let SerializeAddon: typeof SerializeAddonType; @@ -46,6 +52,7 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi widgetManager: TerminalWidgetManager, @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IKeybindingService private readonly _keybindingService: IKeybindingService, + @IThemeService private readonly _themeService: IThemeService, ) { super(); } @@ -67,8 +74,10 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { const overlay = new ctor({ rows: 1, - cols: xterm.raw.cols + cols: xterm.raw.cols, + allowProposedApi: true }); + this._syncOptions(overlay, xterm.raw); this._stickyScrollOverlay = overlay; this._getSerializeAddonConstructor().then(addonCtor => { this._serializeAddon = new addonCtor(); @@ -145,9 +154,15 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi this.add(addStandardDisposableListener(hoverOverlay, 'click', e => { if (this._xterm && this._currentStickyMarker) { this._xterm.scrollToLine(this._currentStickyMarker.line, ScrollPosition.Middle); + this._xterm.markTracker.registerTemporaryDecoration(this._currentStickyMarker); } })); + // Instead of juggling decorations for hover styles, use the selection to indicate the + // hover state as the selection is inaccessible anyway + this.add(addStandardDisposableListener(hoverOverlay, 'mouseover', () => this._stickyScrollOverlay?.selectAll())); + this.add(addStandardDisposableListener(hoverOverlay, 'mouseleave', () => this._stickyScrollOverlay?.clearSelection())); + // TODO: Add to a container outside the xterm instance? // TODO: Remove ! this._stickyScrollOverlay!.open(this._element); @@ -160,14 +175,22 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi private _syncOptions(target: RawXtermTerminal, copyFrom: RawXtermTerminal): void { const o = copyFrom.options; + const theme = this._themeService.getColorTheme(); + // TODO: BG should be editor-aware + const terminalBackground = theme.getColor(terminalStickyScrollBackground) || theme.getColor(TERMINAL_BACKGROUND_COLOR) || theme.getColor(PANEL_BACKGROUND); target.resize(copyFrom.cols, 1); target.options = { - // TODO: Support in xterm.js? - // cursorStyle: 'none' cursorInactiveStyle: 'none', scrollback: 0, logLevel: 'off', - theme: this._xterm!.getXtermTheme(), + + // Selection is used for hover state in the overlay + theme: { + ...this._xterm!.getXtermTheme(), + background: terminalBackground?.toString(), + selectionBackground: theme.getColor(terminalStickyScrollHoverBackground)?.toString(), + selectionInactiveBackground: undefined + }, documentOverride: o.documentOverride, fontFamily: o.fontFamily, @@ -202,3 +225,19 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi } registerTerminalContribution(TerminalStickyScrollContribution.ID, TerminalStickyScrollContribution, true); + +// HACK: These are derived from the editor background, not the terminal background because +const terminalStickyScrollBackground = registerColor('terminalStickyScroll.background', { + light: null, + dark: null, + hcDark: null, + hcLight: null +}, localize('terminalStickyScroll.background', 'The background color of the sticky scroll overlay in the terminal.')); + +// TODO: These default values are from the editorStickyScrollHover.background and may not be ideal +const terminalStickyScrollHoverBackground = registerColor('terminalStickyScrollHover.background', { + dark: '#2A2D2E', + light: '#F0F0F0', + hcDark: null, + hcLight: Color.fromHex('#0F4A85').transparent(0.1) +}, localize('terminalStickyScrollHover.background', 'The background color of the sticky scroll overlay in the terminal when hovered.')); From fc6e61a5a76d5e779302576cdbd994bc19ab4e3f Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 13:44:03 -0800 Subject: [PATCH 047/240] revert isWindowsPty --- .../terminal/common/capabilities/capabilities.ts | 1 - .../common/capabilities/commandDetectionCapability.ts | 4 ---- .../browser/terminal.accessibility.contribution.ts | 10 +--------- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/vs/platform/terminal/common/capabilities/capabilities.ts b/src/vs/platform/terminal/common/capabilities/capabilities.ts index 4c45d7a81ca..a4b9fd95642 100644 --- a/src/vs/platform/terminal/common/capabilities/capabilities.ts +++ b/src/vs/platform/terminal/common/capabilities/capabilities.ts @@ -167,7 +167,6 @@ export interface ICommandDetectionCapability { readonly executingCommandObject: ITerminalCommand | undefined; /** The current cwd at the cursor's position. */ readonly cwd: string | undefined; - get isWindowsPty(): boolean; /** * Whether a command is currently being input. If the a command is current not being input or * the state cannot reliably be detected the fallback of undefined will be used. diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index 9ebac86a310..968e339f1ac 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -532,10 +532,6 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe this._onCommandExecuted.fire(); } - get isWindowsPty(): boolean { - return this._isWindowsPty; - } - private async _handleCommandExecutedWindows(): Promise { await this._commandStartedWindowsBarrier?.wait(); // On Windows, use the gathered cursor move markers to correct the command start and diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index e6596557ab0..03cb1ed1ec1 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -138,19 +138,11 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT } const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection)!; - this._onDidRunCommand.value = this._register(capability.onCommandExecuted(() => { + this._onDidRunCommand.value = this._register(Event.any(capability.onCommandExecuted, capability.onPreCommandFinishedWindows)(() => { if (this._instance.hasFocus) { this.show(); } })); - if (capability.isWindowsPty) { - // It's possible command executed never happens (for example, if PSReadLine is disabled) - this._onDidPreCommandFinishWindows.value = this._register(capability.onPreCommandFinishedWindows(() => { - if (this._instance.hasFocus) { - this.show(); - } - })); - } } private _isTerminalAccessibleViewOpen(): boolean { From cf5656a4c60478b1217674e857abf2979130b5eb Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 6 Nov 2023 14:09:48 -0800 Subject: [PATCH 048/240] Hide sticky scroll in some cases --- .../capabilities/commandDetectionCapability.ts | 11 +++++++++++ .../stickyScroll/browser/media/stickyScroll.css | 3 +-- .../terminal.stickyScroll.contribution.ts | 16 ++++++++++++---- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index f9df0fa31d4..3dfa5449188 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -292,6 +292,17 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe if (this._currentCommand.promptStartMarker && line >= this._currentCommand.promptStartMarker?.line) { return this._currentCommand; } + + // No commands + if (this._commands.length === 0) { + return undefined; + } + + // Line is before any registered commands + if (this._commands[0].marker!.line > line) { + return undefined; + } + // TODO: It would be more reliable to take the closest cwd above the line if it isn't found for the line // TODO: Use a reverse for loop to find the line to avoid creating another array const reversed = [...this._commands].reverse(); diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css index d53717b8992..cd2c7a079a6 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css @@ -8,8 +8,7 @@ left: 0; right: 0; top: 0; - z-index: 32; /* Must be higher than .xterm-viewport and decorations*/ - /* TODO: Sticky scroll background key */ + z-index: 32; /* Must be higher than .xterm-viewport and decorations */ background: var(--vscode-terminalStickyScroll-background, var(--vscode-terminal-background, var(--vscode-panel-background))); box-shadow: var(--vscode-scrollbar-shadow) 0 3px 2px -2px; } diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index e5d18878441..e5f5c9c6944 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -69,7 +69,6 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi this.add(xterm.raw.onScroll(() => this._refresh())); this.add(xterm.raw.onLineFeed(() => this._refresh())); this.add(addStandardDisposableListener(xterm.raw.element!.querySelector('.xterm-viewport')!, 'scroll', () => this._refresh())); - // TODO: Disable in alt buffer TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { const overlay = new ctor({ @@ -107,6 +106,7 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi // The command from viewportY + 1 is used because this one will not be obscured by sticky // scroll. const command = commandDetection.getCommandForLine(this._xterm.raw.buffer.active.viewportY + 1); + const element = this._ensureElement(); // TODO: Expose unified interface for fetching line content const marker = command && 'commandStartMarker' in command @@ -114,11 +114,20 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi : command && 'marker' in command ? command.marker : undefined; + + // Hide if the marker doesn't exist or has been trimmed from the scrollback if (!marker || marker.line === -1) { + hide(element); return; } + + // Hide sticky scroll if it's on the same line + if (marker.line === this._xterm.raw.buffer.active.viewportY) { + hide(element); + return; + } + this._currentStickyMarker = marker; - const element = this._ensureElement(); if (element.textContent === '') { hide(element); } else { @@ -128,8 +137,7 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi if (this._stickyScrollOverlay) { this._stickyScrollOverlay.write('\x1b[H\x1b[K'); - // TODO: Serialize line instead - // TODO: Support providing single line/range serialize addon + // TODO: Serializing all content up to the required line is inefficient; support providing single line/range serialize addon const s = this._serializeAddon?.serialize({ scrollback: this._xterm.raw.buffer.active.baseY - marker.line }); From ff44f704033728f4fe0a8687086d933356a1aee3 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 14:11:09 -0800 Subject: [PATCH 049/240] fake fire command executed --- .vscode/settings.json | 2 +- src/vs/platform/terminal/common/capabilities/capabilities.ts | 1 - .../common/capabilities/commandDetectionCapability.ts | 4 +--- .../browser/terminal.accessibility.contribution.ts | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 98bd618b14f..edef8261dfa 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -112,7 +112,7 @@ }, "[typescript]": { "editor.defaultFormatter": "vscode.typescript-language-features", - "editor.formatOnSave": true + "editor.formatOnSave": true, }, "[javascript]": { "editor.defaultFormatter": "vscode.typescript-language-features", diff --git a/src/vs/platform/terminal/common/capabilities/capabilities.ts b/src/vs/platform/terminal/common/capabilities/capabilities.ts index a4b9fd95642..3c3bec8dd6d 100644 --- a/src/vs/platform/terminal/common/capabilities/capabilities.ts +++ b/src/vs/platform/terminal/common/capabilities/capabilities.ts @@ -175,7 +175,6 @@ export interface ICommandDetectionCapability { readonly currentCommand: ICurrentPartialCommand | undefined; readonly onCommandStarted: Event; readonly onCommandFinished: Event; - readonly onPreCommandFinishedWindows: Event; readonly onCommandExecuted: Event; readonly onCommandInvalidated: Event; readonly onCurrentCommandInvalidated: Event; diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index 968e339f1ac..83815a160fd 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -109,8 +109,6 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe readonly onBeforeCommandFinished = this._onBeforeCommandFinished.event; private readonly _onCommandFinished = this._register(new Emitter()); readonly onCommandFinished = this._onCommandFinished.event; - private readonly _onPreCommandFinishedWindows = this._register(new Emitter()); - readonly onPreCommandFinishedWindows = this._onPreCommandFinishedWindows.event; private readonly _onCommandExecuted = this._register(new Emitter()); readonly onCommandExecuted = this._onCommandExecuted.event; private readonly _onCommandInvalidated = this._register(new Emitter()); @@ -623,7 +621,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe if (this._currentCommand.commandStartMarker) { this._commandMarkers.push(this._currentCommand.commandStartMarker); } - this._onPreCommandFinishedWindows.fire(); + this._onCommandExecuted.fire(); } this._evaluateCommandMarkersWindows(); } diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index 03cb1ed1ec1..8d99f5e044d 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -138,7 +138,7 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT } const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection)!; - this._onDidRunCommand.value = this._register(Event.any(capability.onCommandExecuted, capability.onPreCommandFinishedWindows)(() => { + this._onDidRunCommand.value = this._register(capability.onCommandExecuted(() => { if (this._instance.hasFocus) { this.show(); } From db362a174d602a7fc11926a7cc09f2df109661c6 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Mon, 6 Nov 2023 14:11:53 -0800 Subject: [PATCH 050/240] Update .vscode/settings.json --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index edef8261dfa..98bd618b14f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -112,7 +112,7 @@ }, "[typescript]": { "editor.defaultFormatter": "vscode.typescript-language-features", - "editor.formatOnSave": true, + "editor.formatOnSave": true }, "[javascript]": { "editor.defaultFormatter": "vscode.typescript-language-features", From 56f2a042c6266938b91f80e05ee076f150270c66 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 14:13:01 -0800 Subject: [PATCH 051/240] revert change --- .../browser/terminal.accessibility.contribution.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index 8d99f5e044d..9cd1cb1446d 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -67,7 +67,6 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT private _bufferProvider: TerminalAccessibleBufferProvider | undefined; private _xterm: Pick & { raw: Terminal } | undefined; private _onDidRunCommand: MutableDisposable = new MutableDisposable(); - private _onDidPreCommandFinishWindows: MutableDisposable = new MutableDisposable(); constructor( private readonly _instance: ITerminalInstance, @@ -131,7 +130,6 @@ export class TerminalAccessibleViewContribution extends Disposable implements IT } if (!this._configurationService.getValue(TerminalSettingId.AccessibleViewFocusOnCommandExecution)) { this._onDidRunCommand.clear(); - this._onDidPreCommandFinishWindows.clear(); return; } else if (this._onDidRunCommand.value) { return; From bc36e07d8a8f66069bee3d632c5556200236ae36 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 6 Nov 2023 14:33:22 -0800 Subject: [PATCH 052/240] add comment --- .../terminal/common/capabilities/commandDetectionCapability.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index 83815a160fd..3cac93659ff 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -621,6 +621,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe if (this._currentCommand.commandStartMarker) { this._commandMarkers.push(this._currentCommand.commandStartMarker); } + // Fire this now to prevent issues like #197409 this._onCommandExecuted.fire(); } this._evaluateCommandMarkersWindows(); From 83d2372a98edde81c901b278b131a1342bab7b72 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 6 Nov 2023 16:20:34 -0700 Subject: [PATCH 053/240] Sort chat variables to below slash commands (#197596) Fix microsoft/vscode-copilot#2495 --- .../contrib/chat/browser/contrib/chatInputEditorContrib.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts index 6db8aa47a21..5d7a0f6b205 100644 --- a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts +++ b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts @@ -550,6 +550,7 @@ class BuiltinDynamicCompletions extends Disposable { range: { insert, replace }, kind: CompletionItemKind.Text, command: { id: SelectAndInsertFileAction.ID, title: SelectAndInsertFileAction.ID, arguments: [{ widget, range }] }, + sortText: 'z' } ] }; @@ -701,7 +702,8 @@ class VariableCompletions extends Disposable { range, insertText: withLeader + ' ', detail: v.description, - kind: CompletionItemKind.Text, // The icons are disabled here anyway, + kind: CompletionItemKind.Text, // The icons are disabled here anyway + sortText: 'z' }; }); From 8e8d183e181f8a10dcf626a4dc1062e754bd5997 Mon Sep 17 00:00:00 2001 From: Cody Beyer Date: Mon, 6 Nov 2023 16:49:36 -0800 Subject: [PATCH 054/240] adding azure open-ai package for js --- .../contrib/tags/electron-sandbox/workspaceTagsService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts index a3dc8939bb8..a73223fd549 100644 --- a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts +++ b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts @@ -170,7 +170,8 @@ const ModulesToLookFor = [ '@azure/web-pubsub', '@azure/web-pubsub-client', '@azure/web-pubsub-client-protobuf', - '@azure/web-pubsub-express' + '@azure/web-pubsub-express', + '@azure/openai' ]; const PyMetaModulesToLookFor = [ @@ -522,6 +523,7 @@ export class WorkspaceTagsService implements IWorkspaceTagsService { "workspace.npm.@azure/web-pubsub-client" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.npm.@azure/web-pubsub-client-protobuf" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.npm.@azure/web-pubsub-express" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workspace.npm.@azure/openai" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.npm.react-native-macos" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.npm.react-native-windows" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, "workspace.bower" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, From d576523abbbfb384f8235f0f58e4c9c165cde686 Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Tue, 7 Nov 2023 10:44:51 +0100 Subject: [PATCH 055/240] Updated Editor Actions Location Settings and UI Changes (#197547) * Updated editor actions location settings and related UI changes * ShowEditorActions --- src/vs/platform/actions/common/actions.ts | 1 + .../browser/actions/layoutActions.ts | 119 ++++++++++++++++++ .../parts/editor/editor.contribution.ts | 8 +- .../workbench/browser/parts/editor/editor.ts | 4 +- .../browser/parts/editor/editorTabsControl.ts | 66 ++++++++-- .../editor/media/multieditortabscontrol.css | 4 + .../editor/media/singleeditortabscontrol.css | 5 + .../parts/editor/multiEditorTabsControl.ts | 12 +- .../parts/editor/singleEditorTabsControl.ts | 9 +- .../browser/parts/titlebar/titlebarPart.ts | 20 ++- .../browser/workbench.contribution.ts | 13 +- src/vs/workbench/common/editor.ts | 2 +- 12 files changed, 219 insertions(+), 44 deletions(-) diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index d917d2f9a38..a34f8e71e2c 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -70,6 +70,7 @@ export class MenuId { static readonly EmptyEditorGroupContext = new MenuId('EmptyEditorGroupContext'); static readonly EditorTabsBarContext = new MenuId('EditorTabsBarContext'); static readonly EditorTabsBarShowTabsSubmenu = new MenuId('EditorTabsBarShowTabsSubmenu'); + static readonly EditorActionsPositionSubmenu = new MenuId('EditorActionsPositionSubmenu'); static readonly ExplorerContext = new MenuId('ExplorerContext'); static readonly ExplorerContextShare = new MenuId('ExplorerContextShare'); static readonly ExtensionContext = new MenuId('ExtensionContext'); diff --git a/src/vs/workbench/browser/actions/layoutActions.ts b/src/vs/workbench/browser/actions/layoutActions.ts index 76f90e4cda5..d877dea64d6 100644 --- a/src/vs/workbench/browser/actions/layoutActions.ts +++ b/src/vs/workbench/browser/actions/layoutActions.ts @@ -534,6 +534,125 @@ MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, { order: 10 }); +// --- Show Editor Actions in Title Bar + +export class EditorActionsTitleBarAction extends Action2 { + + static readonly ID = 'workbench.action.editorActionsTitleBar'; + + constructor() { + super({ + id: EditorActionsTitleBarAction.ID, + title: { + value: localize('moveEditorActionsToTitleBar', "Move Editor Actions to Title Bar"), + original: 'Move Editor Actions to Title Bar' + }, + category: Categories.View, + precondition: ContextKeyExpr.and( + ContextKeyExpr.equals('config.workbench.editor.editorActionsLocation', 'titleBar').negate(), + ContextKeyExpr.equals('config.window.style', 'native').negate(), + ), + f1: true + }); + } + + run(accessor: ServicesAccessor): Promise { + const configurationService = accessor.get(IConfigurationService); + return configurationService.updateValue('workbench.editor.editorActionsLocation', 'titleBar'); + } +} +registerAction2(EditorActionsTitleBarAction); + +// --- Editor Actions Default Position + +export class EditorActionsDefaultAction extends Action2 { + + static readonly ID = 'workbench.action.editorActionsDefault'; + + constructor() { + super({ + id: EditorActionsDefaultAction.ID, + title: { + value: localize('moveEditorActionsToTabBar', "Move Editor Actions to Tab Bar"), + original: 'Move Editor Actions to Tab Bar' + }, + category: Categories.View, + precondition: ContextKeyExpr.and( + ContextKeyExpr.equals('config.workbench.editor.editorActionsLocation', 'default').negate(), + ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none').negate(), + ), + f1: true + }); + } + + run(accessor: ServicesAccessor): Promise { + const configurationService = accessor.get(IConfigurationService); + return configurationService.updateValue('workbench.editor.editorActionsLocation', 'default'); + } +} +registerAction2(EditorActionsDefaultAction); + +// --- Hide Editor Actions + +export class HideEditorActionsAction extends Action2 { + + static readonly ID = 'workbench.action.hideEditorActions'; + + constructor() { + super({ + id: HideEditorActionsAction.ID, + title: { + value: localize('hideEditorActons', "Hide Editor Actions"), + original: 'Hide Editor Actions' + }, + category: Categories.View, + precondition: ContextKeyExpr.equals('config.workbench.editor.editorActionsLocation', 'hidden').negate(), + f1: true + }); + } + + run(accessor: ServicesAccessor): Promise { + const configurationService = accessor.get(IConfigurationService); + return configurationService.updateValue('workbench.editor.editorActionsLocation', 'hidden'); + } +} +registerAction2(HideEditorActionsAction); + +// --- Hide Editor Actions + +export class ShowEditorActionsAction extends Action2 { + + static readonly ID = 'workbench.action.showEditorActions'; + + constructor() { + super({ + id: ShowEditorActionsAction.ID, + title: { + value: localize('showEditorActons', "Show Editor Actions"), + original: 'Show Editor Actions' + }, + category: Categories.View, + precondition: ContextKeyExpr.equals('config.workbench.editor.editorActionsLocation', 'hidden'), + f1: true + }); + } + + run(accessor: ServicesAccessor): Promise { + const configurationService = accessor.get(IConfigurationService); + return configurationService.updateValue('workbench.editor.editorActionsLocation', 'default'); + } +} +registerAction2(ShowEditorActionsAction); + +// --- Editor Actions Position Submenu in View Appearance Menu + +MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, { + submenu: MenuId.EditorActionsPositionSubmenu, + title: localize('editorActionsPosition', "Editor Actions Position"), + group: '3_workbench_layout_move', + order: 11 +}); + // --- Toggle Pinned Tabs On Separate Row registerAction2(class extends Action2 { diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 8ebad36c34b..52bc1cf3f38 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -65,7 +65,7 @@ import { Codicon } from 'vs/base/common/codicons'; import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; import { UntitledTextEditorInputSerializer, UntitledTextEditorWorkingCopyEditorHandler } from 'vs/workbench/services/untitled/common/untitledTextEditorHandler'; import { DynamicEditorConfigurations } from 'vs/workbench/browser/parts/editor/editorConfiguration'; -import { HideEditorTabsAction, ShowMultipleEditorTabsAction, ShowSingleEditorTabAction } from 'vs/workbench/browser/actions/layoutActions'; +import { EditorActionsDefaultAction, EditorActionsTitleBarAction, HideEditorActionsAction, HideEditorTabsAction, ShowMultipleEditorTabsAction, ShowSingleEditorTabAction } from 'vs/workbench/browser/actions/layoutActions'; import product from 'vs/platform/product/common/product'; import { ICommandAction } from 'vs/platform/action/common/action'; @@ -357,11 +357,17 @@ MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_ MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_DOWN, title: localize('splitDown', "Split Down") }, group: '2_split', order: 20 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_LEFT, title: localize('splitLeft', "Split Left") }, group: '2_split', order: 30 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_RIGHT, title: localize('splitRight', "Split Right") }, group: '2_split', order: 40 }); + MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { submenu: MenuId.EditorTabsBarShowTabsSubmenu, title: localize('tabBar', "Tab Bar"), group: '3_config', order: 10 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarShowTabsSubmenu, { command: { id: ShowMultipleEditorTabsAction.ID, title: localize('multipleTabs', "Multiple Tabs"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple') }, group: '1_config', order: 10 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarShowTabsSubmenu, { command: { id: ShowSingleEditorTabAction.ID, title: localize('singleTab', "Single Tab"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'single') }, group: '1_config', order: 20 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarShowTabsSubmenu, { command: { id: HideEditorTabsAction.ID, title: localize('hideTabBar', "Hide"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none') }, group: '1_config', order: 30 }); +MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { submenu: MenuId.EditorActionsPositionSubmenu, title: localize('editorActionsPosition', "Editor Actions Position"), group: '3_config', order: 20 }); +MenuRegistry.appendMenuItem(MenuId.EditorActionsPositionSubmenu, { command: { id: EditorActionsDefaultAction.ID, title: localize('tabBar', "Tab Bar"), toggled: ContextKeyExpr.equals('config.workbench.editor.editorActionsLocation', 'default') }, group: '1_config', order: 10, when: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none').negate() }); +MenuRegistry.appendMenuItem(MenuId.EditorActionsPositionSubmenu, { command: { id: EditorActionsTitleBarAction.ID, title: localize('titleBar', "Title Bar"), toggled: ContextKeyExpr.or(ContextKeyExpr.equals('config.workbench.editor.editorActionsLocation', 'titleBar'), ContextKeyExpr.and(ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none'), ContextKeyExpr.equals('config.workbench.editor.editorActionsLocation', 'default'))) }, group: '1_config', order: 20, when: ContextKeyExpr.equals('config.window.titleBarStyle', 'native').negate() }); +MenuRegistry.appendMenuItem(MenuId.EditorActionsPositionSubmenu, { command: { id: HideEditorActionsAction.ID, title: localize('hidden', "Hidden"), toggled: ContextKeyExpr.or(ContextKeyExpr.equals('config.workbench.editor.editorActionsLocation', 'hidden'), ContextKeyExpr.and(ContextKeyExpr.equals('config.window.titleBarStyle', 'native'), ContextKeyExpr.equals('config.workbench.editor.editorActionsLocation', 'titleBar'))) }, group: '1_config', order: 30 }); + // Editor Title Context Menu MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: CLOSE_EDITOR_COMMAND_ID, title: localize('close', "Close") }, group: '1_close', order: 10 }); MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID, title: localize('closeOthers', "Close Others"), precondition: EditorGroupEditorsCountContext.notEqualsTo('1') }, group: '1_close', order: 20 }); diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 0c35bafff59..70b57dbdd41 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -51,7 +51,7 @@ export const DEFAULT_EDITOR_PART_OPTIONS: IEditorPartOptions = { splitOnDragAndDrop: true, centeredLayoutFixedWidth: false, doubleClickTabToToggleEditorGroupSizes: 'expand', - showEditorActionsInTitleBar: 'noTabs', + editorActionsLocation: 'default', wrapTabs: false, enablePreviewFromQuickOpen: false, scrollToSwitchTabs: false, @@ -150,7 +150,7 @@ function validateEditorPartOptions(options: IEditorPartOptions): IEditorPartOpti 'splitInGroupLayout': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['splitInGroupLayout'], ['vertical', 'horizontal']), 'splitSizing': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['splitSizing'], ['distribute', 'split', 'auto']), 'doubleClickTabToToggleEditorGroupSizes': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['doubleClickTabToToggleEditorGroupSizes'], ['maximize', 'expand', 'off']), - 'showEditorActionsInTitleBar': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['showEditorActionsInTitleBar'], ['noTabs', 'never']), + 'editorActionsLocation': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['editorActionsLocation'], ['default', 'titleBar', 'hidden']), 'autoLockGroups': new SetVerifier(DEFAULT_EDITOR_PART_OPTIONS['autoLockGroups']), 'limit': new ObjectVerifier(DEFAULT_EDITOR_PART_OPTIONS['limit'], { diff --git a/src/vs/workbench/browser/parts/editor/editorTabsControl.ts b/src/vs/workbench/browser/parts/editor/editorTabsControl.ts index 362707e380c..6f9a241d4b3 100644 --- a/src/vs/workbench/browser/parts/editor/editorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/editorTabsControl.ts @@ -96,8 +96,10 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC compact: 22 as const }; + protected editorActionsToolbarContainer: HTMLElement | undefined; private editorActionsToolbar: WorkbenchToolBar | undefined; - private editorActionsDisposables = this._register(new DisposableStore()); + private readonly editorActionsToolbarDisposables = this._register(new DisposableStore()); + private readonly editorActionsDisposables = this._register(new DisposableStore()); private resourceContext: ResourceContextKey; @@ -153,17 +155,47 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC this.updateTabHeight(); } - protected createEditorActionsToolBar(container: HTMLElement): void { + private get editorActionsEnabled(): boolean { + return this.groupsView.partOptions.editorActionsLocation === 'default' && this.groupsView.partOptions.showTabs !== 'none'; + } + + protected createEditorActionsToolBar(parent: HTMLElement, classes: string[]): void { + this.editorActionsToolbarContainer = document.createElement('div'); + this.editorActionsToolbarContainer.classList.add(...classes); + parent.appendChild(this.editorActionsToolbarContainer); + + this.handleEditorActionToolBarVisibility(this.editorActionsToolbarContainer); + } + + private handleEditorActionToolBarVisibility(container: HTMLElement): void { + const editorActionsEnabled = this.editorActionsEnabled; + const editorActionsVisible = !!this.editorActionsToolbar; + + // Create toolbar if it is enabled (and not yet created) + if (editorActionsEnabled && !editorActionsVisible) { + this.doCreateEditorActionsToolBar(container); + } + // Remove toolbar if it is not enabled (and is visible) + else if (!editorActionsEnabled && editorActionsVisible) { + this.editorActionsToolbar?.getElement().remove(); + this.editorActionsToolbar = undefined; + this.editorActionsToolbarDisposables.clear(); + this.editorActionsDisposables.clear(); + } + + container.classList.toggle('hidden', !editorActionsEnabled); + } + + private doCreateEditorActionsToolBar(container: HTMLElement): void { const context: IEditorCommandsContext = { groupId: this.groupView.id }; // Toolbar Widget - - this.editorActionsToolbar = this._register(this.instantiationService.createInstance(WorkbenchToolBar, container, { + this.editorActionsToolbar = this.editorActionsToolbarDisposables.add(this.instantiationService.createInstance(WorkbenchToolBar, container, { actionViewItemProvider: action => this.actionViewItemProvider(action), orientation: ActionsOrientation.HORIZONTAL, ariaLabel: localize('ariaLabelEditorActions', "Editor actions"), getKeyBinding: action => this.getKeybinding(action), - actionRunner: this._register(new EditorCommandsContextActionRunner(context)), + actionRunner: this.editorActionsToolbarDisposables.add(new EditorCommandsContextActionRunner(context)), anchorAlignmentProvider: () => AnchorAlignment.RIGHT, renderDropdownAsChildElement: this.renderDropdownAsChildElement, telemetrySource: 'editorPart', @@ -176,7 +208,7 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC this.editorActionsToolbar.context = context; // Action Run Handling - this._register(this.editorActionsToolbar.actionRunner.onDidRun(e => { + this.editorActionsToolbarDisposables.add(this.editorActionsToolbar.actionRunner.onDidRun(e => { // Notify for Error if (e.error && !isCancellationError(e.error)) { @@ -202,6 +234,10 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC } protected updateEditorActionsToolbar(): void { + if (!this.editorActionsEnabled) { + return; + } + this.editorActionsDisposables.clear(); const editorActions = this.groupView.createEditorActions(this.editorActionsDisposables); @@ -218,7 +254,12 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC } protected clearEditorActionsToolbar(): void { - this.editorActionsToolbar?.setActions([], []); + if (!this.editorActionsEnabled) { + return; + } + + const editorActionsToolbar = assertIsDefined(this.editorActionsToolbar); + editorActionsToolbar.setActions([], []); } protected enableGroupDragging(element: HTMLElement): void { @@ -359,6 +400,17 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC if (oldOptions.tabHeight !== newOptions.tabHeight) { this.updateTabHeight(); } + + // Update Editor Actions Toolbar + if ( + oldOptions.editorActionsLocation !== newOptions.editorActionsLocation || + oldOptions.showTabs !== newOptions.showTabs + ) { + if (this.editorActionsToolbarContainer) { + this.handleEditorActionToolBarVisibility(this.editorActionsToolbarContainer); + this.updateEditorActionsToolbar(); + } + } } abstract openEditor(editor: EditorInput): boolean; diff --git a/src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css b/src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css index 774237775de..f675a11075d 100644 --- a/src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css @@ -445,6 +445,10 @@ height: var(--editor-group-tab-height); } +.monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions.hidden { + display: none; +} + .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-item { margin-right: 4px; } diff --git a/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css b/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css index f3a7d7b2484..d48bcc90491 100644 --- a/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css @@ -97,6 +97,11 @@ height: var(--editor-group-tab-height); } +.monaco-workbench .part.editor > .content .editor-group-container > .title > .title-actions.hidden { + display: none; +} + + .monaco-workbench .part.editor > .content .editor-group-container > .title > .title-actions .action-item { margin-right: 4px; } diff --git a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts index 9ed758b674a..7b779017488 100644 --- a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts @@ -106,7 +106,6 @@ export class MultiEditorTabsControl extends EditorTabsControl { private titleContainer: HTMLElement | undefined; private tabsAndActionsContainer: HTMLElement | undefined; private tabsContainer: HTMLElement | undefined; - private editorToolbarContainer: HTMLElement | undefined; private tabsScrollbar: ScrollableElement | undefined; private tabSizingFixedDisposables: DisposableStore | undefined; @@ -191,13 +190,8 @@ export class MultiEditorTabsControl extends EditorTabsControl { // Tabs Container listeners this.registerTabsContainerListeners(this.tabsContainer, this.tabsScrollbar); - // Editor Toolbar Container - this.editorToolbarContainer = document.createElement('div'); - this.editorToolbarContainer.classList.add('editor-actions'); - this.tabsAndActionsContainer.appendChild(this.editorToolbarContainer); - - // Editor Actions Toolbar - this.createEditorActionsToolBar(this.editorToolbarContainer); + // Create Editor Toolbar + this.createEditorActionsToolBar(this.tabsAndActionsContainer, ['editor-actions']); // Set tabs control visibility this.updateTabsControlVisibility(); @@ -1683,7 +1677,7 @@ export class MultiEditorTabsControl extends EditorTabsControl { } private doLayoutTabsWrapping(dimensions: IEditorTitleControlDimensions): boolean { - const [tabsAndActionsContainer, tabsContainer, editorToolbarContainer, tabsScrollbar] = assertAllDefined(this.tabsAndActionsContainer, this.tabsContainer, this.editorToolbarContainer, this.tabsScrollbar); + const [tabsAndActionsContainer, tabsContainer, editorToolbarContainer, tabsScrollbar] = assertAllDefined(this.tabsAndActionsContainer, this.tabsContainer, this.editorActionsToolbarContainer, this.tabsScrollbar); // Handle wrapping tabs according to setting: // - enabled: only add class if tabs wrap and don't exceed available dimensions diff --git a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts index 03c24053b3e..766845687d1 100644 --- a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts @@ -66,13 +66,8 @@ export class SingleEditorTabsControl extends EditorTabsControl { titleContainer.classList.toggle('breadcrumbs', Boolean(this.breadcrumbsControl)); this._register(toDisposable(() => titleContainer.classList.remove('breadcrumbs'))); // important to remove because the container is a shared dom node - // Right Actions Container - const actionsContainer = document.createElement('div'); - actionsContainer.classList.add('title-actions'); - titleContainer.appendChild(actionsContainer); - - // Editor actions toolbar - this.createEditorActionsToolBar(actionsContainer); + // Create editor actions toolbar + this.createEditorActionsToolBar(titleContainer, ['title-actions']); } private registerContainerListeners(titleContainer: HTMLElement): void { diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 57fd944883f..5f438a51972 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -27,7 +27,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { Parts, IWorkbenchLayoutService, ActivityBarPosition, LayoutSettings } from 'vs/workbench/services/layout/browser/layoutService'; import { createActionViewItem, createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { Action2, IMenu, IMenuService, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; -import { ContextKeyExpr, ContextKeyExpression, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { Codicon } from 'vs/base/common/codicons'; import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry'; @@ -187,7 +187,7 @@ export class TitlebarPart extends Part implements ITitleService { } if (this.titleBarStyle !== 'native' && this.actionToolBar) { - const affectsEditorActions = event.affectsConfiguration('workbench.editor.showEditorActionsInTitleBar') || event.affectsConfiguration('workbench.editor.showTabs'); + const affectsEditorActions = event.affectsConfiguration('workbench.editor.editorActionsLocation') || event.affectsConfiguration('workbench.editor.showTabs'); const affectsLayoutControl = event.affectsConfiguration('workbench.layoutControl.enabled'); const affectsActivityControl = event.affectsConfiguration(LayoutSettings.ACTIVITY_BAR_LOCATION); if (affectsEditorActions) { @@ -553,7 +553,11 @@ export class TitlebarPart extends Part implements ITitleService { } private get editorActionsEnabled(): boolean { - return this.editorGroupService.partOptions.showEditorActionsInTitleBar !== 'never' && this.editorGroupService.partOptions.showTabs === 'none'; + return this.editorGroupService.partOptions.editorActionsLocation === 'titleBar' || + ( + this.editorGroupService.partOptions.editorActionsLocation === 'default' && + this.editorGroupService.partOptions.showTabs === 'none' + ); } private get activityActionsEnabled(): boolean { @@ -604,12 +608,12 @@ export class TitlebarPart extends Part implements ITitleService { class ToogleConfigAction extends Action2 { - constructor(private readonly section: string, title: string, order: number, when?: ContextKeyExpression) { + constructor(private readonly section: string, title: string, order: number) { super({ id: `toggle.${section}`, title, toggled: ContextKeyExpr.equals(`config.${section}`, true), - menu: { id: MenuId.TitleBarContext, order, when } + menu: { id: MenuId.TitleBarContext, order } }); } @@ -632,12 +636,6 @@ registerAction2(class ToogleLayoutControl extends ToogleConfigAction { } }); -registerAction2(class ToogleEditorActionsControl extends ToogleConfigAction { - constructor() { - super('workbench.editor.showEditorActionsInTitleBar', localize('toggle.editorActions', 'Editor Actions'), 2, ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none')); - } -}); - const ACCOUNTS_ACTIVITY_TILE_ACTION: IAction = { id: ACCOUNTS_ACTIVITY_ID, label: localize('accounts', "Accounts"), diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 1c16044a043..e39f9c35dd1 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -49,15 +49,16 @@ const registry = Registry.as(ConfigurationExtensions.Con 'description': localize('showEditorTabs', "Controls whether opened editors should show as individual tabs, one single large tab or if the title area should not be shown."), 'default': 'multiple' }, - 'workbench.editor.showEditorActionsInTitleBar': { + 'workbench.editor.editorActionsLocation': { 'type': 'string', - 'enum': ['noTabs', 'never'], + 'enum': ['default', 'titleBar', 'hidden'], 'enumDescriptions': [ - localize('workbench.editor.showEditorActionsInTitleBar.noTabs', "Show editor actions in the editor title bar only when `#workbench.editor.showTabs#` is set to `none`. Otherwise, editor actions show up in the tab bar."), - localize('workbench.editor.showEditorActionsInTitleBar.never', "Do not show editor actions in the editor title bar"), + localize('workbench.editor.editorActionsLocation.default', "Show editor actions in the window title bar when `#workbench.editor.showTabs#` is set to `none`. Otherwise, editor actions are shown in the editor tab bar."), + localize('workbench.editor.editorActionsLocation.titleBar', "Show editor actions in the window title bar. If `#window.titleBarStyle#` is set to `native`, editor actions are hidden."), + localize('workbench.editor.editorActionsLocation.hidden', "Editor actions are not shown."), ], - 'markdownDescription': localize('showEditorActionsInTitleBar', "Controls whether editor actions are shown in the title bar. This value only applies when `#window.titleBarStyle#` is set to `custom`."), - 'default': 'noTabs' + 'markdownDescription': localize('editorActionsLocation', "Controls where the editor actions are shown."), + 'default': 'default' }, 'workbench.editor.wrapTabs': { 'type': 'boolean', diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index e9957f64ede..bb796afcae8 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -1147,7 +1147,7 @@ interface IEditorPartConfiguration { splitOnDragAndDrop?: boolean; centeredLayoutFixedWidth?: boolean; doubleClickTabToToggleEditorGroupSizes?: 'maximize' | 'expand' | 'off'; - showEditorActionsInTitleBar?: 'noTabs' | 'never'; + editorActionsLocation?: 'default' | 'titleBar' | 'hidden'; limit?: IEditorPartLimitConfiguration; decorations?: IEditorPartDecorationsConfiguration; } From d2d9072c915fefd40b31b16da22c3520e6530610 Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:01:09 +0100 Subject: [PATCH 056/240] Fix #197607 (#197623) fix #197607 --- .../workbench/browser/parts/editor/editorGroupView.ts | 10 ++++++++-- .../services/editor/common/editorGroupsService.ts | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 0da1794a339..c29fd8a1ad5 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -9,7 +9,7 @@ import { GroupIdentifier, CloseDirection, IEditorCloseEvent, IEditorPane, SaveRe import { ActiveEditorGroupLockedContext, ActiveEditorDirtyContext, EditorGroupEditorsCountContext, ActiveEditorStickyContext, ActiveEditorPinnedContext, ActiveEditorLastInGroupContext, ActiveEditorFirstInGroupContext, EditorPinnedAndUnpinnedTabsContext, ResourceContextKey, applyAvailableEditorIds, ActiveEditorAvailableEditorIdsContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext } from 'vs/workbench/common/contextkeys'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput'; -import { Emitter, Relay, Event } from 'vs/base/common/event'; +import { Emitter, Relay } from 'vs/base/common/event'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Dimension, trackFocus, addDisposableListener, EventType, EventHelper, findParentWithClass, isAncestor, IDomNodePagePosition, isMouseEvent, isActiveElement, focusWindow } from 'vs/base/browser/dom'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; @@ -1915,7 +1915,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { const primary: IAction[] = []; const secondary: IAction[] = []; - let onDidChange = Event.None; + let onDidChange; // Editor actions require the editor control to be there, so we retrieve it via service const activeEditorPane = this.activeEditorPane; @@ -1933,6 +1933,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView { 'navigation', shouldInlineGroup ); + } else { + // If there is no active pane in the group (it's the last group and it's empty) + // Trigger the change event when the active editor changes + const _onDidChange = new Emitter(); + onDidChange = _onDidChange.event; + disposables.add(this.onDidActiveEditorChange(() => _onDidChange.fire())); } return { actions: { primary, secondary }, onDidChange }; diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index 1c003b02a58..d56f4fc3fb6 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -514,7 +514,7 @@ export const enum OpenEditorContext { export interface IActiveEditorActions { readonly actions: IToolbarActions; - readonly onDidChange: Event; + readonly onDidChange: Event; } export interface IEditorGroup { From 8279aab1559635f77c3a9f44d7ce6a4dcd61e7aa Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:43:45 +0100 Subject: [PATCH 057/240] Dispose Emitter (#197626) :liptick: --- src/vs/workbench/browser/parts/editor/editorGroupView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index c29fd8a1ad5..8716817afa6 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -1936,7 +1936,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } else { // If there is no active pane in the group (it's the last group and it's empty) // Trigger the change event when the active editor changes - const _onDidChange = new Emitter(); + const _onDidChange = disposables.add(new Emitter()); onDidChange = _onDidChange.event; disposables.add(this.onDidActiveEditorChange(() => _onDidChange.fire())); } From 3453c4f9f0186dac194eb4b7d3d27d513a61d5be Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 7 Nov 2023 12:52:20 +0100 Subject: [PATCH 058/240] aux window - avoid/flag more globals (#197614) * aux window - avoid/flag more globals * fix access from worker * allow `queueMicrotask` * more adoptions * fix build * avoid $globalThis --- .eslintrc.json | 132 ++++++++++++++++++ build/lib/layersChecker.js | 17 ++- build/lib/layersChecker.ts | 17 +++ src/vs/base/browser/dom.ts | 28 ++-- src/vs/base/browser/indexedDB.ts | 9 +- src/vs/base/browser/touch.ts | 4 +- .../ui/breadcrumbs/breadcrumbsWidget.ts | 12 +- src/vs/base/browser/ui/list/listView.ts | 8 +- src/vs/base/browser/ui/menu/menu.ts | 2 +- src/vs/base/browser/ui/menu/menubar.ts | 4 +- .../browser/ui/scrollbar/scrollableElement.ts | 4 +- .../browser/ui/selectBox/selectBoxCustom.ts | 2 +- src/vs/base/browser/ui/splitview/splitview.ts | 2 +- src/vs/base/common/async.ts | 30 +++- src/vs/code/electron-main/app.ts | 2 +- .../electron-sandbox/workbench/workbench.js | 1 - .../browser/config/elementSizeObserver.ts | 4 +- .../editor/browser/controller/mouseHandler.ts | 4 +- src/vs/editor/browser/view.ts | 2 +- .../browser/widget/codeEditorContributions.ts | 9 +- .../editor/browser/widget/codeEditorWidget.ts | 2 +- src/vs/editor/common/model/textModelTokens.ts | 4 +- .../contrib/codelens/browser/codeLensCache.ts | 3 +- .../suggest/browser/suggestController.ts | 7 +- .../contrib/suggest/browser/suggestWidget.ts | 8 +- .../common/instantiationService.ts | 4 +- src/vs/platform/storage/common/storage.ts | 4 +- .../browser/parts/editor/editorStatus.ts | 4 +- .../parts/editor/multiEditorTabsControl.ts | 6 +- .../browser/parts/globalCompositeBar.ts | 3 +- .../notifications/notificationsToasts.ts | 2 +- src/vs/workbench/browser/workbench.ts | 2 +- src/vs/workbench/common/contributions.ts | 6 +- .../contrib/chat/browser/chatListRenderer.ts | 8 +- .../contrib/chat/browser/chatWidget.ts | 8 +- .../browser/outline/documentSymbolsTree.ts | 3 +- .../contrib/comments/browser/commentNode.ts | 6 +- .../contrib/outline/notebookOutline.ts | 3 +- .../notebook/browser/diff/diffComponents.ts | 12 +- .../browser/diff/notebookDiffEditor.ts | 12 +- .../browser/diff/notebookDiffOverviewRuler.ts | 2 +- .../notebook/browser/notebookEditorWidget.ts | 12 +- .../services/notebookKernelServiceImpl.ts | 3 +- .../contrib/notebook/browser/view/cellPart.ts | 12 +- .../browser/view/cellParts/codeCell.ts | 4 +- .../notebook/browser/view/notebookCellList.ts | 12 +- .../view/renderers/backLayerWebView.ts | 4 +- .../notebookEditorWidgetContextKeys.ts | 4 +- .../contrib/snippets/browser/snippetsFile.ts | 3 +- .../contrib/splash/browser/partsSplash.ts | 3 +- .../browser/terminalProcessManager.ts | 2 +- .../browser/xterm/markNavigationAddon.ts | 3 +- .../testing/browser/testingOutputPeek.ts | 2 +- .../url/browser/trustedDomainsValidator.ts | 9 +- .../browser/configurationService.ts | 3 +- .../nativeExtensionService.ts | 3 +- .../common/filesConfigurationService.ts | 6 +- .../history/browser/historyService.ts | 3 +- .../suggest/browser/simpleSuggestWidget.ts | 4 +- .../services/timer/browser/timerService.ts | 1 + .../common/userActivityService.ts | 4 +- .../common/workingCopyHistoryTracker.ts | 2 +- 62 files changed, 347 insertions(+), 154 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 0c1557f932e..c24488ff1d7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -720,9 +720,141 @@ "name": "cancelAnimationFrame", "message": "Use .cancelAnimationFrame to support multi-window scenarios." }, + { + "name": "requestIdleCallback", + "message": "Use .requestIdleCallback to support multi-window scenarios." + }, + { + "name": "cancelIdleCallback", + "message": "Use .cancelIdleCallback to support multi-window scenarios." + }, { "name": "window", "message": "Be aware of multi-window scenarios: Use DOM.getWindow() or DOM.getActiveWindow() to obtain the correct window for the context you are in. Only use window.ts#mainWindow if you target the main window." + }, + { + "name": "addEventListener", + "message": "Use .addEventListener to support multi-window scenarios." + }, + { + "name": "removeEventListener", + "message": "Use .removeEventListener to support multi-window scenarios." + }, + { + "name": "getComputedStyle", + "message": "Use .getComputedStyle to support multi-window scenarios." + }, + { + "name": "focus", + "message": "Use .focus to support multi-window scenarios." + }, + { + "name": "blur", + "message": "Use .blur to support multi-window scenarios." + }, + { + "name": "close", + "message": "Use .close to support multi-window scenarios." + }, + { + "name": "dispatchEvent", + "message": "Use .dispatchEvent to support multi-window scenarios." + }, + { + "name": "getSelection", + "message": "Use .getSelection to support multi-window scenarios." + }, + { + "name": "matchMedia", + "message": "Use .matchMedia to support multi-window scenarios." + }, + { + "name": "open", + "message": "Use .open to support multi-window scenarios." + }, + { + "name": "parent", + "message": "Use .parent to support multi-window scenarios." + }, + { + "name": "postMessage", + "message": "Use .postMessage to support multi-window scenarios." + }, + { + "name": "devicePixelRatio", + "message": "Use .devicePixelRatio to support multi-window scenarios." + }, + { + "name": "frames", + "message": "Use .frames to support multi-window scenarios." + }, + { + "name": "frameElement", + "message": "Use .frameElement to support multi-window scenarios." + }, + { + "name": "innerHeight", + "message": "Use .innerHeight to support multi-window scenarios." + }, + { + "name": "innerWidth", + "message": "Use .innerWidth to support multi-window scenarios." + }, + { + "name": "outerHeight", + "message": "Use .outerHeight to support multi-window scenarios." + }, + { + "name": "outerWidth", + "message": "Use .outerWidth to support multi-window scenarios." + }, + { + "name": "length", + "message": "Use .length to support multi-window scenarios." + }, + { + "name": "opener", + "message": "Use .opener to support multi-window scenarios." + }, + { + "name": "origin", + "message": "Use .origin to support multi-window scenarios." + }, + { + "name": "screen", + "message": "Use .screen to support multi-window scenarios." + }, + { + "name": "screenLeft", + "message": "Use .screenLeft to support multi-window scenarios." + }, + { + "name": "screenTop", + "message": "Use .screenTop to support multi-window scenarios." + }, + { + "name": "screenX", + "message": "Use .screenX to support multi-window scenarios." + }, + { + "name": "screenY", + "message": "Use .screenY to support multi-window scenarios." + }, + { + "name": "scrollX", + "message": "Use .scrollX to support multi-window scenarios." + }, + { + "name": "scrollY", + "message": "Use .scrollY to support multi-window scenarios." + }, + { + "name": "top", + "message": "Use .top to support multi-window scenarios." + }, + { + "name": "visualViewport", + "message": "Use .visualViewport to support multi-window scenarios." } ] } diff --git a/build/lib/layersChecker.js b/build/lib/layersChecker.js index 485e2fc7d07..f94674d79d2 100644 --- a/build/lib/layersChecker.js +++ b/build/lib/layersChecker.js @@ -95,6 +95,21 @@ const RULES = [ '@types/node' // no node.js ] }, + // Common: vs/base/common/async.ts + { + target: '**/vs/base/common/async.ts', + allowedTypes: [ + ...CORE_TYPES, + // Safe access to requestIdleCallback & cancelIdleCallback + 'requestIdleCallback', + 'cancelIdleCallback' + ], + disallowedTypes: NATIVE_TYPES, + disallowedDefinitions: [ + 'lib.dom.d.ts', // no DOM + '@types/node' // no node.js + ] + }, // Common: vs/platform/environment/common/* { target: '**/vs/platform/environment/common/*.ts', @@ -298,4 +313,4 @@ for (const sourceFile of program.getSourceFiles()) { if (hasErrors) { process.exit(1); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXJzQ2hlY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxheWVyc0NoZWNrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyxpQ0FBaUM7QUFDakMsMkJBQThDO0FBQzlDLCtCQUE4QztBQUM5Qyx5Q0FBa0M7QUFFbEMsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBQ0YsK0ZBQStGO0FBQy9GLG1EQUFtRDtBQUNuRCw0RUFBNEU7QUFDNUUsaUVBQWlFO0FBQ2pFLEVBQUU7QUFDRixnR0FBZ0c7QUFDaEcsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBRUYsbUZBQW1GO0FBQ25GLHdGQUF3RjtBQUN4RixNQUFNLFVBQVUsR0FBRztJQUNsQixTQUFTLEVBQUUsc0JBQXNCO0lBQ2pDLFlBQVk7SUFDWixjQUFjO0lBQ2QsYUFBYTtJQUNiLGVBQWU7SUFDZixTQUFTO0lBQ1QsU0FBUztJQUNULE9BQU87SUFDUCxrQkFBa0I7SUFDbEIsUUFBUTtJQUNSLGFBQWE7SUFDYixhQUFhO0lBQ2IsTUFBTTtJQUNOLGdCQUFnQjtJQUNoQixPQUFPO0lBQ1AsWUFBWTtJQUNaLGFBQWE7SUFDYixhQUFhO0lBQ2IsV0FBVztJQUNYLFlBQVk7SUFDWixZQUFZO0lBQ1osY0FBYztJQUNkLGNBQWM7SUFDZCxtQkFBbUI7SUFDbkIsZ0JBQWdCO0lBQ2hCLGVBQWU7SUFDZixNQUFNO0lBQ04sTUFBTTtJQUNOLGlCQUFpQjtJQUNqQixhQUFhO0lBQ2IsZ0JBQWdCO0lBQ2hCLGFBQWE7SUFDYixLQUFLO0lBQ0wsaUJBQWlCO0lBQ2pCLGVBQWU7SUFDZixPQUFPO0lBQ1AsYUFBYTtJQUNiLGtCQUFrQjtJQUNsQixhQUFhO0lBQ2IsTUFBTTtDQUNOLENBQUM7QUFFRixvRUFBb0U7QUFDcEUsb0VBQW9FO0FBQ3BFLE1BQU0sWUFBWSxHQUFHO0lBQ3BCLGtCQUFrQjtJQUNsQiwyQkFBMkI7SUFDM0Isa0NBQWtDO0lBQ2xDLDRCQUE0QjtJQUM1QiwwQkFBMEI7SUFDMUIsb0JBQW9CO0lBQ3BCLHFCQUFxQjtDQUNyQixDQUFDO0FBRUYsTUFBTSxLQUFLLEdBQVk7SUFFdEIsY0FBYztJQUNkO1FBQ0MsTUFBTSxFQUFFLGtCQUFrQjtRQUMxQixJQUFJLEVBQUUsSUFBSSxDQUFDLHlCQUF5QjtLQUNwQztJQUVELHFDQUFxQztJQUNyQztRQUNDLE1BQU0sRUFBRSwrQkFBK0I7UUFDdkMsWUFBWSxFQUFFO1lBQ2IsR0FBRyxVQUFVO1lBRWIsMkNBQTJDO1lBQzNDLGNBQWM7U0FDZDtRQUNELGVBQWUsRUFBRSxZQUFZO1FBQzdCLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCwyQ0FBMkM7SUFDM0M7UUFDQyxNQUFNLEVBQUUsd0NBQXdDO1FBQ2hELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCw4Q0FBOEM7SUFDOUM7UUFDQyxNQUFNLEVBQUUsd0NBQXdDO1FBQ2hELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCw4Q0FBOEM7SUFDOUM7UUFDQyxNQUFNLEVBQUUsd0NBQXdDO1FBQ2hELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCx5REFBeUQ7SUFDekQ7UUFDQyxNQUFNLEVBQUUsbURBQW1EO1FBQzNELFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxFQUFDLG9EQUFvRCxDQUFDO1FBQ3ZFLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCw2REFBNkQ7SUFDN0Q7UUFDQyxNQUFNLEVBQUUsdURBQXVEO1FBQy9ELFlBQVksRUFBRTtZQUNiLEdBQUcsVUFBVTtZQUViLHdCQUF3QjtZQUN4QixRQUFRO1NBQ1I7UUFDRCxlQUFlLEVBQUUsWUFBWTtRQUM3QixxQkFBcUIsRUFBRTtZQUN0QixjQUFjLEVBQUUsU0FBUztZQUN6QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsU0FBUztJQUNUO1FBQ0MsTUFBTSxFQUFFLG9CQUFvQjtRQUM1QixZQUFZLEVBQUUsVUFBVTtRQUN4QixlQUFlLEVBQUUsWUFBWTtRQUM3QixxQkFBcUIsRUFBRTtZQUN0QixjQUFjLEVBQUUsU0FBUztZQUN6QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsVUFBVTtJQUNWO1FBQ0MsTUFBTSxFQUFFLHFCQUFxQjtRQUM3QixZQUFZLEVBQUUsVUFBVTtRQUN4QixlQUFlLEVBQUUsWUFBWTtRQUM3QixrQkFBa0IsRUFBRTtZQUNuQixtQ0FBbUMsQ0FBQyxzRkFBc0Y7U0FDMUg7UUFDRCxxQkFBcUIsRUFBRTtZQUN0QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsMkJBQTJCO0lBQzNCO1FBQ0MsTUFBTSxFQUFFLDZCQUE2QjtRQUNyQyxZQUFZLEVBQUUsVUFBVTtRQUN4QixlQUFlLEVBQUUsWUFBWTtRQUM3QixxQkFBcUIsRUFBRTtZQUN0QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsVUFBVTtJQUNWO1FBQ0MsTUFBTSxFQUFFLGtCQUFrQjtRQUMxQixZQUFZLEVBQUUsVUFBVTtRQUN4QixxQkFBcUIsRUFBRTtZQUN0QixjQUFjLENBQUMsU0FBUztTQUN4QjtLQUNEO0lBRUQscUJBQXFCO0lBQ3JCO1FBQ0MsTUFBTSxFQUFFLDhCQUE4QjtRQUN0QyxZQUFZLEVBQUUsVUFBVTtRQUN4QixxQkFBcUIsRUFBRTtZQUN0QixhQUFhLENBQUMsYUFBYTtTQUMzQjtLQUNEO0lBRUQsa0JBQWtCO0lBQ2xCO1FBQ0MsTUFBTSxFQUFFLDJCQUEyQjtRQUNuQyxZQUFZLEVBQUU7WUFDYixHQUFHLFVBQVU7WUFFYixnRUFBZ0U7WUFDaEUsT0FBTztZQUNQLFNBQVM7U0FDVDtRQUNELGVBQWUsRUFBRTtZQUNoQixTQUFTLENBQUMsNENBQTRDO1NBQ3REO1FBQ0QscUJBQXFCLEVBQUU7WUFDdEIsY0FBYyxDQUFDLFNBQVM7U0FDeEI7S0FDRDtDQUNELENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxlQUFlLENBQUMsQ0FBQztBQVd6RSxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7QUFFdEIsU0FBUyxTQUFTLENBQUMsT0FBbUIsRUFBRSxVQUF5QixFQUFFLElBQVc7SUFDN0UsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRXRCLFNBQVMsU0FBUyxDQUFDLElBQWE7UUFDL0IsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDNUMsT0FBTyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLGVBQWU7UUFDekQsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN6QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFakQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2IsT0FBTztRQUNSLENBQUM7UUFFRCxJQUFJLGFBQWEsR0FBUSxNQUFNLENBQUM7UUFFaEMsT0FBTyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDN0IsYUFBYSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUM7UUFDdEMsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFHLGFBQTBCLENBQUM7UUFDaEQsTUFBTSxJQUFJLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRXBDLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMxRCxPQUFPLENBQUMsV0FBVztRQUNwQixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ25FLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEdBQUcsVUFBVSxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3RGLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0RBQW9ELElBQUkscUJBQXFCLElBQUksQ0FBQyxNQUFNLE1BQU0sVUFBVSxDQUFDLFFBQVEsS0FBSyxJQUFJLEdBQUcsQ0FBQyxJQUFJLFNBQVMsR0FBRyxDQUFDLHdIQUF3SCxDQUFDLENBQUM7WUFFclIsU0FBUyxHQUFHLElBQUksQ0FBQztZQUNqQixPQUFPO1FBQ1IsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUM7UUFDekMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDakMsZUFBZSxFQUFFLEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ3pELElBQUksV0FBVyxFQUFFLENBQUM7b0JBQ2pCLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUM7b0JBQ2xDLElBQUksTUFBTSxFQUFFLENBQUM7d0JBQ1osTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7d0JBQ2hELElBQUksZ0JBQWdCLEVBQUUsQ0FBQzs0QkFDdEIsTUFBTSxrQkFBa0IsR0FBRyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUM7NEJBQ3JELElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0NBQzdCLEtBQUssTUFBTSxpQkFBaUIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztvQ0FDekQsSUFBSSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzt3Q0FDeEQsU0FBUyxlQUFlLENBQUM7b0NBQzFCLENBQUM7Z0NBQ0YsQ0FBQzs0QkFDRixDQUFDOzRCQUNELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7Z0NBQ2hDLEtBQUssTUFBTSxvQkFBb0IsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztvQ0FDL0QsSUFBSSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzt3Q0FDM0QsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxVQUFVLENBQUMsNkJBQTZCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7d0NBRXRGLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0RBQXNELElBQUksV0FBVyxvQkFBb0IscUJBQXFCLElBQUksQ0FBQyxNQUFNLE1BQU0sVUFBVSxDQUFDLFFBQVEsS0FBSyxJQUFJLEdBQUcsQ0FBQyxJQUFJLFNBQVMsR0FBRyxDQUFDLHVIQUF1SCxDQUFDLENBQUM7d0NBRXJULFNBQVMsR0FBRyxJQUFJLENBQUM7d0NBQ2pCLE9BQU87b0NBQ1IsQ0FBQztnQ0FDRixDQUFDOzRCQUNGLENBQUM7d0JBQ0YsQ0FBQztvQkFDRixDQUFDO2dCQUNGLENBQUM7WUFDRixDQUFDO1FBQ0YsQ0FBQztJQUNGLENBQUM7QUFDRixDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsWUFBb0I7SUFDMUMsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUVsRSxNQUFNLGdCQUFnQixHQUF1QixFQUFFLFVBQVUsRUFBRSxlQUFVLEVBQUUsYUFBYSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUEsaUJBQVksRUFBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEVBQUUseUJBQXlCLEVBQUUsT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztJQUNwTixNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUMsMEJBQTBCLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxJQUFBLGNBQU8sRUFBQyxJQUFBLGNBQU8sRUFBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFFMUksTUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFFekUsT0FBTyxFQUFFLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztBQUN6RixDQUFDO0FBRUQsRUFBRTtBQUNGLG9DQUFvQztBQUNwQyxFQUFFO0FBQ0YsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBRTlDLEtBQUssTUFBTSxVQUFVLElBQUksT0FBTyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7SUFDbkQsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxQixJQUFJLElBQUEsaUJBQUssRUFBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2hCLFNBQVMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3RDLENBQUM7WUFFRCxNQUFNO1FBQ1AsQ0FBQztJQUNGLENBQUM7QUFDRixDQUFDO0FBRUQsSUFBSSxTQUFTLEVBQUUsQ0FBQztJQUNmLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakIsQ0FBQyJ9 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXJzQ2hlY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxheWVyc0NoZWNrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyxpQ0FBaUM7QUFDakMsMkJBQThDO0FBQzlDLCtCQUE4QztBQUM5Qyx5Q0FBa0M7QUFFbEMsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBQ0YsK0ZBQStGO0FBQy9GLG1EQUFtRDtBQUNuRCw0RUFBNEU7QUFDNUUsaUVBQWlFO0FBQ2pFLEVBQUU7QUFDRixnR0FBZ0c7QUFDaEcsRUFBRTtBQUNGLGdHQUFnRztBQUNoRyxFQUFFO0FBRUYsbUZBQW1GO0FBQ25GLHdGQUF3RjtBQUN4RixNQUFNLFVBQVUsR0FBRztJQUNsQixTQUFTLEVBQUUsc0JBQXNCO0lBQ2pDLFlBQVk7SUFDWixjQUFjO0lBQ2QsYUFBYTtJQUNiLGVBQWU7SUFDZixTQUFTO0lBQ1QsU0FBUztJQUNULE9BQU87SUFDUCxrQkFBa0I7SUFDbEIsUUFBUTtJQUNSLGFBQWE7SUFDYixhQUFhO0lBQ2IsTUFBTTtJQUNOLGdCQUFnQjtJQUNoQixPQUFPO0lBQ1AsWUFBWTtJQUNaLGFBQWE7SUFDYixhQUFhO0lBQ2IsV0FBVztJQUNYLFlBQVk7SUFDWixZQUFZO0lBQ1osY0FBYztJQUNkLGNBQWM7SUFDZCxtQkFBbUI7SUFDbkIsZ0JBQWdCO0lBQ2hCLGVBQWU7SUFDZixNQUFNO0lBQ04sTUFBTTtJQUNOLGlCQUFpQjtJQUNqQixhQUFhO0lBQ2IsZ0JBQWdCO0lBQ2hCLGFBQWE7SUFDYixLQUFLO0lBQ0wsaUJBQWlCO0lBQ2pCLGVBQWU7SUFDZixPQUFPO0lBQ1AsYUFBYTtJQUNiLGtCQUFrQjtJQUNsQixhQUFhO0lBQ2IsTUFBTTtDQUNOLENBQUM7QUFFRixvRUFBb0U7QUFDcEUsb0VBQW9FO0FBQ3BFLE1BQU0sWUFBWSxHQUFHO0lBQ3BCLGtCQUFrQjtJQUNsQiwyQkFBMkI7SUFDM0Isa0NBQWtDO0lBQ2xDLDRCQUE0QjtJQUM1QiwwQkFBMEI7SUFDMUIsb0JBQW9CO0lBQ3BCLHFCQUFxQjtDQUNyQixDQUFDO0FBRUYsTUFBTSxLQUFLLEdBQVk7SUFFdEIsY0FBYztJQUNkO1FBQ0MsTUFBTSxFQUFFLGtCQUFrQjtRQUMxQixJQUFJLEVBQUUsSUFBSSxDQUFDLHlCQUF5QjtLQUNwQztJQUVELHFDQUFxQztJQUNyQztRQUNDLE1BQU0sRUFBRSwrQkFBK0I7UUFDdkMsWUFBWSxFQUFFO1lBQ2IsR0FBRyxVQUFVO1lBRWIsMkNBQTJDO1lBQzNDLGNBQWM7U0FDZDtRQUNELGVBQWUsRUFBRSxZQUFZO1FBQzdCLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCxrQ0FBa0M7SUFDbEM7UUFDQyxNQUFNLEVBQUUsNEJBQTRCO1FBQ3BDLFlBQVksRUFBRTtZQUNiLEdBQUcsVUFBVTtZQUViLDBEQUEwRDtZQUMxRCxxQkFBcUI7WUFDckIsb0JBQW9CO1NBQ3BCO1FBQ0QsZUFBZSxFQUFFLFlBQVk7UUFDN0IscUJBQXFCLEVBQUU7WUFDdEIsY0FBYyxFQUFFLFNBQVM7WUFDekIsYUFBYSxDQUFDLGFBQWE7U0FDM0I7S0FDRDtJQUVELDJDQUEyQztJQUMzQztRQUNDLE1BQU0sRUFBRSx3Q0FBd0M7UUFDaEQsWUFBWSxFQUFFLFVBQVU7UUFDeEIsZUFBZSxFQUFFLEVBQUMsb0RBQW9ELENBQUM7UUFDdkUscUJBQXFCLEVBQUU7WUFDdEIsY0FBYyxFQUFFLFNBQVM7WUFDekIsYUFBYSxDQUFDLGFBQWE7U0FDM0I7S0FDRDtJQUVELDhDQUE4QztJQUM5QztRQUNDLE1BQU0sRUFBRSx3Q0FBd0M7UUFDaEQsWUFBWSxFQUFFLFVBQVU7UUFDeEIsZUFBZSxFQUFFLEVBQUMsb0RBQW9ELENBQUM7UUFDdkUscUJBQXFCLEVBQUU7WUFDdEIsY0FBYyxFQUFFLFNBQVM7WUFDekIsYUFBYSxDQUFDLGFBQWE7U0FDM0I7S0FDRDtJQUVELDhDQUE4QztJQUM5QztRQUNDLE1BQU0sRUFBRSx3Q0FBd0M7UUFDaEQsWUFBWSxFQUFFLFVBQVU7UUFDeEIsZUFBZSxFQUFFLEVBQUMsb0RBQW9ELENBQUM7UUFDdkUscUJBQXFCLEVBQUU7WUFDdEIsY0FBYyxFQUFFLFNBQVM7WUFDekIsYUFBYSxDQUFDLGFBQWE7U0FDM0I7S0FDRDtJQUVELHlEQUF5RDtJQUN6RDtRQUNDLE1BQU0sRUFBRSxtREFBbUQ7UUFDM0QsWUFBWSxFQUFFLFVBQVU7UUFDeEIsZUFBZSxFQUFFLEVBQUMsb0RBQW9ELENBQUM7UUFDdkUscUJBQXFCLEVBQUU7WUFDdEIsY0FBYyxFQUFFLFNBQVM7WUFDekIsYUFBYSxDQUFDLGFBQWE7U0FDM0I7S0FDRDtJQUVELDZEQUE2RDtJQUM3RDtRQUNDLE1BQU0sRUFBRSx1REFBdUQ7UUFDL0QsWUFBWSxFQUFFO1lBQ2IsR0FBRyxVQUFVO1lBRWIsd0JBQXdCO1lBQ3hCLFFBQVE7U0FDUjtRQUNELGVBQWUsRUFBRSxZQUFZO1FBQzdCLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCxTQUFTO0lBQ1Q7UUFDQyxNQUFNLEVBQUUsb0JBQW9CO1FBQzVCLFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxZQUFZO1FBQzdCLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsRUFBRSxTQUFTO1lBQ3pCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCxVQUFVO0lBQ1Y7UUFDQyxNQUFNLEVBQUUscUJBQXFCO1FBQzdCLFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxZQUFZO1FBQzdCLGtCQUFrQixFQUFFO1lBQ25CLG1DQUFtQyxDQUFDLHNGQUFzRjtTQUMxSDtRQUNELHFCQUFxQixFQUFFO1lBQ3RCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCwyQkFBMkI7SUFDM0I7UUFDQyxNQUFNLEVBQUUsNkJBQTZCO1FBQ3JDLFlBQVksRUFBRSxVQUFVO1FBQ3hCLGVBQWUsRUFBRSxZQUFZO1FBQzdCLHFCQUFxQixFQUFFO1lBQ3RCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCxVQUFVO0lBQ1Y7UUFDQyxNQUFNLEVBQUUsa0JBQWtCO1FBQzFCLFlBQVksRUFBRSxVQUFVO1FBQ3hCLHFCQUFxQixFQUFFO1lBQ3RCLGNBQWMsQ0FBQyxTQUFTO1NBQ3hCO0tBQ0Q7SUFFRCxxQkFBcUI7SUFDckI7UUFDQyxNQUFNLEVBQUUsOEJBQThCO1FBQ3RDLFlBQVksRUFBRSxVQUFVO1FBQ3hCLHFCQUFxQixFQUFFO1lBQ3RCLGFBQWEsQ0FBQyxhQUFhO1NBQzNCO0tBQ0Q7SUFFRCxrQkFBa0I7SUFDbEI7UUFDQyxNQUFNLEVBQUUsMkJBQTJCO1FBQ25DLFlBQVksRUFBRTtZQUNiLEdBQUcsVUFBVTtZQUViLGdFQUFnRTtZQUNoRSxPQUFPO1lBQ1AsU0FBUztTQUNUO1FBQ0QsZUFBZSxFQUFFO1lBQ2hCLFNBQVMsQ0FBQyw0Q0FBNEM7U0FDdEQ7UUFDRCxxQkFBcUIsRUFBRTtZQUN0QixjQUFjLENBQUMsU0FBUztTQUN4QjtLQUNEO0NBQ0QsQ0FBQztBQUVGLE1BQU0sY0FBYyxHQUFHLElBQUEsV0FBSSxFQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLGVBQWUsQ0FBQyxDQUFDO0FBV3pFLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQztBQUV0QixTQUFTLFNBQVMsQ0FBQyxPQUFtQixFQUFFLFVBQXlCLEVBQUUsSUFBVztJQUM3RSxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUM7SUFFdEIsU0FBUyxTQUFTLENBQUMsSUFBYTtRQUMvQixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUM1QyxPQUFPLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsZUFBZTtRQUN6RCxDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVqRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDYixPQUFPO1FBQ1IsQ0FBQztRQUVELElBQUksYUFBYSxHQUFRLE1BQU0sQ0FBQztRQUVoQyxPQUFPLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM3QixhQUFhLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQztRQUN0QyxDQUFDO1FBRUQsTUFBTSxZQUFZLEdBQUcsYUFBMEIsQ0FBQztRQUNoRCxNQUFNLElBQUksR0FBRyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFcEMsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQzFELE9BQU8sQ0FBQyxXQUFXO1FBQ3BCLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsVUFBVSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDbkUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxVQUFVLENBQUMsNkJBQTZCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDdEYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvREFBb0QsSUFBSSxxQkFBcUIsSUFBSSxDQUFDLE1BQU0sTUFBTSxVQUFVLENBQUMsUUFBUSxLQUFLLElBQUksR0FBRyxDQUFDLElBQUksU0FBUyxHQUFHLENBQUMsd0hBQXdILENBQUMsQ0FBQztZQUVyUixTQUFTLEdBQUcsSUFBSSxDQUFDO1lBQ2pCLE9BQU87UUFDUixDQUFDO1FBRUQsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQztRQUN6QyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUNqQyxlQUFlLEVBQUUsS0FBSyxNQUFNLFdBQVcsSUFBSSxZQUFZLEVBQUUsQ0FBQztnQkFDekQsSUFBSSxXQUFXLEVBQUUsQ0FBQztvQkFDakIsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQztvQkFDbEMsSUFBSSxNQUFNLEVBQUUsQ0FBQzt3QkFDWixNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQzt3QkFDaEQsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDOzRCQUN0QixNQUFNLGtCQUFrQixHQUFHLGdCQUFnQixDQUFDLFFBQVEsQ0FBQzs0QkFDckQsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztnQ0FDN0IsS0FBSyxNQUFNLGlCQUFpQixJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO29DQUN6RCxJQUFJLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO3dDQUN4RCxTQUFTLGVBQWUsQ0FBQztvQ0FDMUIsQ0FBQztnQ0FDRixDQUFDOzRCQUNGLENBQUM7NEJBQ0QsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztnQ0FDaEMsS0FBSyxNQUFNLG9CQUFvQixJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO29DQUMvRCxJQUFJLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO3dDQUMzRCxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxHQUFHLFVBQVUsQ0FBQyw2QkFBNkIsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQzt3Q0FFdEYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzREFBc0QsSUFBSSxXQUFXLG9CQUFvQixxQkFBcUIsSUFBSSxDQUFDLE1BQU0sTUFBTSxVQUFVLENBQUMsUUFBUSxLQUFLLElBQUksR0FBRyxDQUFDLElBQUksU0FBUyxHQUFHLENBQUMsdUhBQXVILENBQUMsQ0FBQzt3Q0FFclQsU0FBUyxHQUFHLElBQUksQ0FBQzt3Q0FDakIsT0FBTztvQ0FDUixDQUFDO2dDQUNGLENBQUM7NEJBQ0YsQ0FBQzt3QkFDRixDQUFDO29CQUNGLENBQUM7Z0JBQ0YsQ0FBQztZQUNGLENBQUM7UUFDRixDQUFDO0lBQ0YsQ0FBQztBQUNGLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxZQUFvQjtJQUMxQyxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRWxFLE1BQU0sZ0JBQWdCLEdBQXVCLEVBQUUsVUFBVSxFQUFFLGVBQVUsRUFBRSxhQUFhLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBQSxpQkFBWSxFQUFDLElBQUksRUFBRSxNQUFNLENBQUMsRUFBRSx5QkFBeUIsRUFBRSxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sRUFBRSxDQUFDO0lBQ3BOLE1BQU0sY0FBYyxHQUFHLEVBQUUsQ0FBQywwQkFBMEIsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLGdCQUFnQixFQUFFLElBQUEsY0FBTyxFQUFDLElBQUEsY0FBTyxFQUFDLFlBQVksQ0FBQyxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUUxSSxNQUFNLFlBQVksR0FBRyxFQUFFLENBQUMsa0JBQWtCLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUV6RSxPQUFPLEVBQUUsQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxjQUFjLENBQUMsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQ3pGLENBQUM7QUFFRCxFQUFFO0FBQ0Ysb0NBQW9DO0FBQ3BDLEVBQUU7QUFDRixNQUFNLE9BQU8sR0FBRyxhQUFhLENBQUMsY0FBYyxDQUFDLENBQUM7QUFFOUMsS0FBSyxNQUFNLFVBQVUsSUFBSSxPQUFPLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQztJQUNuRCxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQzFCLElBQUksSUFBQSxpQkFBSyxFQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDMUQsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDaEIsU0FBUyxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDdEMsQ0FBQztZQUVELE1BQU07UUFDUCxDQUFDO0lBQ0YsQ0FBQztBQUNGLENBQUM7QUFFRCxJQUFJLFNBQVMsRUFBRSxDQUFDO0lBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQixDQUFDIn0= \ No newline at end of file diff --git a/build/lib/layersChecker.ts b/build/lib/layersChecker.ts index 515081d7828..864d61f1452 100644 --- a/build/lib/layersChecker.ts +++ b/build/lib/layersChecker.ts @@ -102,6 +102,23 @@ const RULES: IRule[] = [ ] }, + // Common: vs/base/common/async.ts + { + target: '**/vs/base/common/async.ts', + allowedTypes: [ + ...CORE_TYPES, + + // Safe access to requestIdleCallback & cancelIdleCallback + 'requestIdleCallback', + 'cancelIdleCallback' + ], + disallowedTypes: NATIVE_TYPES, + disallowedDefinitions: [ + 'lib.dom.d.ts', // no DOM + '@types/node' // no node.js + ] + }, + // Common: vs/platform/environment/common/* { target: '**/vs/platform/environment/common/*.ts', diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 171ba15ed13..2d0d87a1448 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -184,14 +184,14 @@ export function addDisposableGenericMouseUpListener(node: EventTarget, handler: * If currently in an animation frame, `runner` will be executed immediately. * @return token that can be used to cancel the scheduled runner (only if `runner` was not executed immediately). */ -export let runAtThisOrScheduleAtNextAnimationFrame: (runner: () => void, targetWindow: Window, priority?: number) => IDisposable; +export let runAtThisOrScheduleAtNextAnimationFrame: (targetWindow: Window, runner: () => void, priority?: number) => IDisposable; /** * Schedule a callback to be run at the next animation frame. * This allows multiple parties to register callbacks that should run at the next animation frame. * If currently in an animation frame, `runner` will be executed at the next animation frame. * @return token that can be used to cancel the scheduled runner. */ -export let scheduleAtNextAnimationFrame: (runner: () => void, targetWindow: Window, priority?: number) => IDisposable; +export let scheduleAtNextAnimationFrame: (targetWindow: Window, runner: () => void, priority?: number) => IDisposable; class AnimationFrameQueueItem implements IDisposable { @@ -261,7 +261,7 @@ class AnimationFrameQueueItem implements IDisposable { inAnimationFrameRunner.set(targetWindowId, false); }; - scheduleAtNextAnimationFrame = (runner: () => void, targetWindow: Window, priority: number = 0) => { + scheduleAtNextAnimationFrame = (targetWindow: Window, runner: () => void, priority: number = 0) => { const targetWindowId = getWindowId(targetWindow); const item = new AnimationFrameQueueItem(runner, priority); @@ -280,7 +280,7 @@ class AnimationFrameQueueItem implements IDisposable { return item; }; - runAtThisOrScheduleAtNextAnimationFrame = (runner: () => void, targetWindow: Window, priority?: number) => { + runAtThisOrScheduleAtNextAnimationFrame = (targetWindow: Window, runner: () => void, priority?: number) => { const targetWindowId = getWindowId(targetWindow); if (inAnimationFrameRunner.get(targetWindowId)) { const item = new AnimationFrameQueueItem(runner, priority); @@ -292,17 +292,17 @@ class AnimationFrameQueueItem implements IDisposable { currentQueue.push(item); return item; } else { - return scheduleAtNextAnimationFrame(runner, targetWindow, priority); + return scheduleAtNextAnimationFrame(targetWindow, runner, priority); } }; })(); -export function measure(callback: () => void, targetWindow: Window): IDisposable { - return scheduleAtNextAnimationFrame(callback, targetWindow, 10000 /* must be early */); +export function measure(targetWindow: Window, callback: () => void): IDisposable { + return scheduleAtNextAnimationFrame(targetWindow, callback, 10000 /* must be early */); } -export function modify(callback: () => void, targetWindow: Window): IDisposable { - return scheduleAtNextAnimationFrame(callback, targetWindow, -10000 /* must be late */); +export function modify(targetWindow: Window, callback: () => void): IDisposable { + return scheduleAtNextAnimationFrame(targetWindow, callback, -10000 /* must be late */); } /** @@ -1487,13 +1487,13 @@ export function windowOpenWithSuccess(url: string, noOpener = true): boolean { return false; } -export function animate(fn: () => void, targetWindow: Window): IDisposable { +export function animate(targetWindow: Window, fn: () => void): IDisposable { const step = () => { fn(); - stepDisposable = scheduleAtNextAnimationFrame(step, targetWindow); + stepDisposable = scheduleAtNextAnimationFrame(targetWindow, step); }; - let stepDisposable = scheduleAtNextAnimationFrame(step, targetWindow); + let stepDisposable = scheduleAtNextAnimationFrame(targetWindow, step); return toDisposable(() => stepDisposable.dispose()); } @@ -1621,7 +1621,7 @@ export function detectFullscreen(): IDetectedFullscreen | null { // height and comparing that to window height, we can guess // it though. - if ($window.innerHeight === screen.height) { + if ($window.innerHeight === $window.screen.height) { // if the height of the window matches the screen height, we can // safely assume that the browser is fullscreen because no browser // chrome is taking height away (e.g. like toolbars). @@ -1630,7 +1630,7 @@ export function detectFullscreen(): IDetectedFullscreen | null { if (platform.isMacintosh || platform.isLinux) { // macOS and Linux do not properly report `innerHeight`, only Windows does - if ($window.outerHeight === screen.height && $window.outerWidth === screen.width) { + if ($window.outerHeight === $window.screen.height && $window.outerWidth === $window.screen.width) { // if the height of the browser matches the screen height, we can // only guess that we are in fullscreen. It is also possible that // the user has turned off taskbars in the OS and the browser is diff --git a/src/vs/base/browser/indexedDB.ts b/src/vs/base/browser/indexedDB.ts index 867525c0982..38be907918e 100644 --- a/src/vs/base/browser/indexedDB.ts +++ b/src/vs/base/browser/indexedDB.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { mainWindow } from 'vs/base/browser/window'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { getErrorMessage } from 'vs/base/common/errors'; import { mark } from 'vs/base/common/performance'; @@ -55,7 +54,7 @@ export class IndexedDB { private static doOpenDatabase(name: string, version: number | undefined, stores: string[]): Promise { return new Promise((c, e) => { - const request = mainWindow.indexedDB.open(name, version); + const request = indexedDB.open(name, version); request.onerror = () => e(request.error); request.onsuccess = () => { const db = request.result; @@ -79,13 +78,13 @@ export class IndexedDB { }); } - private static deleteDatabase(indexedDB: IDBDatabase): Promise { + private static deleteDatabase(database: IDBDatabase): Promise { return new Promise((c, e) => { // Close any opened connections - indexedDB.close(); + database.close(); // Delete the db - const deleteRequest = mainWindow.indexedDB.deleteDatabase(indexedDB.name); + const deleteRequest = indexedDB.deleteDatabase(database.name); deleteRequest.onerror = (err) => e(deleteRequest.error); deleteRequest.onsuccess = () => c(); }); diff --git a/src/vs/base/browser/touch.ts b/src/vs/base/browser/touch.ts index bee0173f746..79e3211d85f 100644 --- a/src/vs/base/browser/touch.ts +++ b/src/vs/base/browser/touch.ts @@ -284,7 +284,7 @@ export class Gesture extends Disposable { } private inertia(targetWindow: Window, dispatchTo: readonly EventTarget[], t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void { - this.handle = DomUtils.scheduleAtNextAnimationFrame(() => { + this.handle = DomUtils.scheduleAtNextAnimationFrame(targetWindow, () => { const now = Date.now(); // velocity: old speed + accel_over_time @@ -314,7 +314,7 @@ export class Gesture extends Disposable { if (!stopped) { this.inertia(targetWindow, dispatchTo, now, vX, dirX, x + delta_pos_x, vY, dirY, y + delta_pos_y); } - }, targetWindow); + }); } private onTouchMove(e: TouchEvent): void { diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index 6c4edfef56d..7e130b71d09 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -123,23 +123,23 @@ export class BreadcrumbsWidget { private _updateDimensions(dim: dom.Dimension): IDisposable { const disposables = new DisposableStore(); - disposables.add(dom.modify(() => { + disposables.add(dom.modify(dom.getWindow(this._domNode), () => { this._dimension = dim; this._domNode.style.width = `${dim.width}px`; this._domNode.style.height = `${dim.height}px`; disposables.add(this._updateScrollbar()); - }, dom.getWindow(this._domNode))); + })); return disposables; } private _updateScrollbar(): IDisposable { - return dom.measure(() => { - dom.measure(() => { // double RAF + return dom.measure(dom.getWindow(this._domNode), () => { + dom.measure(dom.getWindow(this._domNode), () => { // double RAF this._scrollable.setRevealOnScroll(false); this._scrollable.scanDomNode(); this._scrollable.setRevealOnScroll(true); - }, dom.getWindow(this._domNode)); - }, dom.getWindow(this._domNode)); + }); + }); } private _style(styleElement: HTMLStyleElement, style: IBreadcrumbsWidgetStyles): void { diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index 2b99e6a143f..af760c78a6d 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -407,7 +407,7 @@ export class ListView implements IListView { this.scrollable = this.disposables.add(new Scrollable({ forceIntegerValues: true, smoothScrollDuration: (options.smoothScrolling ?? false) ? 125 : 0, - scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(cb, getWindow(this.domNode)) + scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(getWindow(this.domNode), cb) })); this.scrollableElement = this.disposables.add(new SmoothScrollableElement(this.rowsContainer, { alwaysConsumeMouseWheel: options.alwaysConsumeMouseWheel ?? DefaultOptions.alwaysConsumeMouseWheel, @@ -680,11 +680,11 @@ export class ListView implements IListView { this.rowsContainer.style.height = `${this._scrollHeight}px`; if (!this.scrollableElementUpdateDisposable) { - this.scrollableElementUpdateDisposable = scheduleAtNextAnimationFrame(() => { + this.scrollableElementUpdateDisposable = scheduleAtNextAnimationFrame(getWindow(this.domNode), () => { this.scrollableElement.setScrollDimensions({ scrollHeight: this.scrollHeight }); this.updateScrollWidth(); this.scrollableElementUpdateDisposable = null; - }, getWindow(this.domNode)); + }); } } @@ -1291,7 +1291,7 @@ export class ListView implements IListView { private setupDragAndDropScrollTopAnimation(event: DragEvent): void { if (!this.dragOverAnimationDisposable) { const viewTop = getTopLeftOffset(this.domNode).top; - this.dragOverAnimationDisposable = animate(this.animateDragAndDropScrollTop.bind(this, viewTop), getWindow(this.domNode)); + this.dragOverAnimationDisposable = animate(getWindow(this.domNode), this.animateDragAndDropScrollTop.bind(this, viewTop)); } this.dragOverAnimationStopDisposable.dispose(); diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 64c1daf2838..5d47bfdb09d 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -876,7 +876,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem { // Set the top value of the menu container before construction // This allows the menu constructor to calculate the proper max height - const computedStyles = getComputedStyle(this.parentData.parent.domNode); + const computedStyles = getWindow(this.parentData.parent.domNode).getComputedStyle(this.parentData.parent.domNode); const paddingTop = parseFloat(computedStyles.paddingTop || '0') || 0; // this.submenuContainer.style.top = `${this.element.offsetTop - this.parentData.parent.scrollOffset - paddingTop}px`; this.submenuContainer.style.zIndex = '1'; diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index 58b3f29af0f..199189dadf4 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -627,10 +627,10 @@ export class MenuBar extends Disposable { }); if (!this.overflowLayoutScheduled) { - this.overflowLayoutScheduled = DOM.scheduleAtNextAnimationFrame(() => { + this.overflowLayoutScheduled = DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this.container), () => { this.updateOverflowAction(); this.overflowLayoutScheduled = undefined; - }, DOM.getWindow(this.container)); + }); } this.setUnfocusedState(); diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index ac02cd0c567..ea8a90ea6c0 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -576,7 +576,7 @@ export class ScrollableElement extends AbstractScrollableElement { const scrollable = new Scrollable({ forceIntegerValues: true, smoothScrollDuration: 0, - scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(callback, dom.getWindow(element)) + scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(element), callback) }); super(element, options, scrollable); this._register(scrollable); @@ -621,7 +621,7 @@ export class DomScrollableElement extends AbstractScrollableElement { const scrollable = new Scrollable({ forceIntegerValues: false, // See https://github.com/microsoft/vscode/issues/139877 smoothScrollDuration: 0, - scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(callback, dom.getWindow(element)) + scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(element), callback) }); super(element, options, scrollable); this._register(scrollable); diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts index 4ec3abac78e..83073ee2666 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts @@ -547,7 +547,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi const window = dom.getWindow(this.selectElement); const selectPosition = dom.getDomNodePagePosition(this.selectElement); - const styles = getComputedStyle(this.selectElement); + const styles = dom.getWindow(this.selectElement).getComputedStyle(this.selectElement); const verticalPadding = parseFloat(styles.getPropertyValue('--dropdown-padding-top')) + parseFloat(styles.getPropertyValue('--dropdown-padding-bottom')); const maxSelectDropDownHeightBelow = (window.innerHeight - selectPosition.top - selectPosition.height - (this.selectBoxOptions.minBottomMargin || 0)); const maxSelectDropDownHeightAbove = (selectPosition.top - SelectBoxList.DEFAULT_DROPDOWN_MINIMUM_TOP_MARGIN); diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index e88947b044e..fd0251c432f 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -584,7 +584,7 @@ export class SplitView scheduleAtNextAnimationFrame(callback, getWindow(this.el)), + scheduleAtNextAnimationFrame: callback => scheduleAtNextAnimationFrame(getWindow(this.el), callback), })); this.scrollableElement = this._register(new SmoothScrollableElement(this.viewContainer, { vertical: this.orientation === Orientation.VERTICAL ? (options.scrollbarVisibility ?? ScrollbarVisibility.Auto) : ScrollbarVisibility.Hidden, diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index fa02c451db4..c0b656542da 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -1238,14 +1238,19 @@ export interface IdleDeadline { * [requestIdleCallback]: https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback * [setTimeout]: https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout */ -export let runWhenIdle: (callback: (idle: IdleDeadline) => void, timeout?: number) => IDisposable; +export let runWhenIdle: (targetWindow: typeof globalThis, callback: (idle: IdleDeadline) => void, timeout?: number) => IDisposable; + +/** + * @deprecated use `runWhenIdle` instead passing in the target window + */ +export let globalRunWhenIdle: (callback: (idle: IdleDeadline) => void, timeout?: number) => IDisposable; declare function requestIdleCallback(callback: (args: IdleDeadline) => void, options?: { timeout: number }): number; declare function cancelIdleCallback(handle: number): void; (function () { if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') { - runWhenIdle = (runner) => { + runWhenIdle = (targetWindow, runner) => { setTimeout0(() => { if (disposed) { return; @@ -1269,8 +1274,8 @@ declare function cancelIdleCallback(handle: number): void; }; }; } else { - runWhenIdle = (runner, timeout?) => { - const handle: number = requestIdleCallback(runner, typeof timeout === 'number' ? { timeout } : undefined); + runWhenIdle = (targetWindow, runner, timeout?) => { + const handle: number = targetWindow.requestIdleCallback(runner, typeof timeout === 'number' ? { timeout } : undefined); let disposed = false; return { dispose() { @@ -1278,11 +1283,12 @@ declare function cancelIdleCallback(handle: number): void; return; } disposed = true; - cancelIdleCallback(handle); + targetWindow.cancelIdleCallback(handle); } }; }; } + globalRunWhenIdle = (runner) => runWhenIdle(globalThis, runner); })(); /** @@ -1298,7 +1304,7 @@ export class IdleValue { private _value?: T; private _error: unknown; - constructor(executor: () => T) { + constructor(targetWindow: typeof globalThis, executor: () => T) { this._executor = () => { try { this._value = executor(); @@ -1308,7 +1314,7 @@ export class IdleValue { this._didRun = true; } }; - this._handle = runWhenIdle(() => this._executor()); + this._handle = runWhenIdle(targetWindow, () => this._executor()); } dispose(): void { @@ -1331,6 +1337,16 @@ export class IdleValue { } } +/** + * @deprecated use `IdleValue` instead passing in the target window + */ +export class GlobalIdleValue extends IdleValue { + + constructor(executor: () => T) { + super(globalThis, executor); + } +} + //#endregion export async function retry(task: ITask>, delay: number, retries: number): Promise { diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index cb641c7a08b..48a8a604eab 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -624,7 +624,7 @@ export class CodeApplication extends Disposable { // Set lifecycle phase to `Eventually` after a short delay and when idle (min 2.5sec, max 5sec) const eventuallyPhaseScheduler = this._register(new RunOnceScheduler(() => { - this._register(runWhenIdle(() => this.lifecycleMainService.phase = LifecycleMainPhase.Eventually, 2500)); + this._register(runWhenIdle(globalThis, () => this.lifecycleMainService.phase = LifecycleMainPhase.Eventually, 2500)); }, 2500)); eventuallyPhaseScheduler.schedule(); } diff --git a/src/vs/code/electron-sandbox/workbench/workbench.js b/src/vs/code/electron-sandbox/workbench/workbench.js index b709c8c5008..35e8368d3c9 100644 --- a/src/vs/code/electron-sandbox/workbench/workbench.js +++ b/src/vs/code/electron-sandbox/workbench/workbench.js @@ -61,7 +61,6 @@ // locations, we try to help the browser to // initialize canvas when it is idle, right // before we wait for the scripts to be loaded. - // @ts-ignore window.requestIdleCallback(() => { const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); diff --git a/src/vs/editor/browser/config/elementSizeObserver.ts b/src/vs/editor/browser/config/elementSizeObserver.ts index a7da5f289ed..9dd5af8e6d3 100644 --- a/src/vs/editor/browser/config/elementSizeObserver.ts +++ b/src/vs/editor/browser/config/elementSizeObserver.ts @@ -66,10 +66,10 @@ export class ElementSizeObserver extends Disposable { alreadyObservedThisAnimationFrame = true; observeNow(); } finally { - scheduleAtNextAnimationFrame(() => { + scheduleAtNextAnimationFrame(getWindow(this._referenceDomElement), () => { alreadyObservedThisAnimationFrame = false; update(); - }, getWindow(this._referenceDomElement)); + }); } } }; diff --git a/src/vs/editor/browser/controller/mouseHandler.ts b/src/vs/editor/browser/controller/mouseHandler.ts index 6796378114d..a0de5c1985e 100644 --- a/src/vs/editor/browser/controller/mouseHandler.ts +++ b/src/vs/editor/browser/controller/mouseHandler.ts @@ -682,7 +682,7 @@ class TopBottomDragScrollingOperation extends Disposable { this._position = position; this._mouseEvent = mouseEvent; this._lastTime = Date.now(); - this._animationFrameDisposable = dom.scheduleAtNextAnimationFrame(() => this._execute(), dom.getWindow(mouseEvent.browserEvent)); + this._animationFrameDisposable = dom.scheduleAtNextAnimationFrame(dom.getWindow(mouseEvent.browserEvent), () => this._execute()); } public override dispose(): void { @@ -752,7 +752,7 @@ class TopBottomDragScrollingOperation extends Disposable { } this._dispatchMouse(mouseTarget, true, NavigationCommandRevealType.None); - this._animationFrameDisposable = dom.scheduleAtNextAnimationFrame(() => this._execute(), dom.getWindow(mouseTarget.element)); + this._animationFrameDisposable = dom.scheduleAtNextAnimationFrame(dom.getWindow(mouseTarget.element), () => this._execute()); } } diff --git a/src/vs/editor/browser/view.ts b/src/vs/editor/browser/view.ts index 700b1d55b1d..7faae2183ae 100644 --- a/src/vs/editor/browser/view.ts +++ b/src/vs/editor/browser/view.ts @@ -432,7 +432,7 @@ export class View extends ViewEventHandler { private _scheduleRender(): void { if (this._renderAnimationFrame === null) { - this._renderAnimationFrame = dom.runAtThisOrScheduleAtNextAnimationFrame(this._onRenderScheduled.bind(this), dom.getWindow(this.domNode.domNode), 100); + this._renderAnimationFrame = dom.runAtThisOrScheduleAtNextAnimationFrame(dom.getWindow(this.domNode.domNode), this._onRenderScheduled.bind(this), 100); } } diff --git a/src/vs/editor/browser/widget/codeEditorContributions.ts b/src/vs/editor/browser/widget/codeEditorContributions.ts index 35bf94643b2..81ce555d74e 100644 --- a/src/vs/editor/browser/widget/codeEditorContributions.ts +++ b/src/vs/editor/browser/widget/codeEditorContributions.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { getWindow } from 'vs/base/browser/dom'; import { runWhenIdle } from 'vs/base/common/async'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Disposable, DisposableMap } from 'vs/base/common/lifecycle'; @@ -57,21 +58,21 @@ export class CodeEditorContributions extends Disposable { // AfterFirstRender // - these extensions will be instantiated at the latest 50ms after the first render. // - but if there is idle time, we will instantiate them sooner. - this._register(runWhenIdle(() => { + this._register(runWhenIdle(getWindow(this._editor.getDomNode()), () => { this._instantiateSome(EditorContributionInstantiation.AfterFirstRender); })); // BeforeFirstInteraction // - these extensions will be instantiated at the latest before a mouse or a keyboard event. // - but if there is idle time, we will instantiate them sooner. - this._register(runWhenIdle(() => { + this._register(runWhenIdle(getWindow(this._editor.getDomNode()), () => { this._instantiateSome(EditorContributionInstantiation.BeforeFirstInteraction); })); // Eventually // - these extensions will only be instantiated when there is idle time. // - since there is no guarantee that there will ever be idle time, we set a timeout of 5s here. - this._register(runWhenIdle(() => { + this._register(runWhenIdle(getWindow(this._editor.getDomNode()), () => { this._instantiateSome(EditorContributionInstantiation.Eventually); }, 5000)); } @@ -112,7 +113,7 @@ export class CodeEditorContributions extends Disposable { } public onAfterModelAttached(): void { - this._register(runWhenIdle(() => { + this._register(runWhenIdle(getWindow(this._editor?.getDomNode()), () => { this._instantiateSome(EditorContributionInstantiation.AfterFirstRender); }, 50)); } diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 414b6136d92..b4cd16d44bd 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1649,7 +1649,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE model, DOMLineBreaksComputerFactory.create(), MonospaceLineBreaksComputerFactory.create(this._configuration.options), - (callback) => dom.scheduleAtNextAnimationFrame(callback, dom.getWindow(this._domElement)), + (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(this._domElement), callback), this.languageConfigurationService, this._themeService, attachedView, diff --git a/src/vs/editor/common/model/textModelTokens.ts b/src/vs/editor/common/model/textModelTokens.ts index 0139d8b2055..0a1d02d46c2 100644 --- a/src/vs/editor/common/model/textModelTokens.ts +++ b/src/vs/editor/common/model/textModelTokens.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IdleDeadline, runWhenIdle } from 'vs/base/common/async'; +import { IdleDeadline, globalRunWhenIdle } from 'vs/base/common/async'; import { BugIndicatingError, onUnexpectedError } from 'vs/base/common/errors'; import { setTimeout0 } from 'vs/base/common/platform'; import { StopWatch } from 'vs/base/common/stopwatch'; @@ -462,7 +462,7 @@ export class DefaultBackgroundTokenizer implements IBackgroundTokenizer { } this._isScheduled = true; - runWhenIdle((deadline) => { + globalRunWhenIdle((deadline) => { this._isScheduled = false; this._backgroundTokenizeWithDeadline(deadline); diff --git a/src/vs/editor/contrib/codelens/browser/codeLensCache.ts b/src/vs/editor/contrib/codelens/browser/codeLensCache.ts index 00249b87bea..4f2bfcdb721 100644 --- a/src/vs/editor/contrib/codelens/browser/codeLensCache.ts +++ b/src/vs/editor/contrib/codelens/browser/codeLensCache.ts @@ -13,6 +13,7 @@ import { CodeLensModel } from 'vs/editor/contrib/codelens/browser/codelens'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope, StorageTarget, WillSaveStateReason } from 'vs/platform/storage/common/storage'; +import { $window } from 'vs/base/browser/window'; export const ICodeLensCache = createDecorator('ICodeLensCache'); @@ -52,7 +53,7 @@ export class CodeLensCache implements ICodeLensCache { // remove old data const oldkey = 'codelens/cache'; - runWhenIdle(() => storageService.remove(oldkey, StorageScope.WORKSPACE)); + runWhenIdle($window, () => storageService.remove(oldkey, StorageScope.WORKSPACE)); // restore lens data on start const key = 'codelens/cache2'; diff --git a/src/vs/editor/contrib/suggest/browser/suggestController.ts b/src/vs/editor/contrib/suggest/browser/suggestController.ts index 6450e989bce..7b8a542fa4f 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestController.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestController.ts @@ -45,6 +45,7 @@ import { ISelectedSuggestion, SuggestWidget } from './suggestWidget'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { basename, extname } from 'vs/base/common/resources'; import { hash } from 'vs/base/common/hash'; +import { getWindow } from 'vs/base/browser/dom'; // sticky suggest widget which doesn't disappear on focus out and such const _sticky = false @@ -145,7 +146,7 @@ export class SuggestController implements IEditorContribution { ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode); this._toDispose.add(this.model.onDidTrigger(() => ctxInsertMode.set(editor.getOption(EditorOption.suggest).insertMode))); - this.widget = this._toDispose.add(new IdleValue(() => { + this.widget = this._toDispose.add(new IdleValue(getWindow(editor.getDomNode()), () => { const widget = this._instantiationService.createInstance(SuggestWidget, this.editor); @@ -218,11 +219,11 @@ export class SuggestController implements IEditorContribution { })); // Wire up text overtyping capture - this._overtypingCapturer = this._toDispose.add(new IdleValue(() => { + this._overtypingCapturer = this._toDispose.add(new IdleValue(getWindow(editor.getDomNode()), () => { return this._toDispose.add(new OvertypingCapturer(this.editor, this.model)); })); - this._alternatives = this._toDispose.add(new IdleValue(() => { + this._alternatives = this._toDispose.add(new IdleValue(getWindow(editor.getDomNode()), () => { return this._toDispose.add(new SuggestAlternatives(this.editor, this._contextKeyService)); })); diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index aa78d74936a..37cca65b961 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -566,12 +566,12 @@ export class SuggestWidget implements IDisposable { this._onDidSelect.resume(); } - this._pendingLayout.value = dom.runAtThisOrScheduleAtNextAnimationFrame(() => { + this._pendingLayout.value = dom.runAtThisOrScheduleAtNextAnimationFrame(dom.getWindow(this.element.domNode), () => { this._pendingLayout.clear(); this._layout(this.element.size); // Reset focus border this._details.widget.domNode.classList.remove('focused'); - }, dom.getWindow(this.element.domNode)); + }); } focusSelected(): void { @@ -710,7 +710,7 @@ export class SuggestWidget implements IDisposable { } showDetails(loading: boolean): void { - this._pendingShowDetails.value = dom.runAtThisOrScheduleAtNextAnimationFrame(() => { + this._pendingShowDetails.value = dom.runAtThisOrScheduleAtNextAnimationFrame(dom.getWindow(this.element.domNode), () => { this._pendingShowDetails.clear(); this._details.show(); if (loading) { @@ -721,7 +721,7 @@ export class SuggestWidget implements IDisposable { this._positionDetails(); this.editor.focus(); this.element.domNode.classList.add('shows-details'); - }, dom.getWindow(this.element.domNode)); + }); } toggleExplainMode(): void { diff --git a/src/vs/platform/instantiation/common/instantiationService.ts b/src/vs/platform/instantiation/common/instantiationService.ts index f0db479e3c1..dee82758c0a 100644 --- a/src/vs/platform/instantiation/common/instantiationService.ts +++ b/src/vs/platform/instantiation/common/instantiationService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IdleValue } from 'vs/base/common/async'; +import { GlobalIdleValue } from 'vs/base/common/async'; import { Event } from 'vs/base/common/event'; import { illegalState } from 'vs/base/common/errors'; import { toDisposable } from 'vs/base/common/lifecycle'; @@ -255,7 +255,7 @@ export class InstantiationService implements IInstantiationService { // return "empty events" when the service isn't instantiated yet const earlyListeners = new Map>>>(); - const idle = new IdleValue(() => { + const idle = new GlobalIdleValue(() => { const result = child._createInstance(ctor, args, _trace); // early listeners that we kept are now being subscribed to diff --git a/src/vs/platform/storage/common/storage.ts b/src/vs/platform/storage/common/storage.ts index 174a3038aaa..04dbf785488 100644 --- a/src/vs/platform/storage/common/storage.ts +++ b/src/vs/platform/storage/common/storage.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Promises, RunOnceScheduler, runWhenIdle } from 'vs/base/common/async'; +import { Promises, RunOnceScheduler, globalRunWhenIdle } from 'vs/base/common/async'; import { Emitter, Event, PauseableEmitter } from 'vs/base/common/event'; import { Disposable, DisposableStore, dispose, MutableDisposable } from 'vs/base/common/lifecycle'; import { mark } from 'vs/base/common/performance'; @@ -343,7 +343,7 @@ export abstract class AbstractStorageService extends Disposable implements IStor } private doFlushWhenIdle(): void { - this.runFlushWhenIdle.value = runWhenIdle(() => { + this.runFlushWhenIdle.value = globalRunWhenIdle(() => { if (this.shouldFlushWhenIdle()) { this.flush(); } diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 330cdc3eec4..1b31558cfc1 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -562,7 +562,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { if (!this.toRender) { this.toRender = changed; - this.delayedRender.value = runAtThisOrScheduleAtNextAnimationFrame(() => { + this.delayedRender.value = runAtThisOrScheduleAtNextAnimationFrame(mainWindow, () => { this.delayedRender.clear(); const toRender = this.toRender; @@ -570,7 +570,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { if (toRender) { this.doRenderNow(); } - }, mainWindow); + }); } else { this.toRender.combine(changed); } diff --git a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts index 7b779017488..8d0f91706b7 100644 --- a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts @@ -1032,7 +1032,7 @@ export class MultiEditorTabsControl extends EditorTabsControl { // Fixes https://github.com/microsoft/vscode/issues/18733 tab.classList.add('dragged'); - scheduleAtNextAnimationFrame(() => tab.classList.remove('dragged'), getWindow(tab)); + scheduleAtNextAnimationFrame(getWindow(tab), () => tab.classList.remove('dragged')); })); // Drop support @@ -1616,9 +1616,9 @@ export class MultiEditorTabsControl extends EditorTabsControl { let scheduledLayout: IDisposable; if (this.lifecycleService.phase >= LifecyclePhase.Restored) { - scheduledLayout = scheduleAtNextAnimationFrame(layoutFunction, getWindow(this.tabsContainer)); + scheduledLayout = scheduleAtNextAnimationFrame(getWindow(this.tabsContainer), layoutFunction); } else { - scheduledLayout = runWhenIdle(layoutFunction); + scheduledLayout = runWhenIdle(getWindow(this.tabsContainer), layoutFunction); } this.layoutScheduler.value = { options, dispose: () => scheduledLayout.dispose() }; diff --git a/src/vs/workbench/browser/parts/globalCompositeBar.ts b/src/vs/workbench/browser/parts/globalCompositeBar.ts index b6e16473762..c37227778d0 100644 --- a/src/vs/workbench/browser/parts/globalCompositeBar.ts +++ b/src/vs/workbench/browser/parts/globalCompositeBar.ts @@ -43,6 +43,7 @@ import { DEFAULT_ICON } from 'vs/workbench/services/userDataProfile/common/userD import { isString } from 'vs/base/common/types'; import { KeyCode } from 'vs/base/common/keyCodes'; import { ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND } from 'vs/workbench/common/theme'; +import { $window } from 'vs/base/browser/window'; export class GlobalCompositeBar extends Disposable { @@ -354,7 +355,7 @@ export class AccountsActivityActionViewItem extends AbstractGlobalActivityAction if (this._store.isDisposed) { return; } - const disposable = this._register(runWhenIdle(async () => { + const disposable = this._register(runWhenIdle($window, async () => { await this.doInitialize(); disposable.dispose(); })); diff --git a/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts b/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts index fb0f7f5d318..d9b8e5fa9fb 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts @@ -150,7 +150,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast // (see also https://github.com/microsoft/vscode/issues/107935) const itemDisposables = new DisposableStore(); this.mapNotificationToDisposable.set(item, itemDisposables); - itemDisposables.add(scheduleAtNextAnimationFrame(() => this.doAddToast(item, itemDisposables), getWindow(this.container))); + itemDisposables.add(scheduleAtNextAnimationFrame(getWindow(this.container), () => this.doAddToast(item, itemDisposables))); } private doAddToast(item: INotificationViewItem, itemDisposables: DisposableStore): void { diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 4a13d94c66a..56225a3e363 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -451,7 +451,7 @@ export class Workbench extends Layout { // Set lifecycle phase to `Eventually` after a short delay and when idle (min 2.5sec, max 5sec) const eventuallyPhaseScheduler = this._register(new RunOnceScheduler(() => { - this._register(runWhenIdle(() => lifecycleService.phase = LifecyclePhase.Eventually, 2500)); + this._register(runWhenIdle(mainWindow, () => lifecycleService.phase = LifecyclePhase.Eventually, 2500)); }, 2500)); eventuallyPhaseScheduler.schedule(); }) diff --git a/src/vs/workbench/common/contributions.ts b/src/vs/workbench/common/contributions.ts index 2b8ebeeac55..942bf1c37bd 100644 --- a/src/vs/workbench/common/contributions.ts +++ b/src/vs/workbench/common/contributions.ts @@ -6,7 +6,7 @@ import { IInstantiationService, IConstructorSignature, ServicesAccessor, BrandedService } from 'vs/platform/instantiation/common/instantiation'; import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; -import { runWhenIdle, IdleDeadline, DeferredPromise } from 'vs/base/common/async'; +import { globalRunWhenIdle, IdleDeadline, DeferredPromise } from 'vs/base/common/async'; import { mark } from 'vs/base/common/performance'; import { ILogService } from 'vs/platform/log/common/log'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -155,7 +155,7 @@ class WorkbenchContributionsRegistry implements IWorkbenchContributionsRegistry this.safeCreateContribution(instantiationService, logService, environmentService, contribution, phase); if (idle.timeRemaining() < 1) { // time is up -> reschedule - runWhenIdle(instantiateSome, forcedTimeout); + globalRunWhenIdle(instantiateSome, forcedTimeout); break; } } @@ -169,7 +169,7 @@ class WorkbenchContributionsRegistry implements IWorkbenchContributionsRegistry } }; - runWhenIdle(instantiateSome, forcedTimeout); + globalRunWhenIdle(instantiateSome, forcedTimeout); } private safeCreateContribution(instantiationService: IInstantiationService, logService: ILogService, environmentService: IEnvironmentService, contribution: IConstructorSignature, phase: LifecyclePhase): void { diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index c7f1c97fd14..a42a9dfa3b3 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -455,10 +455,10 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer { + const disposable = templateData.elementDisposables.add(dom.scheduleAtNextAnimationFrame(dom.getWindow(templateData.value), () => { disposable.dispose(); this._onDidChangeItemHeight.fire({ element, height: newHeight }); - }, dom.getWindow(templateData.value))); + })); } } @@ -493,10 +493,10 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer { + const disposable = templateData.elementDisposables.add(dom.scheduleAtNextAnimationFrame(dom.getWindow(templateData.value), () => { disposable.dispose(); this._onDidChangeItemHeight.fire({ element, height: newHeight }); - }, dom.getWindow(templateData.value))); + })); } } diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index c6f79e430df..9a21a8da6ca 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -404,10 +404,10 @@ export class ChatWidget extends Disposable implements IChatWidget { // Consider the tree to be scrolled all the way down if it is within 2px of the bottom. const lastElementWasVisible = this.tree.scrollTop + this.tree.renderHeight >= this.previousTreeScrollHeight - 2; if (lastElementWasVisible) { - dom.scheduleAtNextAnimationFrame(() => { + dom.scheduleAtNextAnimationFrame(dom.getWindow(this.listContainer), () => { // Can't set scrollTop during this event listener, the list might overwrite the change revealLastElement(this.tree); - }, dom.getWindow(this.listContainer), 0); + }, 0); } } @@ -625,7 +625,7 @@ export class ChatWidget extends Disposable implements IChatWidget { if (!this._dynamicMessageLayoutData?.enabled) { return; } - mutableDisposable.value = dom.scheduleAtNextAnimationFrame(() => { + mutableDisposable.value = dom.scheduleAtNextAnimationFrame(dom.getWindow(this.listContainer), () => { if (!e.scrollTopChanged || e.heightChanged || e.scrollHeightChanged) { return; } @@ -640,7 +640,7 @@ export class ChatWidget extends Disposable implements IChatWidget { const inputPartHeight = this.inputPart.layout(possibleMaxHeight, width); const newHeight = Math.min(renderHeight + diff, possibleMaxHeight - inputPartHeight); this.layout(newHeight + inputPartHeight, width); - }, dom.getWindow(this.listContainer)); + }); })); } diff --git a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts index 3e7bdeec9c0..d753d9a7b4d 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsTree.ts @@ -24,6 +24,7 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/tex import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget'; import { IOutlineComparator, OutlineConfigKeys } from 'vs/workbench/services/outline/browser/outline'; import { ThemeIcon } from 'vs/base/common/themables'; +import { mainWindow } from 'vs/base/browser/window'; export type DocumentSymbolItem = OutlineGroup | OutlineElement; @@ -251,7 +252,7 @@ export class DocumentSymbolFilter implements ITreeFilter { export class DocumentSymbolComparator implements IOutlineComparator { - private readonly _collator = new IdleValue(() => new Intl.Collator(undefined, { numeric: true })); + private readonly _collator = new IdleValue(mainWindow, () => new Intl.Collator(undefined, { numeric: true })); compareByPosition(a: DocumentSymbolItem, b: DocumentSymbolItem): number { if (a instanceof OutlineGroup && b instanceof OutlineGroup) { diff --git a/src/vs/workbench/contrib/comments/browser/commentNode.ts b/src/vs/workbench/contrib/comments/browser/commentNode.ts index 65ad313fff7..5a4066e7a8d 100644 --- a/src/vs/workbench/contrib/comments/browser/commentNode.ts +++ b/src/vs/workbench/contrib/comments/browser/commentNode.ts @@ -170,7 +170,7 @@ export class CommentNode extends Disposable { this._scrollable = new Scrollable({ forceIntegerValues: true, smoothScrollDuration: 125, - scheduleAtNextAnimationFrame: cb => dom.scheduleAtNextAnimationFrame(cb, dom.getWindow(container)) + scheduleAtNextAnimationFrame: cb => dom.scheduleAtNextAnimationFrame(dom.getWindow(container), cb) }); this._scrollableElement = this._register(new SmoothScrollableElement(body, { horizontal: ScrollbarVisibility.Visible, @@ -486,10 +486,10 @@ export class CommentNode extends Disposable { this._commentEditor.layout({ width: container.clientWidth - 14, height: this._editorHeight }); this._commentEditor.focus(); - dom.scheduleAtNextAnimationFrame(() => { + dom.scheduleAtNextAnimationFrame(dom.getWindow(editContainer), () => { this._commentEditor!.layout({ width: container.clientWidth - 14, height: this._editorHeight }); this._commentEditor!.focus(); - }, dom.getWindow(editContainer)); + }); const lastLine = this._commentEditorModel.getLineCount(); const lastColumn = this._commentEditorModel.getLineLength(lastLine) + 1; diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts b/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts index 4996b79f268..52b0931a404 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts @@ -37,6 +37,7 @@ import { OutlineEntry } from 'vs/workbench/contrib/notebook/browser/viewModel/Ou import { CancellationToken } from 'vs/base/common/cancellation'; import { IModelDeltaDecoration } from 'vs/editor/common/model'; import { Range } from 'vs/editor/common/core/range'; +import { mainWindow } from 'vs/base/browser/window'; class NotebookOutlineTemplate { @@ -177,7 +178,7 @@ class NotebookQuickPickProvider implements IQuickPickDataSource { class NotebookComparator implements IOutlineComparator { - private readonly _collator = new IdleValue(() => new Intl.Collator(undefined, { numeric: true })); + private readonly _collator = new IdleValue(mainWindow, () => new Intl.Collator(undefined, { numeric: true })); compareByPosition(a: OutlineEntry, b: OutlineEntry): number { return a.index - b.index; diff --git a/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts b/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts index 92327e752c6..bee5a8db7c4 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts @@ -971,7 +971,7 @@ export class DeletedElement extends SingleSideDiffElement { } layout(state: IDiffElementLayoutState) { - DOM.scheduleAtNextAnimationFrame(() => { + DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this._diffEditorContainer), () => { if (state.editorHeight || state.outerWidth) { this._editor.layout({ width: this.cell.getComputedCellContainerWidth(this.notebookEditor.getLayoutInfo(), false, false), @@ -998,7 +998,7 @@ export class DeletedElement extends SingleSideDiffElement { } this.layoutNotebookCell(); - }, DOM.getWindow(this._diffEditorContainer)); + }); } _buildOutputRendererContainer() { @@ -1174,7 +1174,7 @@ export class InsertElement extends SingleSideDiffElement { } layout(state: IDiffElementLayoutState) { - DOM.scheduleAtNextAnimationFrame(() => { + DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this._diffEditorContainer), () => { if (state.editorHeight || state.outerWidth) { this._editor.layout({ width: this.cell.getComputedCellContainerWidth(this.notebookEditor.getLayoutInfo(), false, false), @@ -1201,7 +1201,7 @@ export class InsertElement extends SingleSideDiffElement { if (this._diagonalFill) { this._diagonalFill.style.height = `${this.cell.layoutInfo.editorHeight + this.cell.layoutInfo.editorMargin + this.cell.layoutInfo.metadataStatusHeight + this.cell.layoutInfo.metadataHeight + this.cell.layoutInfo.outputTotalHeight + this.cell.layoutInfo.outputStatusHeight}px`; } - }, DOM.getWindow(this._diffEditorContainer)); + }); } override dispose() { @@ -1591,7 +1591,7 @@ export class ModifiedElement extends AbstractElementRenderer { } layout(state: IDiffElementLayoutState) { - DOM.scheduleAtNextAnimationFrame(() => { + DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this._diffEditorContainer), () => { if (state.editorHeight) { this._editorContainer.style.height = `${this.cell.layoutInfo.editorHeight}px`; this._editor!.layout({ @@ -1626,7 +1626,7 @@ export class ModifiedElement extends AbstractElementRenderer { } this.layoutNotebookCell(); - }, DOM.getWindow(this._diffEditorContainer)); + }); } override dispose() { diff --git a/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.ts b/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.ts index 35c1e3cf692..5b87a0024a2 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.ts @@ -447,7 +447,7 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD private _attachModel() { this._eventDispatcher = new NotebookDiffEditorEventDispatcher(); const updateInsets = () => { - DOM.scheduleAtNextAnimationFrame(() => { + DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this._listViewContainer), () => { if (this._isDisposed) { return; } @@ -463,7 +463,7 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD return diffElement.original; }, DiffSide.Original); } - }, DOM.getWindow(this._listViewContainer)); + }); }; this._localStore.add(this._list.onDidChangeContentHeight(() => { @@ -761,9 +761,9 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD const webview = diffSide === DiffSide.Modified ? this._modifiedWebview : this._originalWebview; - DOM.scheduleAtNextAnimationFrame(() => { + DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this._listViewContainer), () => { webview?.ackHeight([{ cellId: cellInfo.cellId, outputId, height }]); - }, DOM.getWindow(this._listViewContainer), 10); + }, 10); } private pendingLayouts = new WeakMap(); @@ -779,12 +779,12 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD } let r: () => void; - const layoutDisposable = DOM.scheduleAtNextAnimationFrame(() => { + const layoutDisposable = DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this._listViewContainer), () => { this.pendingLayouts.delete(cell); relayout(cell, height); r(); - }, DOM.getWindow(this._listViewContainer)); + }); this.pendingLayouts.set(cell, toDisposable(() => { layoutDisposable.dispose(); diff --git a/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffOverviewRuler.ts b/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffOverviewRuler.ts index 57938e24695..71032920fcb 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffOverviewRuler.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffOverviewRuler.ts @@ -114,7 +114,7 @@ export class NotebookDiffOverviewRuler extends Themable { private _scheduleRender(): void { if (this._renderAnimationFrame === null) { - this._renderAnimationFrame = DOM.runAtThisOrScheduleAtNextAnimationFrame(this._onRenderScheduled.bind(this), DOM.getWindow(this._domNode.domNode), 16); + this._renderAnimationFrame = DOM.runAtThisOrScheduleAtNextAnimationFrame(DOM.getWindow(this._domNode.domNode), this._onRenderScheduled.bind(this), 16); } } diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index f1a902a7271..bdacfa5ffd6 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -1154,7 +1154,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD } this._backgroundMarkdownRenderRunning = true; - runWhenIdle((deadline) => { + runWhenIdle(DOM.getWindow(this._body), (deadline) => { this._backgroundMarkdownRenderingWithDeadline(deadline); }); } @@ -1449,10 +1449,10 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD } hasPendingChangeContentHeight = true; - this._localStore.add(DOM.scheduleAtNextAnimationFrame(() => { + this._localStore.add(DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this._body), () => { hasPendingChangeContentHeight = false; this._updateScrollHeight(); - }, DOM.getWindow(this._body), 100)); + }, 100)); })); this._localStore.add(this._list.onDidRemoveOutputs(outputs => { @@ -2257,7 +2257,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD }; if (this._list.inRenderingTransaction) { - const layoutDisposable = DOM.scheduleAtNextAnimationFrame(doLayout, DOM.getWindow(this._body)); + const layoutDisposable = DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this._body), doLayout); this._pendingLayouts?.set(cell, toDisposable(() => { layoutDisposable.dispose(); @@ -2964,14 +2964,14 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD this._pendingOutputHeightAcks.set(outputId, { cellId: cellInfo.cellId, outputId, height }); if (wasEmpty) { - DOM.scheduleAtNextAnimationFrame(() => { + DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this._body), () => { this._debug('ack height'); this._updateScrollHeight(); this._webview?.ackHeight([...this._pendingOutputHeightAcks.values()]); this._pendingOutputHeightAcks.clear(); - }, DOM.getWindow(this._body), -1); // -1 priority because this depends on calls to layoutNotebookCell, and that may be called multiple times before this runs + }, -1); // -1 priority because this depends on calls to layoutNotebookCell, and that may be called multiple times before this runs } } diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookKernelServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookKernelServiceImpl.ts index 7eb95b9c062..da098ab2422 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookKernelServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookKernelServiceImpl.ts @@ -17,6 +17,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IAction } from 'vs/base/common/actions'; import { MarshalledId } from 'vs/base/common/marshallingIds'; import { Schemas } from 'vs/base/common/network'; +import { $window } from 'vs/base/browser/window'; class KernelInfo { @@ -168,7 +169,7 @@ export class NotebookKernelService extends Disposable implements INotebookKernel private _persistMementos(): void { this._persistSoonHandle?.dispose(); - this._persistSoonHandle = runWhenIdle(() => { + this._persistSoonHandle = runWhenIdle($window, () => { this._storageService.store(NotebookKernelService._storageNotebookBinding, JSON.stringify(this._notebookBindings), StorageScope.WORKSPACE, StorageTarget.MACHINE); }, 100); } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellPart.ts b/src/vs/workbench/contrib/notebook/browser/view/cellPart.ts index 32dc2032748..af28b7b63e7 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellPart.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellPart.ts @@ -158,11 +158,11 @@ export class CellPartsCollection extends Disposable { part.renderCell(element); } - this._scheduledOverlayRendering.value = DOM.modify(() => { + this._scheduledOverlayRendering.value = DOM.modify(this.targetWindow, () => { for (const part of this.overlayParts) { part.renderCell(element); } - }, this.targetWindow); + }); } unrenderCell(element: ICellViewModel): void { @@ -200,11 +200,11 @@ export class CellPartsCollection extends Disposable { part.updateState(viewCell, e); } - this._scheduledOverlayUpdateState.value = DOM.modify(() => { + this._scheduledOverlayUpdateState.value = DOM.modify(this.targetWindow, () => { for (const part of this.overlayParts) { part.updateState(viewCell, e); } - }, this.targetWindow); + }); } updateForExecutionState(viewCell: ICellViewModel, e: ICellExecutionStateChangedEvent) { @@ -212,10 +212,10 @@ export class CellPartsCollection extends Disposable { part.updateForExecutionState(viewCell, e); } - this._scheduledOverlayUpdateExecutionState.value = DOM.modify(() => { + this._scheduledOverlayUpdateExecutionState.value = DOM.modify(this.targetWindow, () => { for (const part of this.overlayParts) { part.updateForExecutionState(viewCell, e); } - }, this.targetWindow); + }); } } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts index 9f727ebfe88..31f4337c70a 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts @@ -144,9 +144,9 @@ export class CodeCell extends Disposable { private updateForLayout(): void { this._pendingLayout?.dispose(); - this._pendingLayout = DOM.modify(() => { + this._pendingLayout = DOM.modify(DOM.getWindow(this.templateData.container), () => { this.cellParts.updateInternalLayoutNow(this.viewCell); - }, DOM.getWindow(this.templateData.container)); + }); } private updateForOutputHover() { diff --git a/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts b/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts index 827a3195e21..bd6e7b68c7c 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/notebookCellList.ts @@ -282,17 +282,17 @@ export class NotebookCellList extends WorkbenchList implements ID this._localDisposableStore.add(this.view.onDidChangeContentHeight(() => { if (this._isInLayout) { - DOM.scheduleAtNextAnimationFrame(() => { + DOM.scheduleAtNextAnimationFrame(DOM.getWindow(container), () => { updateVisibleRanges(); - }, DOM.getWindow(container)); + }); } updateVisibleRanges(); })); this._localDisposableStore.add(this.view.onDidScroll(() => { if (this._isInLayout) { - DOM.scheduleAtNextAnimationFrame(() => { + DOM.scheduleAtNextAnimationFrame(DOM.getWindow(container), () => { updateVisibleRanges(); - }, DOM.getWindow(container)); + }); } updateVisibleRanges(); })); @@ -358,13 +358,13 @@ export class NotebookCellList extends WorkbenchList implements ID if (e.synchronous) { this._updateElementsInWebview(viewDiffs); } else { - this._viewModelStore.add(DOM.scheduleAtNextAnimationFrame(() => { + this._viewModelStore.add(DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this.rowsContainer), () => { if (this._isDisposed) { return; } this._updateElementsInWebview(viewDiffs); - }, DOM.getWindow(this.rowsContainer))); + })); } })); diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index 0816ebffe43..fe504529b07 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -6,7 +6,7 @@ import * as osPath from 'vs/base/common/path'; import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; import { coalesce } from 'vs/base/common/arrays'; -import { DeferredPromise, runWhenIdle } from 'vs/base/common/async'; +import { DeferredPromise, globalRunWhenIdle } from 'vs/base/common/async'; import { decodeBase64 } from 'vs/base/common/buffer'; import { Emitter, Event } from 'vs/base/common/event'; import { getExtensionForMimeType } from 'vs/base/common/mime'; @@ -1435,7 +1435,7 @@ export class BackLayerWebView extends Themable { return; } - this.pendingWebviewIdleCreationRequest.set(content.source, runWhenIdle(() => { + this.pendingWebviewIdleCreationRequest.set(content.source, globalRunWhenIdle(() => { const { message, renderer, transfer: transferable } = this._createOutputCreationMessage(cellInfo, content, cellTop, offset, true, true); this._sendMessageToWebview(message, transferable); this.pendingWebviewIdleInsetMapping.set(content.source, { outputId: message.outputId, versionId: content.source.model.versionId, cellInfo: cellInfo, renderer, cachedCreation: message }); diff --git a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts index 390ed06f677..60950c7aea6 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts @@ -113,9 +113,9 @@ export class NotebookEditorContextKeys { return c.model.onDidChangeOutputs(() => { layoutDisposable.clear(); - layoutDisposable.add(DOM.scheduleAtNextAnimationFrame(() => { + layoutDisposable.add(DOM.scheduleAtNextAnimationFrame(DOM.getWindow(this._editor.getDomNode()), () => { recomputeOutputsExistence(); - }, DOM.getWindow(this._editor.getDomNode()))); + })); }); }; diff --git a/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts b/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts index 5c79e50d35a..f083842b4c5 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts @@ -17,6 +17,7 @@ import { relativePath } from 'vs/base/common/resources'; import { isObject } from 'vs/base/common/types'; import { tail } from 'vs/base/common/arrays'; import { Iterable } from 'vs/base/common/iterator'; +import { $window } from 'vs/base/browser/window'; class SnippetBodyInsights { @@ -117,7 +118,7 @@ export class Snippet { readonly extensionId?: ExtensionIdentifier, ) { this.prefixLow = prefix.toLowerCase(); - this._bodyInsights = new IdleValue(() => new SnippetBodyInsights(this.body)); + this._bodyInsights = new IdleValue($window, () => new SnippetBodyInsights(this.body)); } get codeSnippet(): string { diff --git a/src/vs/workbench/contrib/splash/browser/partsSplash.ts b/src/vs/workbench/contrib/splash/browser/partsSplash.ts index 08fd7e5a8d5..1683602cde2 100644 --- a/src/vs/workbench/contrib/splash/browser/partsSplash.ts +++ b/src/vs/workbench/contrib/splash/browser/partsSplash.ts @@ -20,6 +20,7 @@ import * as perf from 'vs/base/common/performance'; import { assertIsDefined } from 'vs/base/common/types'; import { runWhenIdle } from 'vs/base/common/async'; import { ISplashStorageService } from 'vs/workbench/contrib/splash/browser/splash'; +import { mainWindow } from 'vs/base/browser/window'; export class PartsSplash { @@ -45,7 +46,7 @@ export class PartsSplash { let lastIdleSchedule: IDisposable | undefined; Event.any(onDidChangeFullscreen, editorGroupsService.mainPart.onDidLayout, _themeService.onDidColorThemeChange)(() => { lastIdleSchedule?.dispose(); - lastIdleSchedule = runWhenIdle(() => this._savePartsSplash(), 800); + lastIdleSchedule = runWhenIdle(mainWindow, () => this._savePartsSplash(), 800); }, undefined, this._disposables); _configService.onDidChangeConfiguration(e => { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index c39f5ef43b9..002d9346087 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -395,7 +395,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce } // Report the latency to the pty host when idle - runWhenIdle(() => { + runWhenIdle($window, () => { this.backend?.getLatency().then(measurements => { this._logService.info(`Latency measurements for ${this.remoteAuthority ?? 'local'} backend\n${measurements.map(e => `${e.label}: ${e.latency.toFixed(2)}ms`).join('\n')}`); }); diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts index 3ec8a0f746f..9fc50899fe9 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts @@ -11,6 +11,7 @@ import type { Terminal, IMarker, ITerminalAddon, IDecoration } from '@xterm/xter import { timeout } from 'vs/base/common/async'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { TERMINAL_OVERVIEW_RULER_CURSOR_FOREGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; +import { getWindow } from 'vs/base/browser/dom'; enum Boundary { Top, @@ -241,7 +242,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe element.classList.add('terminal-scroll-highlight', 'terminal-scroll-highlight-outline'); } if (this._terminal?.element) { - element.style.marginLeft = `-${getComputedStyle(this._terminal.element).paddingLeft}`; + element.style.marginLeft = `-${getWindow(this._terminal.element).getComputedStyle(this._terminal.element).paddingLeft}`; } } }); diff --git a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts index 072fa071e36..c8439af52c8 100644 --- a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts +++ b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts @@ -1534,7 +1534,7 @@ class TerminalMessagePeek extends Disposable implements IPeekOutputRenderer { private attachTerminalToDom(terminal: IDetachedTerminalInstance) { terminal.xterm.write('\x1b[?25l'); // hide cursor - dom.scheduleAtNextAnimationFrame(() => this.layoutTerminal(terminal), dom.getWindow(this.container)); + dom.scheduleAtNextAnimationFrame(dom.getWindow(this.container), () => this.layoutTerminal(terminal)); terminal.attachToElement(this.container, { enableGpu: false }); } diff --git a/src/vs/workbench/contrib/url/browser/trustedDomainsValidator.ts b/src/vs/workbench/contrib/url/browser/trustedDomainsValidator.ts index 075c0882f9f..4bc6a9ae018 100644 --- a/src/vs/workbench/contrib/url/browser/trustedDomainsValidator.ts +++ b/src/vs/workbench/contrib/url/browser/trustedDomainsValidator.ts @@ -24,6 +24,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { testUrlMatchesGlob } from 'vs/workbench/contrib/url/common/urlGlob'; import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { $window } from 'vs/base/browser/window'; export class OpenerValidatorContributions implements IWorkbenchContribution { @@ -47,19 +48,19 @@ export class OpenerValidatorContributions implements IWorkbenchContribution { ) { this._openerService.registerValidator({ shouldOpen: (uri, options) => this.validateLink(uri, options) }); - this._readAuthenticationTrustedDomainsResult = new IdleValue(() => + this._readAuthenticationTrustedDomainsResult = new IdleValue($window, () => this._instantiationService.invokeFunction(readAuthenticationTrustedDomains)); this._authenticationService.onDidRegisterAuthenticationProvider(() => { this._readAuthenticationTrustedDomainsResult?.dispose(); - this._readAuthenticationTrustedDomainsResult = new IdleValue(() => + this._readAuthenticationTrustedDomainsResult = new IdleValue($window, () => this._instantiationService.invokeFunction(readAuthenticationTrustedDomains)); }); - this._readWorkspaceTrustedDomainsResult = new IdleValue(() => + this._readWorkspaceTrustedDomainsResult = new IdleValue($window, () => this._instantiationService.invokeFunction(readWorkspaceTrustedDomains)); this._workspaceContextService.onDidChangeWorkspaceFolders(() => { this._readWorkspaceTrustedDomainsResult?.dispose(); - this._readWorkspaceTrustedDomainsResult = new IdleValue(() => + this._readWorkspaceTrustedDomainsResult = new IdleValue($window, () => this._instantiationService.invokeFunction(readWorkspaceTrustedDomains)); }); } diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 6ab7684c47a..e2a14ad1b94 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -45,6 +45,7 @@ import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userData import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; +import { $window } from 'vs/base/browser/window'; function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined { return (userDataProfile.isDefault || userDataProfile.useDefaultFlags?.settings) @@ -576,7 +577,7 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat if (!this.localUserConfiguration.hasTasksLoaded) { // Reload local user configuration again to load user tasks - this._register(runWhenIdle(() => this.reloadLocalUserConfiguration(false, this._configuration.localUserConfiguration))); + this._register(runWhenIdle($window, () => this.reloadLocalUserConfiguration(false, this._configuration.localUserConfiguration))); } } diff --git a/src/vs/workbench/services/extensions/electron-sandbox/nativeExtensionService.ts b/src/vs/workbench/services/extensions/electron-sandbox/nativeExtensionService.ts index f6a4677fb9c..a56790c0f88 100644 --- a/src/vs/workbench/services/extensions/electron-sandbox/nativeExtensionService.ts +++ b/src/vs/workbench/services/extensions/electron-sandbox/nativeExtensionService.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { $window } from 'vs/base/browser/window'; import { runWhenIdle } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Schemas } from 'vs/base/common/network'; @@ -134,7 +135,7 @@ export class NativeExtensionService extends AbstractExtensionService implements // see https://github.com/microsoft/vscode/issues/41322 lifecycleService.when(LifecyclePhase.Ready).then(() => { // reschedule to ensure this runs after restoring viewlets, panels, and editors - runWhenIdle(() => { + runWhenIdle($window, () => { this._initialize(); }, 50 /*max delay*/); }); diff --git a/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts b/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts index 9e9594a25f4..7043019fd1b 100644 --- a/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts +++ b/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts @@ -16,7 +16,7 @@ import { URI } from 'vs/base/common/uri'; import { isWeb } from 'vs/base/common/platform'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { ResourceGlobMatcher } from 'vs/workbench/common/resources'; -import { IdleValue } from 'vs/base/common/async'; +import { GlobalIdleValue } from 'vs/base/common/async'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ResourceMap } from 'vs/base/common/map'; @@ -108,8 +108,8 @@ export class FilesConfigurationService extends Disposable implements IFilesConfi private currentHotExitConfig: string; - private readonly readonlyIncludeMatcher = this._register(new IdleValue(() => this.createReadonlyMatcher(FILES_READONLY_INCLUDE_CONFIG))); - private readonly readonlyExcludeMatcher = this._register(new IdleValue(() => this.createReadonlyMatcher(FILES_READONLY_EXCLUDE_CONFIG))); + private readonly readonlyIncludeMatcher = this._register(new GlobalIdleValue(() => this.createReadonlyMatcher(FILES_READONLY_INCLUDE_CONFIG))); + private readonly readonlyExcludeMatcher = this._register(new GlobalIdleValue(() => this.createReadonlyMatcher(FILES_READONLY_EXCLUDE_CONFIG))); private configuredReadonlyFromPermissions: boolean | undefined; private readonly sessionReadonlyOverrides = new ResourceMap(resource => this.uriIdentityService.extUri.getComparisonKey(resource)); diff --git a/src/vs/workbench/services/history/browser/historyService.ts b/src/vs/workbench/services/history/browser/historyService.ts index dd1dd1797e3..4e65f5db377 100644 --- a/src/vs/workbench/services/history/browser/historyService.ts +++ b/src/vs/workbench/services/history/browser/historyService.ts @@ -34,6 +34,7 @@ import { IPathService } from 'vs/workbench/services/path/common/pathService'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { ILogService, LogLevel } from 'vs/platform/log/common/log'; +import { mainWindow } from 'vs/base/browser/window'; export class HistoryService extends Disposable implements IHistoryService { @@ -752,7 +753,7 @@ export class HistoryService extends Disposable implements IHistoryService { private readonly editorHistoryListeners = new Map(); - private readonly resourceExcludeMatcher = this._register(new IdleValue(() => { + private readonly resourceExcludeMatcher = this._register(new IdleValue(mainWindow, () => { const matcher = this._register(this.instantiationService.createInstance( ResourceGlobMatcher, root => getExcludes(root ? this.configurationService.getValue({ resource: root }) : this.configurationService.getValue()) || Object.create(null), diff --git a/src/vs/workbench/services/suggest/browser/simpleSuggestWidget.ts b/src/vs/workbench/services/suggest/browser/simpleSuggestWidget.ts index f3e8d1c542c..2f4d72e7f5b 100644 --- a/src/vs/workbench/services/suggest/browser/simpleSuggestWidget.ts +++ b/src/vs/workbench/services/suggest/browser/simpleSuggestWidget.ts @@ -251,12 +251,12 @@ export class SimpleSuggestWidget implements IDisposable { // this._onDidSelect.resume(); } - this._pendingLayout.value = dom.runAtThisOrScheduleAtNextAnimationFrame(() => { + this._pendingLayout.value = dom.runAtThisOrScheduleAtNextAnimationFrame(dom.getWindow(this.element.domNode), () => { this._pendingLayout.clear(); this._layout(this.element.size); // Reset focus border // this._details.widget.domNode.classList.remove('focused'); - }, dom.getWindow(this.element.domNode)); + }); } setLineContext(lineContext: LineContext): void { diff --git a/src/vs/workbench/services/timer/browser/timerService.ts b/src/vs/workbench/services/timer/browser/timerService.ts index d70ec4df70a..28d247f2871 100644 --- a/src/vs/workbench/services/timer/browser/timerService.ts +++ b/src/vs/workbench/services/timer/browser/timerService.ts @@ -544,6 +544,7 @@ export abstract class AbstractTimerService implements ITimerService { const t1 = performance.now(); fib(24); const value = Math.round(performance.now() - t1); + // eslint-disable-next-line no-restricted-globals postMessage({ value: tooSlow ? -1 : value }); }).toString(); diff --git a/src/vs/workbench/services/userActivity/common/userActivityService.ts b/src/vs/workbench/services/userActivity/common/userActivityService.ts index c632b849ff5..d9e24a6eef4 100644 --- a/src/vs/workbench/services/userActivity/common/userActivityService.ts +++ b/src/vs/workbench/services/userActivity/common/userActivityService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { RunOnceScheduler, runWhenIdle } from 'vs/base/common/async'; +import { RunOnceScheduler, globalRunWhenIdle } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -60,7 +60,7 @@ export class UserActivityService extends Disposable implements IUserActivityServ constructor(@IInstantiationService instantiationService: IInstantiationService) { super(); - this._register(runWhenIdle(() => userActivityRegistry.take(this, instantiationService))); + this._register(globalRunWhenIdle(() => userActivityRegistry.take(this, instantiationService))); } /** @inheritdoc */ diff --git a/src/vs/workbench/services/workingCopy/common/workingCopyHistoryTracker.ts b/src/vs/workbench/services/workingCopy/common/workingCopyHistoryTracker.ts index 7e3d7a7c2b4..aecdd02b3f6 100644 --- a/src/vs/workbench/services/workingCopy/common/workingCopyHistoryTracker.ts +++ b/src/vs/workbench/services/workingCopy/common/workingCopyHistoryTracker.ts @@ -37,7 +37,7 @@ export class WorkingCopyHistoryTracker extends Disposable implements IWorkbenchC private readonly limiter = this._register(new Limiter(MAX_PARALLEL_HISTORY_IO_OPS)); - private readonly resourceExcludeMatcher = this._register(new IdleValue(() => { + private readonly resourceExcludeMatcher = this._register(new IdleValue(globalThis, () => { const matcher = this._register(new ResourceGlobMatcher( root => this.configurationService.getValue(WorkingCopyHistoryTracker.SETTINGS.EXCLUDES, { resource: root }), event => event.affectsConfiguration(WorkingCopyHistoryTracker.SETTINGS.EXCLUDES), From b657ad16dcc8ad7d279d8e40a100a71fdf7720a6 Mon Sep 17 00:00:00 2001 From: Marcus Revaj Date: Tue, 7 Nov 2023 13:22:20 +0100 Subject: [PATCH 059/240] # Fix Suggest dropdown partial accept race --- .../browser/inlineCompletionsModel.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index 1a7663d40ee..c213410b299 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -403,6 +403,13 @@ export class InlineCompletionsModel extends Disposable { const partialText = line.substring(0, acceptUntilIndexExclusive); + // Create a local reference to the suggest completion + const suggestWidgetInlineCompletions = this._source.suggestWidgetInlineCompletions.get(); + let clonedSuggest; + if (suggestWidgetInlineCompletions) { + clonedSuggest = suggestWidgetInlineCompletions.clone(); + } + this._isAcceptingPartially = true; try { editor.pushUndoStop(); @@ -411,6 +418,8 @@ export class InlineCompletionsModel extends Disposable { ]); const length = lengthOfText(partialText); editor.setPosition(addPositions(position, length)); + } catch (e) { + clonedSuggest?.dispose(); } finally { this._isAcceptingPartially = false; } @@ -425,6 +434,10 @@ export class InlineCompletionsModel extends Disposable { text.length, ); } + + // If already removed outside of the partial accept, + // this will dispose it also on extensionHost. + clonedSuggest?.dispose(); } public handleSuggestAccepted(item: SuggestItemInfo) { From 8d8912f1e0d4090cebc2d14f75cdf799be4c2775 Mon Sep 17 00:00:00 2001 From: Marcus Revaj Date: Tue, 7 Nov 2023 13:45:24 +0100 Subject: [PATCH 060/240] # Modify to update all active completions --- .../browser/inlineCompletionsModel.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index c213410b299..0f03c19e9eb 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -403,12 +403,11 @@ export class InlineCompletionsModel extends Disposable { const partialText = line.substring(0, acceptUntilIndexExclusive); - // Create a local reference to the suggest completion - const suggestWidgetInlineCompletions = this._source.suggestWidgetInlineCompletions.get(); - let clonedSuggest; - if (suggestWidgetInlineCompletions) { - clonedSuggest = suggestWidgetInlineCompletions.clone(); - } + // Create a local reference to the active completions. + const activeInlineCompletions = [ + this._source.suggestWidgetInlineCompletions.get()?.clone(), + this._source.inlineCompletions.get()?.clone() + ]; this._isAcceptingPartially = true; try { @@ -419,7 +418,7 @@ export class InlineCompletionsModel extends Disposable { const length = lengthOfText(partialText); editor.setPosition(addPositions(position, length)); } catch (e) { - clonedSuggest?.dispose(); + activeInlineCompletions.forEach(c => { c?.dispose(); }); } finally { this._isAcceptingPartially = false; } @@ -435,9 +434,10 @@ export class InlineCompletionsModel extends Disposable { ); } + // Cleans up previously cloned completions. // If already removed outside of the partial accept, // this will dispose it also on extensionHost. - clonedSuggest?.dispose(); + activeInlineCompletions.forEach(c => { c?.dispose(); }); } public handleSuggestAccepted(item: SuggestItemInfo) { From b21c877be0ca69138d2e310e64e64b07207f38f0 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 7 Nov 2023 14:48:37 +0100 Subject: [PATCH 061/240] Uses `completion.source.addRef`/`removeRef` --- .../browser/inlineCompletionsModel.ts | 57 ++++++++----------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index 0f03c19e9eb..66edb2ea369 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -403,41 +403,34 @@ export class InlineCompletionsModel extends Disposable { const partialText = line.substring(0, acceptUntilIndexExclusive); - // Create a local reference to the active completions. - const activeInlineCompletions = [ - this._source.suggestWidgetInlineCompletions.get()?.clone(), - this._source.inlineCompletions.get()?.clone() - ]; - - this._isAcceptingPartially = true; + // Executing the edit might free the completion, so we have to hold a reference on it. + completion.source.addRef(); try { - editor.pushUndoStop(); - editor.executeEdits('inlineSuggestion.accept', [ - EditOperation.replace(Range.fromPositions(position), partialText), - ]); - const length = lengthOfText(partialText); - editor.setPosition(addPositions(position, length)); - } catch (e) { - activeInlineCompletions.forEach(c => { c?.dispose(); }); + this._isAcceptingPartially = true; + try { + editor.pushUndoStop(); + editor.executeEdits('inlineSuggestion.accept', [ + EditOperation.replace(Range.fromPositions(position), partialText), + ]); + const length = lengthOfText(partialText); + editor.setPosition(addPositions(position, length)); + } finally { + this._isAcceptingPartially = false; + } + + if (completion.source.provider.handlePartialAccept) { + const acceptedRange = Range.fromPositions(completion.range.getStartPosition(), addPositions(position, lengthOfText(partialText))); + // This assumes that the inline completion and the model use the same EOL style. + const text = editor.getModel()!.getValueInRange(acceptedRange, EndOfLinePreference.LF); + completion.source.provider.handlePartialAccept( + completion.source.inlineCompletions, + completion.sourceInlineCompletion, + text.length, + ); + } } finally { - this._isAcceptingPartially = false; + completion.source.removeRef(); } - - if (completion.source.provider.handlePartialAccept) { - const acceptedRange = Range.fromPositions(completion.range.getStartPosition(), addPositions(position, lengthOfText(partialText))); - // This assumes that the inline completion and the model use the same EOL style. - const text = editor.getModel()!.getValueInRange(acceptedRange, EndOfLinePreference.LF); - completion.source.provider.handlePartialAccept( - completion.source.inlineCompletions, - completion.sourceInlineCompletion, - text.length, - ); - } - - // Cleans up previously cloned completions. - // If already removed outside of the partial accept, - // this will dispose it also on extensionHost. - activeInlineCompletions.forEach(c => { c?.dispose(); }); } public handleSuggestAccepted(item: SuggestItemInfo) { From 716e1653a0364087259f8cbb6746f631a96d6d41 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 7 Nov 2023 15:41:01 +0100 Subject: [PATCH 062/240] wip --- src/vs/workbench/contrib/chat/browser/actions/chatActions.ts | 1 + src/vs/workbench/contrib/chat/browser/chat.contribution.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts index a0412cac5b6..6c9f87338d9 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts @@ -249,6 +249,7 @@ export function registerChatActions() { const editorPaneDescriptor = editorPanesRegistry.getEditorPane(chatEditorInput); const auxiliaryEditorPart = await editorGroupService.createAuxiliaryEditorPart(); const editorPane = editorPaneDescriptor?.instantiate(instantiationService); + console.log('editorPane : ', editorPane); if (!editorPane || !editorPane.group || !editorPane.input) { return; } diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index 7c68e511413..cbe23536b18 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -93,7 +93,7 @@ configurationRegistry.registerConfiguration({ } }); -// TODO + Registry.as(EditorExtensions.EditorPane).registerEditorPane( EditorPaneDescriptor.create( ChatEditor, From 32f793e8e97e1748cf83f734ff3e31ad83b3c799 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 7 Nov 2023 15:13:57 +0100 Subject: [PATCH 063/240] Fixes autorun logging bug. --- src/vs/base/common/observableInternal/autorun.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/base/common/observableInternal/autorun.ts b/src/vs/base/common/observableInternal/autorun.ts index 050e9bae1c3..e65da14e7d0 100644 --- a/src/vs/base/common/observableInternal/autorun.ts +++ b/src/vs/base/common/observableInternal/autorun.ts @@ -140,15 +140,18 @@ export class AutorunObserver implements IObserver, IReader this.state = AutorunState.upToDate; + const isDisposed = this.disposed; try { - if (!this.disposed) { + if (!isDisposed) { getLogger()?.handleAutorunTriggered(this); const changeSummary = this.changeSummary!; this.changeSummary = this.createChangeSummary?.(); this._runFn(this, changeSummary); } } finally { - getLogger()?.handleAutorunFinished(this); + if (!isDisposed) { + getLogger()?.handleAutorunFinished(this); + } // We don't want our observed observables to think that they are (not even temporarily) not being observed. // Thus, we only unsubscribe from observables that are definitely not read anymore. for (const o of this.dependenciesToBeRemoved) { From d700c43194da632c436f4ace55c309efc53bb358 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 7 Nov 2023 15:16:36 +0100 Subject: [PATCH 064/240] Observable improvements --- src/vs/base/common/observableInternal/base.ts | 26 ++++++++++-- .../base/common/observableInternal/utils.ts | 42 +++++++++++++++---- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/src/vs/base/common/observableInternal/base.ts b/src/vs/base/common/observableInternal/base.ts index bc7f900caed..e4ce36ec74e 100644 --- a/src/vs/base/common/observableInternal/base.ts +++ b/src/vs/base/common/observableInternal/base.ts @@ -231,6 +231,24 @@ export function transaction(fn: (tx: ITransaction) => void, getDebugName?: () => } } +let _globalTransaction: ITransaction | undefined = undefined; + +export function globalTransaction(fn: (tx: ITransaction) => void) { + if (_globalTransaction) { + fn(_globalTransaction); + } else { + const tx = new TransactionImpl(fn, undefined); + _globalTransaction = tx; + try { + fn(tx); + } finally { + tx.finish(); // During finish, more actions might be added to the transaction. + // Which is why we only clear the global transaction after finish. + _globalTransaction = undefined; + } + } +} + export async function asyncTransaction(fn: (tx: ITransaction) => Promise, getDebugName?: () => string): Promise { const tx = new TransactionImpl(fn, getDebugName); try { @@ -263,17 +281,19 @@ export class TransactionImpl implements ITransaction { } public updateObserver(observer: IObserver, observable: IObservable): void { + // When this gets called while finish is active, they will still get considered this.updatingObservers!.push({ observer, observable }); observer.beginUpdate(observable); } public finish(): void { const updatingObservers = this.updatingObservers!; - // Prevent anyone from updating observers from now on. - this.updatingObservers = null; - for (const { observer, observable } of updatingObservers) { + for (let i = 0; i < updatingObservers.length; i++) { + const { observer, observable } = updatingObservers[i]; observer.endUpdate(observable); } + // Prevent anyone from updating observers from now on. + this.updatingObservers = null; getLogger()?.handleEndTransaction(); } } diff --git a/src/vs/base/common/observableInternal/utils.ts b/src/vs/base/common/observableInternal/utils.ts index 77cf5fb7422..dfc6e315d06 100644 --- a/src/vs/base/common/observableInternal/utils.ts +++ b/src/vs/base/common/observableInternal/utils.ts @@ -6,7 +6,7 @@ import { Event } from 'vs/base/common/event'; import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { autorun } from 'vs/base/common/observableInternal/autorun'; -import { BaseObservable, ConvenientObservable, IObservable, IObserver, IReader, ITransaction, getDebugName, getFunctionName, observableValue, transaction } from 'vs/base/common/observableInternal/base'; +import { BaseObservable, ConvenientObservable, IObservable, IObserver, IReader, ITransaction, getDebugName, getFunctionName, observableValue, subtransaction, transaction } from 'vs/base/common/observableInternal/base'; import { derived } from 'vs/base/common/observableInternal/derived'; import { getLogger } from 'vs/base/common/observableInternal/logging'; @@ -56,16 +56,17 @@ export function waitForState(observable: IObservable, predicate: (state: T return new Promise(resolve => { let didRun = false; let shouldDispose = false; + const stateObs = observable.map(state => ({ isFinished: predicate(state), state })); const d = autorun(reader => { /** @description waitForState */ - const currentState = observable.read(reader); - if (predicate(currentState)) { + const { isFinished, state } = stateObs.read(reader); + if (isFinished) { if (!didRun) { shouldDispose = true; } else { d.dispose(); } - resolve(currentState); + resolve(state); } }); didRun = true; @@ -83,6 +84,8 @@ export function observableFromEvent( } export class FromEventObservable extends BaseObservable { + public static globalTransaction: ITransaction | undefined; + private value: T | undefined; private hasValue = false; private subscription: IDisposable | undefined; @@ -109,17 +112,21 @@ export class FromEventObservable extends BaseObservable { private readonly handleEvent = (args: TArgs | undefined) => { const newValue = this._getValue(args); + const oldValue = this.value; - const didChange = !this.hasValue || this.value !== newValue; - - getLogger()?.handleFromEventObservableTriggered(this, { oldValue: this.value, newValue, change: undefined, didChange, hadValue: this.hasValue }); + const didChange = !this.hasValue || oldValue !== newValue; + let didRunTransaction = false; if (didChange) { this.value = newValue; if (this.hasValue) { - transaction( + didRunTransaction = true; + subtransaction( + FromEventObservable.globalTransaction, (tx) => { + getLogger()?.handleFromEventObservableTriggered(this, { oldValue, newValue, change: undefined, didChange, hadValue: this.hasValue }); + for (const o of this.observers) { tx.updateObserver(o, this); o.handleChange(this, undefined); @@ -133,6 +140,10 @@ export class FromEventObservable extends BaseObservable { } this.hasValue = true; } + + if (!didRunTransaction) { + getLogger()?.handleFromEventObservableTriggered(this, { oldValue, newValue, change: undefined, didChange, hadValue: this.hasValue }); + } }; protected override onLastObserverRemoved(): void { @@ -157,6 +168,21 @@ export class FromEventObservable extends BaseObservable { export namespace observableFromEvent { export const Observer = FromEventObservable; + + export function batchEventsGlobally(tx: ITransaction, fn: () => void): void { + let didSet = false; + if (FromEventObservable.globalTransaction === undefined) { + FromEventObservable.globalTransaction = tx; + didSet = true; + } + try { + fn(); + } finally { + if (didSet) { + FromEventObservable.globalTransaction = undefined; + } + } + } } export function observableSignalFromEvent( From 35be92193fd13cc6ca2c4dcaeb7f75bc6620d60b Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 7 Nov 2023 15:27:22 +0100 Subject: [PATCH 065/240] Improves observable descriptions --- .../widget/diffEditor/diffEditorEditors.ts | 2 +- .../browser/widget/diffEditor/diffEditorSash.ts | 2 +- .../widget/diffEditor/diffEditorViewModel.ts | 1 + .../widget/diffEditor/movedBlocksLines.ts | 5 +++-- .../inlineCompletions/browser/ghostTextWidget.ts | 2 +- .../browser/inlineCompletionsController.ts | 16 ++++++++-------- .../codeEditor/browser/diffEditorHelper.ts | 2 +- 7 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditor/diffEditorEditors.ts b/src/vs/editor/browser/widget/diffEditor/diffEditorEditors.ts index bb6cbeef5c5..b6d518d4c1c 100644 --- a/src/vs/editor/browser/widget/diffEditor/diffEditorEditors.ts +++ b/src/vs/editor/browser/widget/diffEditor/diffEditorEditors.ts @@ -41,7 +41,7 @@ export class DiffEditorEditors extends Disposable { this.original = this._register(this._createLeftHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.originalEditor || {})); this.modified = this._register(this._createRightHandSideEditor(_options.editorOptions.get(), codeEditorWidgetOptions.modifiedEditor || {})); - this.modifiedModel = observableFromEvent(this.modified.onDidChangeModel, () => this.modified.getModel()); + this.modifiedModel = observableFromEvent(this.modified.onDidChangeModel, () => /** @description modified.model */ this.modified.getModel()); this._register(autorunHandleChanges({ createEmptyChangeSummary: () => ({} as IDiffEditorConstructionOptions), diff --git a/src/vs/editor/browser/widget/diffEditor/diffEditorSash.ts b/src/vs/editor/browser/widget/diffEditor/diffEditorSash.ts index b5aeba205ef..0db9948a6c4 100644 --- a/src/vs/editor/browser/widget/diffEditor/diffEditorSash.ts +++ b/src/vs/editor/browser/widget/diffEditor/diffEditorSash.ts @@ -43,7 +43,7 @@ export class DiffEditorSash extends Disposable { this._register(this._sash.onDidReset(() => this._sashRatio.set(undefined, undefined))); this._register(autorun(reader => { - /** @description update sash layout */ + /** @description DiffEditorSash.layoutSash */ const enabled = this._options.enableSplitViewResizing.read(reader); this._sash.state = enabled ? SashState.Enabled : SashState.Disabled; this.sashLeft.read(reader); diff --git a/src/vs/editor/browser/widget/diffEditor/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditor/diffEditorViewModel.ts index 6b81646b0f9..3b54ff415f4 100644 --- a/src/vs/editor/browser/widget/diffEditor/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditor/diffEditorViewModel.ts @@ -221,6 +221,7 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo result = applyModifiedEdits(result, modifiedTextEditInfos, model.original, model.modified) ?? result; transaction(tx => { + /** @description write diff result */ updateUnchangedRegions(result, tx); this._lastDiff = result; diff --git a/src/vs/editor/browser/widget/diffEditor/movedBlocksLines.ts b/src/vs/editor/browser/widget/diffEditor/movedBlocksLines.ts index edaf0c6e099..05d33c3cdf6 100644 --- a/src/vs/editor/browser/widget/diffEditor/movedBlocksLines.ts +++ b/src/vs/editor/browser/widget/diffEditor/movedBlocksLines.ts @@ -72,8 +72,8 @@ export class MovedBlocksLinesPart extends Disposable { })); }); - this._register(applyViewZones(this._editors.original, movedBlockViewZones.map(zones => zones.map(z => z.original)))); - this._register(applyViewZones(this._editors.modified, movedBlockViewZones.map(zones => zones.map(z => z.modified)))); + this._register(applyViewZones(this._editors.original, movedBlockViewZones.map(zones => /** @description movedBlockViewZones.original */ zones.map(z => z.original)))); + this._register(applyViewZones(this._editors.modified, movedBlockViewZones.map(zones => /** @description movedBlockViewZones.modified */ zones.map(z => z.modified)))); this._register(autorunWithStore((reader, store) => { const blocks = movedBlockViewZones.read(reader); @@ -104,6 +104,7 @@ export class MovedBlocksLinesPart extends Disposable { return true; } }, reader => { + /** @description MovedBlocksLines.setActiveMovedTextFromCursor */ originalHasFocus.read(reader); modifiedHasFocus.read(reader); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts index f690a7142d9..0cfd4f3cb44 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextWidget.ts @@ -34,7 +34,7 @@ export interface IGhostTextWidgetModel { export class GhostTextWidget extends Disposable { private readonly isDisposed = observableValue(this, false); - private readonly currentTextModel = observableFromEvent(this.editor.onDidChangeModel, () => this.editor.getModel()); + private readonly currentTextModel = observableFromEvent(this.editor.onDidChangeModel, () => /** @description editor.model */ this.editor.getModel()); constructor( private readonly editor: ICodeEditor, diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts index 4f977c5df2e..b86160ee020 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController.ts @@ -46,7 +46,7 @@ export class InlineCompletionsController extends Disposable { (tx) => this.updateObservables(tx, VersionIdChangeReason.Other), (item) => { transaction(tx => { - /** @description handleSuggestAccepted */ + /** @description InlineCompletionsController.handleSuggestAccepted */ this.updateObservables(tx, VersionIdChangeReason.Other); this.model.get()?.handleSuggestAccepted(item); }); @@ -83,7 +83,7 @@ export class InlineCompletionsController extends Disposable { this._register(new InlineCompletionContextKeys(this._contextKeyService, this.model)); this._register(Event.runAndSubscribe(editor.onDidChangeModel, () => transaction(tx => { - /** @description onDidChangeModel */ + /** @description InlineCompletionsController.onDidChangeModel */ this.model.set(undefined, tx); this.updateObservables(tx, VersionIdChangeReason.Other); @@ -112,12 +112,12 @@ export class InlineCompletionsController extends Disposable { return VersionIdChangeReason.Other; }; this._register(editor.onDidChangeModelContent((e) => transaction(tx => - /** @description onDidChangeModelContent */ + /** @description InlineCompletionsController.onDidChangeModelContent */ this.updateObservables(tx, getReason(e)) ))); this._register(editor.onDidChangeCursorPosition(e => transaction(tx => { - /** @description onDidChangeCursorPosition */ + /** @description InlineCompletionsController.onDidChangeCursorPosition */ this.updateObservables(tx, VersionIdChangeReason.Other); if (e.reason === CursorChangeReason.Explicit || e.source === 'api') { this.model.get()?.stop(tx); @@ -125,7 +125,7 @@ export class InlineCompletionsController extends Disposable { }))); this._register(editor.onDidType(() => transaction(tx => { - /** @description onDidType */ + /** @description InlineCompletionsController.onDidType */ this.updateObservables(tx, VersionIdChangeReason.Other); if (this._enabled.get()) { this.model.get()?.trigger(tx); @@ -159,13 +159,13 @@ export class InlineCompletionsController extends Disposable { return; } transaction(tx => { - /** @description onDidBlurEditorWidget */ + /** @description InlineCompletionsController.onDidBlurEditorWidget */ this.model.get()?.stop(tx); }); })); this._register(autorun(reader => { - /** @description forceRenderingAbove */ + /** @description InlineCompletionsController.forceRenderingAbove */ const state = this.model.read(reader)?.state.read(reader); if (state?.suggestItem) { if (state.ghostText.lineCount >= 2) { @@ -188,7 +188,7 @@ export class InlineCompletionsController extends Disposable { return true; }, }, async reader => { - /** @description play audio cue & read suggestion */ + /** @description InlineCompletionsController.playAudioCueAndReadSuggestion */ this._playAudioCueSignal.read(reader); const model = this.model.read(reader); diff --git a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts index e5331b3b34d..a6a66ffd952 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts @@ -43,7 +43,7 @@ class DiffEditorHelperContribution extends Disposable implements IDiffEditorCont const isEmbeddedDiffEditor = this._diffEditor instanceof EmbeddedDiffEditorWidget; if (!isEmbeddedDiffEditor) { - const computationResult = observableFromEvent(e => this._diffEditor.onDidUpdateDiff(e), () => this._diffEditor.getDiffComputationResult()); + const computationResult = observableFromEvent(e => this._diffEditor.onDidUpdateDiff(e), () => /** diffEditor.diffComputationResult */ this._diffEditor.getDiffComputationResult()); const onlyWhiteSpaceChange = computationResult.map(r => r && !r.identical && r.changes2.length === 0); this._register(autorunWithStore((reader, store) => { From a85f65be4d9e3a7972955092e6bb2a5ef0269cae Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 7 Nov 2023 15:29:59 +0100 Subject: [PATCH 066/240] Improves diff editor set model performance --- .../widget/diffEditor/diffEditorWidget.ts | 101 ++++++++++++++---- .../diffEditor/hideUnchangedRegionsFeature.ts | 36 ++++--- .../widget/diffEditor/lineAlignment.ts | 94 ++++------------ .../editor/browser/widget/diffEditor/utils.ts | 29 +++-- 4 files changed, 144 insertions(+), 116 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts index 1a4a07758c5..f5f984cd239 100644 --- a/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts @@ -8,12 +8,13 @@ import { findLast } from 'vs/base/common/arraysFind'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Event } from 'vs/base/common/event'; import { toDisposable } from 'vs/base/common/lifecycle'; -import { IObservable, autorun, autorunWithStore, derived, derivedWithStore, disposableObservableValue, recomputeInitiallyAndOnChange, observableValue, transaction } from 'vs/base/common/observable'; +import { IObservable, ITransaction, autorun, autorunWithStore, derived, derivedWithStore, observableFromEvent, observableValue, recomputeInitiallyAndOnChange, subtransaction, transaction } from 'vs/base/common/observable'; import 'vs/css!./style'; import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration'; import { ICodeEditor, IDiffEditor, IDiffEditorConstructionOptions, IMouseTargetViewZone } from 'vs/editor/browser/editorBrowser'; import { EditorExtensionsRegistry, IDiffEditorContributionDescription } from 'vs/editor/browser/editorExtensions'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { StableEditorScrollState } from 'vs/editor/browser/stableEditorScroll'; import { CodeEditorWidget, ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget'; import { AccessibleDiffViewer } from 'vs/editor/browser/widget/diffEditor/accessibleDiffViewer'; import { DiffEditorDecorations } from 'vs/editor/browser/widget/diffEditor/diffEditorDecorations'; @@ -22,7 +23,7 @@ import { HideUnchangedRegionsFeature } from 'vs/editor/browser/widget/diffEditor import { ViewZoneManager } from 'vs/editor/browser/widget/diffEditor/lineAlignment'; import { MovedBlocksLinesPart } from 'vs/editor/browser/widget/diffEditor/movedBlocksLines'; import { OverviewRulerPart } from 'vs/editor/browser/widget/diffEditor/overviewRulerPart'; -import { CSSStyle, ObservableElementSizeObserver, applyStyle, readHotReloadableExport } from 'vs/editor/browser/widget/diffEditor/utils'; +import { CSSStyle, ObservableElementSizeObserver, applyStyle, applyViewZones, readHotReloadableExport } from 'vs/editor/browser/widget/diffEditor/utils'; import { IDiffEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IDimension } from 'vs/editor/common/core/dimension'; import { Position } from 'vs/editor/common/core/position'; @@ -59,7 +60,8 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor { h('div.editor.modified@modified', { style: { position: 'absolute', height: '100%' } }), h('div.accessibleDiffViewer@accessibleDiffViewer', { style: { position: 'absolute', height: '100%' } }), ]); - private readonly _diffModel = this._register(disposableObservableValue('diffModel', undefined)); + private readonly _diffModel = observableValue(this, undefined); + private _shouldDisposeDiffModel = false; public readonly onDidChangeModel = Event.fromObservableLight(this._diffModel); public get onDidContentSizeChange() { return this._editors.onDidContentSizeChange; } @@ -73,8 +75,6 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor { private readonly _sash: IObservable; private readonly _boundarySashes = observableValue(this, undefined); - private unchangedRangesFeature!: HideUnchangedRegionsFeature; - private _accessibleDiffViewerShouldBeVisible = observableValue(this, false); private _accessibleDiffViewerVisible = derived(this, reader => this._options.onlyShowAccessibleDiffViewer.read(reader) @@ -163,29 +163,65 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor { }); this._register(recomputeInitiallyAndOnChange(this._sash)); - this._register(autorunWithStore((reader, store) => { + const unchangedRangesFeature = derivedWithStore((reader, store) => { /** @description UnchangedRangesFeature */ - this.unchangedRangesFeature = store.add( - this._instantiationService.createInstance(readHotReloadableExport(HideUnchangedRegionsFeature, reader), this._editors, this._diffModel, this._options) - ); - })); + return store.add(this._instantiationService.createInstance( + readHotReloadableExport(HideUnchangedRegionsFeature, reader), + this._editors, + this._diffModel, + this._options + )); + }); this._register(autorunWithStore((reader, store) => { /** @description DiffEditorDecorations */ store.add(new (readHotReloadableExport(DiffEditorDecorations, reader))(this._editors, this._diffModel, this._options)); })); - this._register(autorunWithStore((reader, store) => { + + const origViewZoneIdsToIgnore = new Set(); + const modViewZoneIdsToIgnore = new Set(); + let isUpdatingViewZones = false; + const viewZoneManager = derivedWithStore((reader, store) => { /** @description ViewZoneManager */ - store.add(this._instantiationService.createInstance( + return store.add(this._instantiationService.createInstance( readHotReloadableExport(ViewZoneManager, reader), getWindow(this._domElement), this._editors, this._diffModel, this._options, this, - () => this.unchangedRangesFeature.isUpdatingViewZones, + () => isUpdatingViewZones || unchangedRangesFeature.get().isUpdatingHiddenAreas, + origViewZoneIdsToIgnore, + modViewZoneIdsToIgnore, )); - })); + }); + this._register(recomputeInitiallyAndOnChange(viewZoneManager)); + + const originalViewZones = derived((reader) => { + /** @description DiffEditorWidget.originalViewZones */ + const orig = viewZoneManager.read(reader).viewZones.read(reader).orig; + const orig2 = unchangedRangesFeature.read(reader).viewZones.read(reader).origViewZones; + return orig.concat(orig2); + }); + const modifiedViewZones = derived((reader) => { + /** @description DiffEditorWidget.modifiedViewZones */ + const mod = viewZoneManager.read(reader).viewZones.read(reader).mod; + const mod2 = unchangedRangesFeature.read(reader).viewZones.read(reader).modViewZones; + return mod.concat(mod2); + }); + this._register(applyViewZones(this._editors.original, originalViewZones, isUpdatingOrigViewZones => { + isUpdatingViewZones = isUpdatingOrigViewZones; + }, origViewZoneIdsToIgnore)); + let scrollState: StableEditorScrollState | undefined; + this._register(applyViewZones(this._editors.modified, modifiedViewZones, isUpdatingModViewZones => { + isUpdatingViewZones = isUpdatingModViewZones; + if (!isUpdatingViewZones) { + scrollState = StableEditorScrollState.capture(this._editors.modified); + } else { + scrollState?.restore(this._editors.modified); + scrollState = undefined; + } + }, modViewZoneIdsToIgnore)); this._register(autorunWithStore((reader, store) => { /** @description OverviewRulerPart */ @@ -276,13 +312,20 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor { } })); - const isDiffUpToDate = this._diffModel.map((m, reader) => m?.isDiffUpToDate.read(reader)); + const isDiffUpToDate = this._diffModel.map((m, reader) => /** @description DiffEditorWidgetHelper.isDiffUpToDate */ m?.isDiffUpToDate.read(reader)); this._register(autorunWithStore((reader, store) => { + /** @description DiffEditorWidgetHelper.ShowProgress */ if (isDiffUpToDate.read(reader) === false) { const r = this._editorProgressService.show(true, 1000); store.add(toDisposable(() => r.done())); } })); + + this._register(toDisposable(() => { + if (this._shouldDisposeDiffModel) { + this._diffModel.get()?.dispose(); + } + })); } public getViewWidth(): number { @@ -385,18 +428,32 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor { override getModel(): IDiffEditorModel | null { return this._diffModel.get()?.model ?? null; } - override setModel(model: IDiffEditorModel | null | IDiffEditorViewModel): void { + override setModel(model: IDiffEditorModel | null | IDiffEditorViewModel, tx?: ITransaction): void { if (!model && this._diffModel.get()) { // Transitioning from a model to no-model this._accessibleDiffViewer.close(); } - const vm = model ? ('model' in model) ? model : this.createViewModel(model) : undefined; - this._editors.original.setModel(vm ? vm.model.original : null); - this._editors.modified.setModel(vm ? vm.model.modified : null); - transaction(tx => { - this._diffModel.set(vm as (DiffEditorViewModel | undefined), tx); - }); + const vm = model ? ('model' in model) ? { model, shouldDispose: false } : { model: this.createViewModel(model), shouldDispose: true } : undefined; + + if (this._diffModel.get() !== vm?.model) { + subtransaction(tx, tx => { + /** @description DiffEditorWidget.setModel */ + observableFromEvent.batchEventsGlobally(tx, () => { + this._editors.original.setModel(vm ? vm.model.model.original : null); + this._editors.modified.setModel(vm ? vm.model.model.modified : null); + }); + const prevValue = this._diffModel.get(); + const shouldDispose = this._shouldDisposeDiffModel; + + this._shouldDisposeDiffModel = vm?.shouldDispose ?? false; + this._diffModel.set(vm?.model as (DiffEditorViewModel | undefined), tx); + + if (shouldDispose) { + prevValue?.dispose(); + } + }); + } } /** diff --git a/src/vs/editor/browser/widget/diffEditor/hideUnchangedRegionsFeature.ts b/src/vs/editor/browser/widget/diffEditor/hideUnchangedRegionsFeature.ts index 395ecbcd785..97fe0061573 100644 --- a/src/vs/editor/browser/widget/diffEditor/hideUnchangedRegionsFeature.ts +++ b/src/vs/editor/browser/widget/diffEditor/hideUnchangedRegionsFeature.ts @@ -13,12 +13,12 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IObservable, IReader, autorun, autorunWithStore, derived, derivedWithStore, observableFromEvent, observableSignalFromEvent, observableValue, transaction } from 'vs/base/common/observable'; import { ThemeIcon } from 'vs/base/common/themables'; import { isDefined } from 'vs/base/common/types'; -import { ICodeEditor, IViewZone } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditor/diffEditorEditors'; import { DiffEditorOptions } from 'vs/editor/browser/widget/diffEditor/diffEditorOptions'; import { DiffEditorViewModel, UnchangedRegion } from 'vs/editor/browser/widget/diffEditor/diffEditorViewModel'; import { OutlineModel } from 'vs/editor/browser/widget/diffEditor/outlineModel'; -import { DisposableCancellationTokenSource, PlaceholderViewZone, ViewZoneOverlayWidget, applyObservableDecorations, applyStyle, applyViewZones } from 'vs/editor/browser/widget/diffEditor/utils'; +import { DisposableCancellationTokenSource, IObservableViewZone, PlaceholderViewZone, ViewZoneOverlayWidget, applyObservableDecorations, applyStyle } from 'vs/editor/browser/widget/diffEditor/utils'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { Position } from 'vs/editor/common/core/position'; @@ -29,16 +29,24 @@ import { IModelDecorationOptions, IModelDeltaDecoration, ITextModel } from 'vs/e import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { localize } from 'vs/nls'; +/** + * Make sure to add the view zones to the editor! + */ export class HideUnchangedRegionsFeature extends Disposable { - private _isUpdatingViewZones = false; - public get isUpdatingViewZones(): boolean { return this._isUpdatingViewZones; } - private readonly _modifiedOutlineSource = derivedWithStore(this, (reader, store) => { const m = this._editors.modifiedModel.read(reader); if (!m) { return undefined; } return store.add(new OutlineSource(this._languageFeaturesService, m)); }); + public readonly viewZones: IObservable<{ + origViewZones: IObservableViewZone[]; + modViewZones: IObservableViewZone[]; + }>; + + private _isUpdatingHiddenAreas = false; + public get isUpdatingHiddenAreas() { return this._isUpdatingHiddenAreas; } + constructor( private readonly _editors: DiffEditorEditors, private readonly _diffModel: IObservable, @@ -73,13 +81,13 @@ export class HideUnchangedRegionsFeature extends Disposable { const unchangedRegions = this._diffModel.map((m, reader) => m?.diff.read(reader)?.mappings.length === 0 ? [] : m?.unchangedRegions.read(reader) ?? []); - const viewZones = derivedWithStore(this, (reader, store) => { + this.viewZones = derivedWithStore(this, (reader, store) => { /** @description view Zones */ const modifiedOutlineSource = this._modifiedOutlineSource.read(reader); if (!modifiedOutlineSource) { return { origViewZones: [], modViewZones: [] }; } - const origViewZones: IViewZone[] = []; - const modViewZones: IViewZone[] = []; + const origViewZones: IObservableViewZone[] = []; + const modViewZones: IObservableViewZone[] = []; const sideBySide = this._options.renderSideBySide.read(reader); const curUnchangedRegions = unchangedRegions.read(reader); @@ -172,14 +180,16 @@ export class HideUnchangedRegionsFeature extends Disposable { return result; }))); - this._register(applyViewZones(this._editors.original, viewZones.map(v => v.origViewZones), v => this._isUpdatingViewZones = v)); - this._register(applyViewZones(this._editors.modified, viewZones.map(v => v.modViewZones), v => this._isUpdatingViewZones = v)); - this._register(autorun((reader) => { /** @description update folded unchanged regions */ const curUnchangedRegions = unchangedRegions.read(reader); - this._editors.original.setHiddenAreas(curUnchangedRegions.map(r => r.getHiddenOriginalRange(reader).toInclusiveRange()).filter(isDefined)); - this._editors.modified.setHiddenAreas(curUnchangedRegions.map(r => r.getHiddenModifiedRange(reader).toInclusiveRange()).filter(isDefined)); + this._isUpdatingHiddenAreas = true; + try { + this._editors.original.setHiddenAreas(curUnchangedRegions.map(r => r.getHiddenOriginalRange(reader).toInclusiveRange()).filter(isDefined)); + this._editors.modified.setHiddenAreas(curUnchangedRegions.map(r => r.getHiddenModifiedRange(reader).toInclusiveRange()).filter(isDefined)); + } finally { + this._isUpdatingHiddenAreas = false; + } })); this._register(this._editors.modified.onMouseUp(event => { diff --git a/src/vs/editor/browser/widget/diffEditor/lineAlignment.ts b/src/vs/editor/browser/widget/diffEditor/lineAlignment.ts index 698734aeba0..d86a9720f4f 100644 --- a/src/vs/editor/browser/widget/diffEditor/lineAlignment.ts +++ b/src/vs/editor/browser/widget/diffEditor/lineAlignment.ts @@ -7,13 +7,11 @@ import { $ } from 'vs/base/browser/dom'; import { ArrayQueue } from 'vs/base/common/arrays'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Codicon } from 'vs/base/common/codicons'; -import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; -import { IObservable, autorun, autorunWithStore, derived, observableFromEvent, observableValue } from 'vs/base/common/observable'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { IObservable, autorun, derived, observableFromEvent, observableValue } from 'vs/base/common/observable'; import { ThemeIcon } from 'vs/base/common/themables'; import { assertIsDefined } from 'vs/base/common/types'; import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; -import { IViewZone } from 'vs/editor/browser/editorBrowser'; -import { StableEditorScrollState } from 'vs/editor/browser/stableEditorScroll'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { diffDeleteDecoration, diffRemoveIcon } from 'vs/editor/browser/widget/diffEditor/decorations'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditor/diffEditorEditors'; @@ -21,7 +19,7 @@ import { DiffEditorViewModel, DiffMapping } from 'vs/editor/browser/widget/diffE import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditor/diffEditorWidget'; import { InlineDiffDeletedCodeMargin } from 'vs/editor/browser/widget/diffEditor/inlineDiffDeletedCodeMargin'; import { LineSource, RenderOptions, renderLines } from 'vs/editor/browser/widget/diffEditor/renderLines'; -import { animatedObservable, joinCombine } from 'vs/editor/browser/widget/diffEditor/utils'; +import { IObservableViewZone, animatedObservable, joinCombine } from 'vs/editor/browser/widget/diffEditor/utils'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { Position } from 'vs/editor/common/core/position'; @@ -37,6 +35,8 @@ import { DiffEditorOptions } from './diffEditorOptions'; * Ensures both editors have the same height by aligning unchanged lines. * In inline view mode, inserts viewzones to show deleted code from the original text model in the modified code editor. * Synchronizes scrolling. + * + * Make sure to add the view zones! */ export class ViewZoneManager extends Disposable { private readonly _originalTopPadding = observableValue(this, 0); @@ -49,6 +49,8 @@ export class ViewZoneManager extends Disposable { private readonly _modifiedScrollOffset = observableValue(this, 0); private readonly _modifiedScrollOffsetAnimated = animatedObservable(this._targetWindow, this._modifiedScrollOffset, this._store); + public readonly viewZones: IObservable<{ orig: IObservableViewZone[]; mod: IObservableViewZone[] }>; + constructor( private readonly _targetWindow: Window, private readonly _editors: DiffEditorEditors, @@ -56,20 +58,21 @@ export class ViewZoneManager extends Disposable { private readonly _options: DiffEditorOptions, private readonly _diffEditorWidget: DiffEditorWidget, private readonly _canIgnoreViewZoneUpdateEvent: () => boolean, + private readonly _origViewZonesToIgnore: Set, + private readonly _modViewZonesToIgnore: Set, @IClipboardService private readonly _clipboardService: IClipboardService, @IContextMenuService private readonly _contextMenuService: IContextMenuService, ) { super(); - let isChangingViewZones = false; - const state = observableValue('state', 0); + const state = observableValue('invalidateAlignmentsState', 0); const updateImmediately = this._register(new RunOnceScheduler(() => { state.set(state.get() + 1, undefined); }, 0)); - this._register(this._editors.original.onDidChangeViewZones((_args) => { if (!isChangingViewZones && !this._canIgnoreViewZoneUpdateEvent()) { updateImmediately.schedule(); } })); - this._register(this._editors.modified.onDidChangeViewZones((_args) => { if (!isChangingViewZones && !this._canIgnoreViewZoneUpdateEvent()) { updateImmediately.schedule(); } })); + this._register(this._editors.original.onDidChangeViewZones((_args) => { if (!this._canIgnoreViewZoneUpdateEvent()) { updateImmediately.schedule(); } })); + this._register(this._editors.modified.onDidChangeViewZones((_args) => { if (!this._canIgnoreViewZoneUpdateEvent()) { updateImmediately.schedule(); } })); this._register(this._editors.original.onDidChangeConfiguration((args) => { if (args.hasChanged(EditorOption.wrappingInfo) || args.hasChanged(EditorOption.lineHeight)) { updateImmediately.schedule(); } })); @@ -81,9 +84,6 @@ export class ViewZoneManager extends Disposable { m ? observableFromEvent(m.model.original.onDidChangeTokens, () => m.model.original.tokenization.backgroundTokenizationState === BackgroundTokenizationState.Completed) : undefined ).map((m, reader) => m?.read(reader)); - const alignmentViewZoneIdsOrig = new Set(); - const alignmentViewZoneIdsMod = new Set(); - const alignments = derived((reader) => { /** @description alignments */ const diffModel = this._diffModel.read(reader); @@ -96,14 +96,14 @@ export class ViewZoneManager extends Disposable { this._editors.original, this._editors.modified, diff.mappings, - alignmentViewZoneIdsOrig, - alignmentViewZoneIdsMod, + this._origViewZonesToIgnore, + this._modViewZonesToIgnore, innerHunkAlignment ); }); const alignmentsSyncedMovedText = derived((reader) => { - /** @description alignments */ + /** @description alignmentsSyncedMovedText */ const syncedMovedText = this._diffModel.read(reader)?.movedTextToCompare.read(reader); if (!syncedMovedText) { return null; } state.read(reader); @@ -113,8 +113,8 @@ export class ViewZoneManager extends Disposable { this._editors.original, this._editors.modified, mappings, - alignmentViewZoneIdsOrig, - alignmentViewZoneIdsMod, + this._origViewZonesToIgnore, + this._modViewZonesToIgnore, true ); }); @@ -126,14 +126,13 @@ export class ViewZoneManager extends Disposable { } const alignmentViewZonesDisposables = this._register(new DisposableStore()); - const alignmentViewZones = derived<{ orig: IViewZoneWithZoneId[]; mod: IViewZoneWithZoneId[] }>((reader) => { - /** @description alignment viewzones */ + this.viewZones = derived<{ orig: IObservableViewZone[]; mod: IObservableViewZone[] }>(this, (reader) => { alignmentViewZonesDisposables.clear(); const alignmentsVal = alignments.read(reader) || []; - const origViewZones: IViewZoneWithZoneId[] = []; - const modViewZones: IViewZoneWithZoneId[] = []; + const origViewZones: IObservableViewZone[] = []; + const modViewZones: IObservableViewZone[] = []; const modifiedTopPaddingVal = this._modifiedTopPadding.read(reader); if (modifiedTopPaddingVal > 0) { @@ -340,50 +339,6 @@ export class ViewZoneManager extends Disposable { return { orig: origViewZones, mod: modViewZones }; }); - this._register(autorunWithStore((reader) => { - /** @description alignment viewzones */ - const scrollState = StableEditorScrollState.capture(this._editors.modified); - - const alignmentViewZones_ = alignmentViewZones.read(reader); - isChangingViewZones = true; - this._editors.original.changeViewZones((aOrig) => { - for (const id of alignmentViewZoneIdsOrig) { aOrig.removeZone(id); } - alignmentViewZoneIdsOrig.clear(); - for (const z of alignmentViewZones_.orig) { - const id = aOrig.addZone(z); - if (z.setZoneId) { - z.setZoneId(id); - } - alignmentViewZoneIdsOrig.add(id); - } - }); - this._editors.modified.changeViewZones(aMod => { - for (const id of alignmentViewZoneIdsMod) { aMod.removeZone(id); } - alignmentViewZoneIdsMod.clear(); - for (const z of alignmentViewZones_.mod) { - const id = aMod.addZone(z); - if (z.setZoneId) { - z.setZoneId(id); - } - alignmentViewZoneIdsMod.add(id); - } - }); - isChangingViewZones = false; - - scrollState.restore(this._editors.modified); - })); - - this._register(toDisposable(() => { - this._editors.original.changeViewZones((a) => { - for (const id of alignmentViewZoneIdsOrig) { a.removeZone(id); } - alignmentViewZoneIdsOrig.clear(); - }); - this._editors.modified.changeViewZones((a) => { - for (const id of alignmentViewZoneIdsMod) { a.removeZone(id); } - alignmentViewZoneIdsMod.clear(); - }); - })); - let ignoreChange = false; this._register(this._editors.original.onDidScrollChange(e => { if (e.scrollLeftChanged && !ignoreChange) { @@ -400,8 +355,8 @@ export class ViewZoneManager extends Disposable { } })); - this._originalScrollTop = observableFromEvent(this._editors.original.onDidScrollChange, () => this._editors.original.getScrollTop()); - this._modifiedScrollTop = observableFromEvent(this._editors.modified.onDidScrollChange, () => this._editors.modified.getScrollTop()); + this._originalScrollTop = observableFromEvent(this._editors.original.onDidScrollChange, () => /** @description original.getScrollTop */ this._editors.original.getScrollTop()); + this._modifiedScrollTop = observableFromEvent(this._editors.modified.onDidScrollChange, () => /** @description modified.getScrollTop */ this._editors.modified.getScrollTop()); // origExtraHeight + origOffset - origScrollTop = modExtraHeight + modOffset - modScrollTop @@ -465,11 +420,6 @@ export class ViewZoneManager extends Disposable { } } -interface IViewZoneWithZoneId extends IViewZone { - // Tells a view zone its id. - setZoneId?(zoneId: string): void; -} - interface ILineRangeAlignment { originalRange: LineRange; modifiedRange: LineRange; diff --git a/src/vs/editor/browser/widget/diffEditor/utils.ts b/src/vs/editor/browser/widget/diffEditor/utils.ts index b847df16668..5cfc72b0c65 100644 --- a/src/vs/editor/browser/widget/diffEditor/utils.ts +++ b/src/vs/editor/browser/widget/diffEditor/utils.ts @@ -7,7 +7,7 @@ import { IDimension } from 'vs/base/browser/dom'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { isHotReloadEnabled, registerHotReloadHandler } from 'vs/base/common/hotReload'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IObservable, IReader, ISettableObservable, autorun, autorunHandleChanges, autorunOpts, observableFromEvent, observableSignalFromEvent, observableValue, transaction } from 'vs/base/common/observable'; +import { IObservable, IReader, ISettableObservable, autorun, autorunHandleChanges, autorunOpts, autorunWithStore, observableFromEvent, observableSignalFromEvent, observableValue, transaction } from 'vs/base/common/observable'; import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver'; import { ICodeEditor, IOverlayWidget, IViewZone } from 'vs/editor/browser/editorBrowser'; import { IModelDeltaDecoration } from 'vs/editor/common/model'; @@ -91,10 +91,10 @@ export class ObservableElementSizeObserver extends Disposable { private readonly elementSizeObserver: ElementSizeObserver; private readonly _width: ISettableObservable; - public get width(): ISettableObservable { return this._width; } + public get width(): IObservable { return this._width; } private readonly _height: ISettableObservable; - public get height(): ISettableObservable { return this._height; } + public get height(): IObservable { return this._height; } constructor(element: HTMLElement | null, dimension: IDimension | undefined) { super(); @@ -208,7 +208,11 @@ export abstract class ViewZoneOverlayWidget extends Disposable { } export interface IObservableViewZone extends IViewZone { + // Causes the view zone to relayout. onChange?: IObservable; + + // Tells a view zone its id. + setZoneId?(zoneId: string): void; } export class PlaceholderViewZone implements IObservableViewZone { @@ -313,37 +317,43 @@ export function observeHotReloadableExports(values: any[], reader: IReader | und } } -export function applyViewZones(editor: ICodeEditor, viewZones: IObservable, setIsUpdating?: (isUpdatingViewZones: boolean) => void): IDisposable { +export function applyViewZones(editor: ICodeEditor, viewZones: IObservable, setIsUpdating?: (isUpdatingViewZones: boolean) => void, zoneIds?: Set): IDisposable { const store = new DisposableStore(); const lastViewZoneIds: string[] = []; - store.add(autorun(reader => { + store.add(autorunWithStore((reader, store) => { /** @description applyViewZones */ const curViewZones = viewZones.read(reader); const viewZonIdsPerViewZone = new Map(); const viewZoneIdPerOnChangeObservable = new Map, string>(); + // Add/remove view zones if (setIsUpdating) { setIsUpdating(true); } editor.changeViewZones(a => { - for (const id of lastViewZoneIds) { a.removeZone(id); } + for (const id of lastViewZoneIds) { a.removeZone(id); zoneIds?.delete(id); } lastViewZoneIds.length = 0; for (const z of curViewZones) { const id = a.addZone(z); + if (z.setZoneId) { + z.setZoneId(id); + } lastViewZoneIds.push(id); + zoneIds?.add(id); viewZonIdsPerViewZone.set(z, id); } }); if (setIsUpdating) { setIsUpdating(false); } + // Layout zone on change store.add(autorunHandleChanges({ createEmptyChangeSummary() { - return [] as string[]; + return { zoneIds: [] as string[] }; }, handleChange(context, changeSummary) { const id = viewZoneIdPerOnChangeObservable.get(context.changedObservable); - if (id !== undefined) { changeSummary.push(id); } + if (id !== undefined) { changeSummary.zoneIds.push(id); } return true; }, }, (reader, changeSummary) => { @@ -355,7 +365,7 @@ export function applyViewZones(editor: ICodeEditor, viewZones: IObservable { for (const id of changeSummary) { a.layoutZone(id); } }); + editor.changeViewZones(a => { for (const id of changeSummary.zoneIds) { a.layoutZone(id); } }); if (setIsUpdating) { setIsUpdating(false); } })); })); @@ -364,6 +374,7 @@ export function applyViewZones(editor: ICodeEditor, viewZones: IObservable { for (const id of lastViewZoneIds) { a.removeZone(id); } }); + zoneIds?.clear(); if (setIsUpdating) { setIsUpdating(false); } } }); From 93351c7436a95cb3bcdcd3f9513a7afe2050ccdc Mon Sep 17 00:00:00 2001 From: Mohammad Reza Gharabaghi <40915667+mrgharabaghi@users.noreply.github.com> Date: Tue, 7 Nov 2023 16:49:05 +0100 Subject: [PATCH 067/240] Update theme-defaults (#197449) * Update dark_vs.json * Update light_modern.json * Update light_vs.json * Update hc_black.json --- extensions/theme-defaults/themes/dark_vs.json | 4 ++-- extensions/theme-defaults/themes/hc_black.json | 4 ++-- extensions/theme-defaults/themes/light_modern.json | 2 +- extensions/theme-defaults/themes/light_vs.json | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/extensions/theme-defaults/themes/dark_vs.json b/extensions/theme-defaults/themes/dark_vs.json index 2b9f0d5a5ab..54d69be0068 100644 --- a/extensions/theme-defaults/themes/dark_vs.json +++ b/extensions/theme-defaults/themes/dark_vs.json @@ -6,8 +6,8 @@ "editor.background": "#1E1E1E", "editor.foreground": "#D4D4D4", "editor.inactiveSelectionBackground": "#3A3D41", - "editorIndentGuide.background": "#404040", - "editorIndentGuide.activeBackground": "#707070", + "editorIndentGuide.background1": "#404040", + "editorIndentGuide.activeBackground1": "#707070", "editor.selectionHighlightBackground": "#ADD6FF26", "list.dropBackground": "#383B3D", "activityBarBadge.background": "#007ACC", diff --git a/extensions/theme-defaults/themes/hc_black.json b/extensions/theme-defaults/themes/hc_black.json index 7b671065646..46ac7e671f8 100644 --- a/extensions/theme-defaults/themes/hc_black.json +++ b/extensions/theme-defaults/themes/hc_black.json @@ -4,8 +4,8 @@ "colors": { "editor.background": "#000000", "editor.foreground": "#FFFFFF", - "editorIndentGuide.background": "#FFFFFF", - "editorIndentGuide.activeBackground": "#FFFFFF", + "editorIndentGuide.background1": "#FFFFFF", + "editorIndentGuide.activeBackground1": "#FFFFFF", "sideBarTitle.foreground": "#FFFFFF", "selection.background": "#008000", "editor.selectionBackground": "#FFFFFF", diff --git a/extensions/theme-defaults/themes/light_modern.json b/extensions/theme-defaults/themes/light_modern.json index a89defee385..b37c6275c24 100644 --- a/extensions/theme-defaults/themes/light_modern.json +++ b/extensions/theme-defaults/themes/light_modern.json @@ -38,7 +38,7 @@ "editorGutter.addedBackground": "#2EA043", "editorGutter.deletedBackground": "#F85149", "editorGutter.modifiedBackground": "#005FB8", - "editorIndentGuide.background": "#D3D3D3", + "editorIndentGuide.background1": "#D3D3D3", "editorLineNumber.activeForeground": "#171184", "editorLineNumber.foreground": "#6E7681", "editorOverviewRuler.border": "#E5E5E5", diff --git a/extensions/theme-defaults/themes/light_vs.json b/extensions/theme-defaults/themes/light_vs.json index 5e2d5a7889e..b093cc73ca3 100644 --- a/extensions/theme-defaults/themes/light_vs.json +++ b/extensions/theme-defaults/themes/light_vs.json @@ -6,8 +6,8 @@ "editor.background": "#FFFFFF", "editor.foreground": "#000000", "editor.inactiveSelectionBackground": "#E5EBF1", - "editorIndentGuide.background": "#D3D3D3", - "editorIndentGuide.activeBackground": "#939393", + "editorIndentGuide.background1": "#D3D3D3", + "editorIndentGuide.activeBackground1": "#939393", "editor.selectionHighlightBackground": "#ADD6FF80", "editorSuggestWidget.background": "#F3F3F3", "activityBarBadge.background": "#007ACC", From 090fd2c7720589cfe0c7b44bb838345bdf874ba3 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 7 Nov 2023 16:49:15 +0100 Subject: [PATCH 068/240] Implements first iteration of multi diff editors. Co-authored-by: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> --- build/lib/i18n.resources.json | 4 + .../lib/stylelint/vscode-known-variables.json | 1 + extensions/git/package.json | 52 +++- extensions/git/package.nls.json | 1 + extensions/git/src/commands.ts | 68 ++++ extensions/git/src/git.ts | 5 + extensions/git/src/repository.ts | 4 + .../browser/viewParts/viewZones/viewZones.ts | 5 + .../editor/browser/widget/codeEditorWidget.ts | 1 - .../widget/diffEditor/diffEditorEditors.ts | 1 - .../diffEditor/diffProviderFactoryService.ts | 1 + .../widget/multiDiffEditorWidget/colors.ts | 13 + .../widget/multiDiffEditorWidget/model.ts | 40 +++ .../multiDiffEditorWidget.ts | 44 +++ .../multiDiffEditorWidgetImpl.ts | 292 ++++++++++++++++++ .../multiDiffEditorWidget/objectPool.ts | 36 +++ .../widget/multiDiffEditorWidget/style.css | 8 + src/vs/editor/common/core/offsetRange.ts | 12 + .../standalone/browser/standaloneEditor.ts | 8 + .../browser/standaloneThemeService.ts | 2 +- src/vs/monaco.d.ts | 2 + .../api/common/extHostApiCommands.ts | 25 ++ src/vs/workbench/api/common/extHostSCM.ts | 2 +- .../browser/parts/editor/editorCommands.ts | 35 ++- src/vs/workbench/common/editor.ts | 27 +- .../common/editor/sideBySideEditorInput.ts | 5 +- .../codeEditor/browser/diffEditorHelper.ts | 2 +- .../browser/multiDiffEditor.contribution.ts | 98 ++++++ .../browser/multiDiffEditor.ts | 63 ++++ .../browser/multiDiffEditorInput.ts | 45 +++ src/vs/workbench/contrib/scm/common/scm.ts | 4 + .../editor/browser/editorResolverService.ts | 11 +- .../editor/common/editorResolverService.ts | 5 +- src/vs/workbench/workbench.common.main.ts | 3 + src/vs/workbench/workbench.desktop.main.ts | 3 + 35 files changed, 914 insertions(+), 14 deletions(-) create mode 100644 src/vs/editor/browser/widget/multiDiffEditorWidget/colors.ts create mode 100644 src/vs/editor/browser/widget/multiDiffEditorWidget/model.ts create mode 100644 src/vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidget.ts create mode 100644 src/vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidgetImpl.ts create mode 100644 src/vs/editor/browser/widget/multiDiffEditorWidget/objectPool.ts create mode 100644 src/vs/editor/browser/widget/multiDiffEditorWidget/style.css create mode 100644 src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor.contribution.ts create mode 100644 src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor.ts create mode 100644 src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index a29d78b2167..cf74aac44be 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -74,6 +74,10 @@ "name": "vs/workbench/contrib/dialogs", "project": "vscode-workbench" }, + { + "name": "vs/workbench/contrib/multiDiffEditor", + "project": "vscode-workbench" + }, { "name": "vs/workbench/contrib/emmet", "project": "vscode-workbench" diff --git a/build/lib/stylelint/vscode-known-variables.json b/build/lib/stylelint/vscode-known-variables.json index 0baec502572..e2203ec77b1 100644 --- a/build/lib/stylelint/vscode-known-variables.json +++ b/build/lib/stylelint/vscode-known-variables.json @@ -417,6 +417,7 @@ "--vscode-minimapSlider-activeBackground", "--vscode-minimapSlider-background", "--vscode-minimapSlider-hoverBackground", + "--vscode-multiDiffEditor-headerBackground", "--vscode-notebook-cellBorderColor", "--vscode-notebook-cellEditorBackground", "--vscode-notebook-cellHoverBackground", diff --git a/extensions/git/package.json b/extensions/git/package.json index 8b1df39dd43..7a20e7ffef1 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -694,6 +694,12 @@ "title": "%command.timelineCompareWithSelected%", "category": "Git" }, + { + "command": "git.timeline.openCommit", + "title": "%command.timelineOpenCommit%", + "icon": "$(wand)", + "category": "Git" + }, { "command": "git.rebaseAbort", "title": "%command.rebaseAbort%", @@ -753,6 +759,18 @@ "command": "git.openRepositoriesInParentFolders", "title": "%command.openRepositoriesInParentFolders%", "category": "Git" + }, + { + "command": "git.viewChanges", + "title": "View Changes", + "icon": "$(search)", + "category": "Git" + }, + { + "command": "git.viewStagedChanges", + "title": "View Staged Changes", + "icon": "$(search)", + "category": "Git" } ], "continueEditSession": [ @@ -1197,6 +1215,10 @@ "command": "git.timeline.compareWithSelected", "when": "false" }, + { + "command": "git.timeline.openCommit", + "when": "false" + }, { "command": "git.closeAllDiffEditors", "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0" @@ -1224,6 +1246,14 @@ { "command": "git.openRepositoriesInParentFolders", "when": "config.git.enabled && !git.missing && git.parentRepositoryCount != 0" + }, + { + "command": "git.viewChanges", + "when": "false" + }, + { + "command": "git.viewStagedChanges", + "when": "false" } ], "scm/title": [ @@ -1390,6 +1420,16 @@ "command": "git.stageAllUntracked", "when": "scmProvider == git && scmResourceGroup == untracked", "group": "inline@2" + }, + { + "command": "git.viewStagedChanges", + "when": "scmProvider == git && scmResourceGroup == index", + "group": "inline@1" + }, + { + "command": "git.viewChanges", + "when": "scmProvider == git && scmResourceGroup == workingTree", + "group": "inline@1" } ], "scm/resourceFolder/context": [ @@ -1767,11 +1807,21 @@ } ], "timeline/item/context": [ + { + "command": "git.timeline.openCommit", + "group": "inline", + "when": "config.git.enabled && !git.missing && timelineItem =~ /git:file:commit\\b/ && !listMultiSelection" + }, { "command": "git.timeline.openDiff", - "group": "1_actions", + "group": "1_actions@1", "when": "config.git.enabled && !git.missing && timelineItem =~ /git:file\\b/ && !listMultiSelection" }, + { + "command": "git.timeline.openCommit", + "group": "1_actions@2", + "when": "config.git.enabled && !git.missing && timelineItem =~ /git:file:commit\\b/ && !listMultiSelection" + }, { "command": "git.timeline.compareWithSelected", "group": "3_compare@1", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 20a807be2cb..5f454ae4008 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -104,6 +104,7 @@ "command.stashDrop": "Drop Stash...", "command.stashDropAll": "Drop All Stashes...", "command.timelineOpenDiff": "Open Changes", + "command.timelineOpenCommit": "Open Commit", "command.timelineCopyCommitId": "Copy Commit ID", "command.timelineCopyCommitMessage": "Copy Commit Message", "command.timelineSelectForCompare": "Select for Compare", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index f6b625a71de..89ca2519c5a 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -3426,6 +3426,54 @@ export class CommandCenter { }; } + @command('git.timeline.openCommit', { repository: false }) + async timelineOpenCommit(item: TimelineItem, uri: Uri | undefined, _source: string) { + console.log('timelineOpenCommit', item); + if (!GitTimelineItem.is(item)) { + return; + } + + const cmd = await this._resolveTimelineOpenCommitCommand( + item, uri, + { + preserveFocus: true, + preview: true, + viewColumn: ViewColumn.Active + }, + ); + if (cmd === undefined) { + return undefined; + } + + return commands.executeCommand(cmd.command, ...(cmd.arguments ?? [])); + } + + private async _resolveTimelineOpenCommitCommand(item: TimelineItem, uri: Uri | undefined, options?: TextDocumentShowOptions): Promise { + if (uri === undefined || uri === null || !GitTimelineItem.is(item)) { + return undefined; + } + + const repository = await this.model.getRepository(uri.fsPath); + if (!repository) { + return undefined; + } + + const commit = await repository.getCommit(item.ref); + const commitFiles = await repository.getCommitFiles(item.ref); + + const args: [Uri, Uri | undefined, Uri | undefined][] = []; + for (const commitFile of commitFiles) { + const commitFileUri = Uri.file(path.join(repository.root, commitFile)); + args.push([commitFileUri, toGitUri(commitFileUri, item.previousRef), toGitUri(commitFileUri, item.ref)]); + } + + return { + command: 'vscode.changes', + title: l10n.t('Open Commit'), + arguments: [`${item.shortRef} - ${commit.message}`, args, options] + }; + } + @command('git.timeline.copyCommitId', { repository: false }) async timelineCopyCommitId(item: TimelineItem, _uri: Uri | undefined, _source: string) { if (!GitTimelineItem.is(item)) { @@ -3603,6 +3651,26 @@ export class CommandCenter { repository.generateCommitMessageCancel(); } + @command('git.viewChanges', { repository: true }) + viewChanges(repository: Repository): void { + this._viewChanges('Changes', repository.workingTreeGroup.resourceStates); + } + + @command('git.viewStagedChanges', { repository: true }) + viewStagedChanges(repository: Repository): void { + this._viewChanges('Staged Changes', repository.indexGroup.resourceStates); + } + + private _viewChanges(title: string, resources: Resource[]): void { + const args: [Uri, Uri | undefined, Uri | undefined][] = []; + + for (const resource of resources) { + args.push([resource.resourceUri, resource.leftUri, resource.rightUri]); + } + + commands.executeCommand('vscode.changes', title, args); + } + private createCommand(id: string, key: string, method: Function, options: ScmCommandOptions): (...args: any[]) => any { const result = (...args: any[]) => { let result: Promise; diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 421cc14b752..f072af20935 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -2552,6 +2552,11 @@ export class Repository { return commits[0]; } + async getCommitFiles(ref: string): Promise { + const result = await this.exec(['diff-tree', '--no-commit-id', '--name-only', '-r', ref]); + return result.stdout.split('\n').filter(l => !!l); + } + async getCommitCount(range: string): Promise<{ ahead: number; behind: number }> { const result = await this.exec(['rev-list', '--count', '--left-right', range]); const [ahead, behind] = result.stdout.trim().split('\t'); diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 21859a62434..cebecfd239a 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -1658,6 +1658,10 @@ export class Repository implements Disposable { return await this.repository.getCommit(ref); } + async getCommitFiles(ref: string): Promise { + return await this.repository.getCommitFiles(ref); + } + async getCommitCount(range: string): Promise<{ ahead: number; behind: number }> { return await this.run(Operation.RevList, () => this.repository.getCommitCount(range)); } diff --git a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts index 37914a70335..c38ac1d72cd 100644 --- a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts +++ b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts @@ -358,6 +358,11 @@ export class ViewZones extends ViewPart { let hasVisibleZone = false; for (const visibleWhitespace of visibleWhitespaces) { + if (!this._zones[visibleWhitespace.id]) { + // This zone got deleted in the meantime? + // TODO@hediet: This should not happen. + continue; + } if (this._zones[visibleWhitespace.id].isInHiddenArea) { continue; } diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index b4cd16d44bd..7ec1c797edb 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1491,7 +1491,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE } this._overlayWidgets[widget.getId()] = widgetData; - if (this._modelData && this._modelData.hasRealView) { this._modelData.view.addOverlayWidget(widgetData); } diff --git a/src/vs/editor/browser/widget/diffEditor/diffEditorEditors.ts b/src/vs/editor/browser/widget/diffEditor/diffEditorEditors.ts index b6d518d4c1c..1b76ed9df95 100644 --- a/src/vs/editor/browser/widget/diffEditor/diffEditorEditors.ts +++ b/src/vs/editor/browser/widget/diffEditor/diffEditorEditors.ts @@ -143,7 +143,6 @@ export class DiffEditorEditors extends Disposable { // Clone scrollbar options before changing them clonedOptions.scrollbar = { ...(clonedOptions.scrollbar || {}) }; - clonedOptions.scrollbar.vertical = 'visible'; clonedOptions.folding = false; clonedOptions.codeLens = this._options.diffCodeLens.get(); clonedOptions.fixedOverflowWidgets = true; diff --git a/src/vs/editor/browser/widget/diffEditor/diffProviderFactoryService.ts b/src/vs/editor/browser/widget/diffEditor/diffProviderFactoryService.ts index 3fe7ebb61d4..6f548bbfa5e 100644 --- a/src/vs/editor/browser/widget/diffEditor/diffProviderFactoryService.ts +++ b/src/vs/editor/browser/widget/diffEditor/diffProviderFactoryService.ts @@ -17,6 +17,7 @@ export interface IDocumentDiffProviderOptions { export interface IDiffProviderFactoryService { readonly _serviceBrand: undefined; + // TODO, don't include IDiffEditor createDiffProvider(editor: IDiffEditor, options: IDocumentDiffProviderOptions): IDocumentDiffProvider; } diff --git a/src/vs/editor/browser/widget/multiDiffEditorWidget/colors.ts b/src/vs/editor/browser/widget/multiDiffEditorWidget/colors.ts new file mode 100644 index 00000000000..5b69dd6c1df --- /dev/null +++ b/src/vs/editor/browser/widget/multiDiffEditorWidget/colors.ts @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { registerColor } from 'vs/platform/theme/common/colorRegistry'; + +export const multiDiffEditorHeaderBackground = registerColor( + 'multiDiffEditor.headerBackground', + { dark: '#808080', light: '#b4b4b4', hcDark: '#808080', hcLight: '#b4b4b4', }, + localize('multiDiffEditor.headerBackground', 'The background color of the diff editor\'s header') +); diff --git a/src/vs/editor/browser/widget/multiDiffEditorWidget/model.ts b/src/vs/editor/browser/widget/multiDiffEditorWidget/model.ts new file mode 100644 index 00000000000..4de8c1a0280 --- /dev/null +++ b/src/vs/editor/browser/widget/multiDiffEditorWidget/model.ts @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from 'vs/base/common/event'; +import { ITextModel } from 'vs/editor/common/model'; + +export interface IMultiDocumentDiffEditorModel { + readonly diffs: LazyPromise[]; + readonly onDidChange: Event; +} + +export interface LazyPromise { + request(): Promise; + readonly value: T | undefined; + readonly onHasValueDidChange: Event; +} + +export class ConstLazyPromise implements LazyPromise { + public readonly onHasValueDidChange = Event.None; + + constructor( + private readonly _value: T + ) { } + + public request(): Promise { + return Promise.resolve(this._value); + } + + public get value(): T { + return this._value; + } +} + +export interface IDiffEntry { + readonly title: string; + readonly original: ITextModel | undefined; // undefined if the file was created. + readonly modified: ITextModel | undefined; // undefined if the file was deleted. +} diff --git a/src/vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidget.ts b/src/vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidget.ts new file mode 100644 index 00000000000..e59063af53b --- /dev/null +++ b/src/vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidget.ts @@ -0,0 +1,44 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Dimension } from 'vs/base/browser/dom'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { derivedWithStore, observableValue, recomputeInitiallyAndOnChange } from 'vs/base/common/observable'; +import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditor/utils'; +import { IMultiDocumentDiffEditorModel } from 'vs/editor/browser/widget/multiDiffEditorWidget/model'; +import { MultiDiffEditorWidgetImpl } from 'vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidgetImpl'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import './colors'; + +export class MultiDiffEditorWidget extends Disposable { + private readonly _dimension = observableValue(this, undefined); + private readonly _model = observableValue(this, undefined); + + private readonly widgetImpl = derivedWithStore(this, (reader, store) => { + return store.add(this._instantiationService.createInstance(( + readHotReloadableExport(MultiDiffEditorWidgetImpl, reader)), + this._element, + this._dimension, + this._model, + )); + }); + + constructor( + private readonly _element: HTMLElement, + @IInstantiationService private readonly _instantiationService: IInstantiationService, + ) { + super(); + + this._register(recomputeInitiallyAndOnChange(this.widgetImpl)); + } + + public setModel(model: IMultiDocumentDiffEditorModel): void { + this._model.set(model, undefined); + } + + public layout(dimension: Dimension): void { + this._dimension.set(dimension, undefined); + } +} diff --git a/src/vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidgetImpl.ts b/src/vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidgetImpl.ts new file mode 100644 index 00000000000..c1c3d74dd52 --- /dev/null +++ b/src/vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidgetImpl.ts @@ -0,0 +1,292 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Dimension, getWindow, h, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; +import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; +import { Disposable, IReference, toDisposable } from 'vs/base/common/lifecycle'; +import { IObservable, IReader, ISettableObservable, autorun, constObservable, observableFromEvent, observableValue } from 'vs/base/common/observable'; +import { globalTransaction } from 'vs/base/common/observableInternal/base'; +import { Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable'; +import 'vs/css!./style'; +import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditor/diffEditorWidget'; +import { ObservableElementSizeObserver } from 'vs/editor/browser/widget/diffEditor/utils'; +import { IDiffEntry, IMultiDocumentDiffEditorModel, LazyPromise } from 'vs/editor/browser/widget/multiDiffEditorWidget/model'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; +import { IDiffEditorViewModel } from 'vs/editor/common/editorCommon'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ILabelService } from 'vs/platform/label/common/label'; +import { ObjectPool } from './objectPool'; + +export class MultiDiffEditorWidgetImpl extends Disposable { + private readonly _elements = h('div', { + style: { + overflowY: 'hidden', + } + }, [ + h('div@content', { + style: { + overflow: 'hidden', + } + }) + ]); + + private readonly _sizeObserver = new ObservableElementSizeObserver(this._element, undefined); + private readonly _documentsObs = this._model.map(this, m => !m ? constObservable([]) : observableFromEvent(m.onDidChange, /** @description Documents changed */() => m.diffs)); + private readonly _documents = this._documentsObs.map(this, (m, reader) => m.read(reader)); + + private readonly _objectPool = new ObjectPool(() => this._instantiationService.createInstance(DiffEditorItemTemplate, this._elements.content)); + + private readonly _hiddenContainer = document.createElement('div'); + + private readonly _editor = this._register(this._instantiationService.createInstance(DiffEditorWidget, this._hiddenContainer, { + hideUnchangedRegions: { + enabled: true, + }, + }, {})); + + private readonly _viewItems = this._documents.map(this, + docs => docs.map(d => new DiffEditorItem(this._objectPool, d, this._editor)) + ); + + private readonly _totalHeight = this._viewItems.map(this, (items, reader) => items.reduce((r, i) => r + i.contentHeight.read(reader), 0)); + + private readonly scrollTop: IObservable; + + constructor( + private readonly _element: HTMLElement, + private readonly _dimension: IObservable, + private readonly _model: IObservable, + @IInstantiationService private readonly _instantiationService: IInstantiationService, + ) { + super(); + + this._sizeObserver.setAutomaticLayout(true); + + this._register(autorun((reader) => { + /** @description Update widget dimension */ + const dimension = this._dimension.read(reader); + this._sizeObserver.observe(dimension); + })); + + const scrollable = this._register(new Scrollable({ + forceIntegerValues: false, + scheduleAtNextAnimationFrame: (cb) => scheduleAtNextAnimationFrame(getWindow(_element), cb), + smoothScrollDuration: 100, + })); + + this._elements.content.style.position = 'relative'; + + const scrollableElement = this._register(new SmoothScrollableElement(this._elements.root, { + vertical: ScrollbarVisibility.Auto, + className: 'monaco-component', + }, scrollable)); + + this.scrollTop = observableFromEvent(scrollableElement.onScroll, () => /** @description onScroll */ scrollableElement.getScrollPosition().scrollTop); + + this._register(autorun((reader) => { + /** @description Update scroll dimensions */ + const height = this._sizeObserver.height.read(reader); + this._elements.root.style.height = `${height}px`; + const totalHeight = this._totalHeight.read(reader); + this._elements.content.style.height = `${totalHeight}px`; + scrollableElement.setScrollDimensions({ + width: _element.clientWidth, + height: height, + scrollHeight: totalHeight, + scrollWidth: _element.clientWidth, + }); + })); + + _element.replaceChildren(scrollableElement.getDomNode()); + this._register(toDisposable(() => { + _element.replaceChildren(); + })); + + this._register(this._register(autorun(reader => { + /** @description Render all */ + this.render(reader); + }))); + } + + private render(reader: IReader | undefined) { + const scrollTop = this.scrollTop.read(reader); + let contentScrollOffsetToScrollOffset = 0; + let itemHeightSumBefore = 0; + let itemContentHeightSumBefore = 0; + const viewPortHeight = this._elements.root.clientHeight; + const contentViewPort = OffsetRange.ofStartAndLength(scrollTop, viewPortHeight); + + const width = this._elements.content.clientWidth; + + for (const v of this._viewItems.read(reader)) { + const itemContentHeight = v.contentHeight.read(reader); + const itemHeight = Math.min(itemContentHeight, viewPortHeight); + const itemRange = OffsetRange.ofStartAndLength(itemHeightSumBefore, itemHeight); + const itemContentRange = OffsetRange.ofStartAndLength(itemContentHeightSumBefore, itemContentHeight); + + if (itemContentRange.isBefore(contentViewPort)) { + contentScrollOffsetToScrollOffset -= itemContentHeight - itemHeight; + v.hide(); + } else if (itemContentRange.isAfter(contentViewPort)) { + v.hide(); + } else { + const scroll = Math.max(0, Math.min(contentViewPort.start - itemContentRange.start, itemContentHeight - itemHeight)); + v.render(itemRange, scroll, width); + contentScrollOffsetToScrollOffset -= scroll; + } + + itemHeightSumBefore += itemHeight; + itemContentHeightSumBefore += itemContentHeight; + } + + this._elements.content.style.transform = `translateY(${-(scrollTop + contentScrollOffsetToScrollOffset)}px)`; + } +} + +class DiffEditorItem { + private readonly _height = observableValue(this, 500); + public readonly contentHeight: IObservable = this._height; + private _templateRef: IReference | undefined; + + private _vm: IDiffEditorViewModel | undefined; + + constructor( + private readonly _objectPool: ObjectPool, + private readonly _entry: LazyPromise, + baseDiffEditorWidget: DiffEditorWidget, + ) { + this._vm = baseDiffEditorWidget.createViewModel({ + original: _entry.value!.original!, + modified: _entry.value!.modified!, + }); + } + + public toString(): string { + return `ViewItem(${this._entry.value!.title})`; + } + + public hide(): void { + this._templateRef?.object.hide(); + this._templateRef?.dispose(); + this._templateRef = undefined; + } + + public render(verticalSpace: OffsetRange, offset: number, width: number): void { + if (!this._templateRef) { + this._templateRef = this._objectPool.getUnusedObj(); + this._templateRef.object.setData({ height: this._height, viewModel: this._vm!, entry: this._entry.value! }); + } + this._templateRef.object.render(verticalSpace, width, offset); + } +} + +class DiffEditorItemTemplate extends Disposable { + private _height: number = 500; + private _heightObs: ISettableObservable | undefined = undefined; + + private readonly _elements = h('div', { + style: { + display: 'flex', + flexDirection: 'column', + + } + }, [ + h('div', { + style: { + display: 'flex', + flexDirection: 'column', + + flex: '1', + border: '1px solid #4d4d4d', + borderRadius: '5px', + overflow: 'hidden', + margin: '10px 10px 10px 10px', + } + }, [ + + h('div', { style: { display: 'flex', alignItems: 'center', padding: '8px 5px', background: 'var(--vscode-multiDiffEditor-headerBackground)', color: 'black' } }, [ + //h('div.expand-button@collapseButton', { style: { margin: '0 5px' } }), + h('div@title', { style: { fontSize: '14px' } }, ['Title'] as any), + ]), + + h('div', { + style: { + flex: '1', + display: 'flex', + flexDirection: 'column', + } + }, [ + h('div@editor', { style: { flex: '1' } }), + ]) + + ]) + ]); + + private readonly editor = this._register(this._instantiationService.createInstance(DiffEditorWidget, this._elements.editor, { + automaticLayout: true, + scrollBeyondLastLine: false, + hideUnchangedRegions: { + enabled: true, + }, + scrollbar: { + vertical: 'hidden', + handleMouseWheel: false, + }, + renderOverviewRuler: false, + }, { + modifiedEditor: { + contributions: [], + }, + originalEditor: { + contributions: [], + } + })); + + constructor( + private readonly _container: HTMLElement, + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @ILabelService private readonly _labelService: ILabelService, + ) { + super(); + + // TODO@hediet + /* + const btn = new Button(this._elements.collapseButton, {}); + btn.icon = Codicon.chevronDown; + */ + + this._register(this.editor.onDidContentSizeChange(e => { + this._height = e.contentHeight + this._elements.root.clientHeight - this._elements.editor.clientHeight; + globalTransaction(tx => { + this._heightObs?.set(this._height, tx); + }); + })); + + this._container.appendChild(this._elements.root); + } + + public setData(data: { height: ISettableObservable; viewModel: IDiffEditorViewModel; entry: IDiffEntry }) { + this._heightObs = data.height; + globalTransaction(tx => { + this.editor.setModel(data.viewModel, tx); + this._heightObs!.set(this._height, tx); + }); + this._elements.title.innerText = this._labelService.getUriLabel(data.viewModel.model.modified.uri, { relative: true }); // data.entry.title; + } + + public hide(): void { + this._elements.root.style.top = `-100000px`; + this._elements.root.style.visibility = 'hidden'; // Some editor parts are still visible + } + + public render(verticalRange: OffsetRange, width: number, editorScroll: number): void { + this._elements.root.style.visibility = 'visible'; + this._elements.root.style.top = `${verticalRange.start}px`; + this._elements.root.style.height = `${verticalRange.length}px`; + this._elements.root.style.width = `${width}px`; + this._elements.root.style.position = 'absolute'; + this.editor.getOriginalEditor().setScrollTop(editorScroll); + } +} diff --git a/src/vs/editor/browser/widget/multiDiffEditorWidget/objectPool.ts b/src/vs/editor/browser/widget/multiDiffEditorWidget/objectPool.ts new file mode 100644 index 00000000000..95954589a40 --- /dev/null +++ b/src/vs/editor/browser/widget/multiDiffEditorWidget/objectPool.ts @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { IDisposable, IReference } from 'vs/base/common/lifecycle'; + +export class ObjectPool { + private readonly _unused = new Set(); + private readonly _used = new Set(); + + constructor( + private readonly _create: () => T + ) { } + + public getUnusedObj(): IReference { + let obj: T; + if (this._unused.size === 0) { + obj = this._create(); + } else { + obj = this._unused.values().next().value; + this._unused.delete(obj); + } + this._used.add(obj); + return { + object: obj, + dispose: () => { + this._used.delete(obj); + if (this._unused.size > 5) { + obj.dispose(); + } else { + this._unused.add(obj); + } + } + }; + } +} diff --git a/src/vs/editor/browser/widget/multiDiffEditorWidget/style.css b/src/vs/editor/browser/widget/multiDiffEditorWidget/style.css new file mode 100644 index 00000000000..7206dda8cf6 --- /dev/null +++ b/src/vs/editor/browser/widget/multiDiffEditorWidget/style.css @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.monaco-component .expand-button a { + display: block; +} diff --git a/src/vs/editor/common/core/offsetRange.ts b/src/vs/editor/common/core/offsetRange.ts index 7e78d30b591..5efa09faecc 100644 --- a/src/vs/editor/common/core/offsetRange.ts +++ b/src/vs/editor/common/core/offsetRange.ts @@ -43,6 +43,10 @@ export class OffsetRange implements IOffsetRange { return new OffsetRange(0, length); } + public static ofStartAndLength(start: number, length: number): OffsetRange { + return new OffsetRange(start, start + length); + } + constructor(public readonly start: number, public readonly endExclusive: number) { if (start > endExclusive) { throw new BugIndicatingError(`Invalid range: ${this.toString()}`); @@ -114,6 +118,14 @@ export class OffsetRange implements IOffsetRange { return start <= end; } + public isBefore(other: OffsetRange): boolean { + return this.endExclusive <= other.start; + } + + public isAfter(other: OffsetRange): boolean { + return this.start >= other.endExclusive; + } + public slice(arr: T[]): T[] { return arr.slice(this.start, this.endExclusive); } diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index 92cf32cf2d5..903e20e1151 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -38,6 +38,7 @@ import { ITextResourceEditorInput } from 'vs/platform/editor/common/editor'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IMarker, IMarkerData, IMarkerService } from 'vs/platform/markers/common/markers'; import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { MultiDiffEditorWidget } from 'vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidget'; /** * Create a new editor under `domElement`. @@ -98,6 +99,11 @@ export function createDiffEditor(domElement: HTMLElement, options?: IStandaloneD return instantiationService.createInstance(StandaloneDiffEditor2, domElement, options); } +export function createMultiFileDiffEditor(domElement: HTMLElement, override?: IEditorOverrideServices) { + const instantiationService = StandaloneServices.initialize(override || {}); + return new MultiDiffEditorWidget(domElement, instantiationService); +} + /** * Description of a command contribution */ @@ -567,6 +573,8 @@ export function createMonacoEditorAPI(): typeof monaco.editor { ApplyUpdateResult: ApplyUpdateResult, EditorZoom: EditorZoom, + createMultiFileDiffEditor: createMultiFileDiffEditor, + // vars EditorType: EditorType, EditorOptions: EditorOptions diff --git a/src/vs/editor/standalone/browser/standaloneThemeService.ts b/src/vs/editor/standalone/browser/standaloneThemeService.ts index 0d1810873da..5fc765ed2d1 100644 --- a/src/vs/editor/standalone/browser/standaloneThemeService.ts +++ b/src/vs/editor/standalone/browser/standaloneThemeService.ts @@ -393,7 +393,7 @@ export class StandaloneThemeService extends Disposable implements IStandaloneThe colorVariables.push(`${asCssVariableName(item.id)}: ${color.toString()};`); } } - ruleCollector.addRule(`.monaco-editor, .monaco-diff-editor { ${colorVariables.join('\n')} }`); + ruleCollector.addRule(`.monaco-editor, .monaco-diff-editor, .monaco-component { ${colorVariables.join('\n')} }`); const colorMap = this._colorMapOverride || this._theme.tokenTheme.getColorMap(); ruleCollector.addRule(generateTokensCSSForColorMap(colorMap)); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index e45bb5af784..eee22193298 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -974,6 +974,8 @@ declare namespace monaco.editor { */ export function createDiffEditor(domElement: HTMLElement, options?: IStandaloneDiffEditorConstructionOptions, override?: IEditorOverrideServices): IStandaloneDiffEditor; + export function createMultiFileDiffEditor(domElement: HTMLElement, override?: IEditorOverrideServices): any; + /** * Description of a command contribution */ diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index e79c39ceee6..7412cb9168a 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -432,6 +432,31 @@ const newCommands: ApiCommand[] = [ ], ApiCommandResult.Void ), + new ApiCommand( + 'vscode.changes', '_workbench.changes', 'Opens a list of resources in the changes editor to compare their contents.', + [ + ApiCommandArgument.String.with('title', 'Human readable title for the changes editor'), + new ApiCommandArgument<[URI, URI?, URI?][]>('resourceList', 'List of resources to compare', + resources => { + for (const resource of resources) { + if (resource.length !== 3) { + return false; + } + + const [label, left, right] = resource; + if (!URI.isUri(label) || + (!URI.isUri(left) && left !== undefined && left !== null) || + (!URI.isUri(right) && right !== undefined && right !== null)) { + return false; + } + } + + return true; + }, + v => v) + ], + ApiCommandResult.Void + ), // --- type hierarchy new ApiCommand( 'vscode.prepareTypeHierarchy', '_executePrepareTypeHierarchy', 'Prepare type hierarchy at a position inside a document', diff --git a/src/vs/workbench/api/common/extHostSCM.ts b/src/vs/workbench/api/common/extHostSCM.ts index fe6da7f00c0..6a7132ad998 100644 --- a/src/vs/workbench/api/common/extHostSCM.ts +++ b/src/vs/workbench/api/common/extHostSCM.ts @@ -461,7 +461,7 @@ class ExtHostSourceControlResourceGroup implements vscode.SourceControlResourceG let command: ICommandDto | undefined; if (r.command) { - if (r.command.command === 'vscode.open' || r.command.command === 'vscode.diff') { + if (r.command.command === 'vscode.open' || r.command.command === 'vscode.diff' || r.command.command === 'vscode.changes') { const disposables = new DisposableStore(); command = this._commands.converter.toInternal(r.command, disposables); this._resourceStatesDisposablesMap.set(handle, disposables); diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index f8c4178a374..74bcd105029 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -7,7 +7,7 @@ import { localize } from 'vs/nls'; import { isObject, isString, isUndefined, isNumber } from 'vs/base/common/types'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { IEditorIdentifier, IEditorCommandsContext, CloseDirection, IVisibleEditorPane, EditorsOrder, EditorInputCapabilities, isEditorIdentifier, isEditorInputWithOptionsAndGroup, IUntitledTextResourceEditorInput } from 'vs/workbench/common/editor'; +import { IEditorIdentifier, IEditorCommandsContext, CloseDirection, IVisibleEditorPane, EditorsOrder, EditorInputCapabilities, isEditorIdentifier, isEditorInputWithOptionsAndGroup, IUntitledTextResourceEditorInput, IResourceDiffEditorInput } from 'vs/workbench/common/editor'; import { TextCompareEditorVisibleContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, ActiveEditorStickyContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, TextCompareEditorActiveContext, SideBySideEditorActiveContext } from 'vs/workbench/common/contextkeys'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { EditorGroupColumn, columnToEditorGroup } from 'vs/workbench/services/editor/common/editorGroupColumn'; @@ -632,6 +632,39 @@ function registerOpenEditorAPICommands(): void { await editorService.openEditor({ resource: URI.from(resource, true), options: { ...optionsArg, pinned: true, override: id } }, columnToEditorGroup(editorGroupsService, configurationService, columnArg)); }); + + // partial, renderer-side API command to open diff editor + // complements https://github.com/microsoft/vscode/blob/2b164efb0e6a5de3826bff62683eaeafe032284f/src/vs/workbench/api/common/extHostApiCommands.ts#L397 + CommandsRegistry.registerCommand({ + id: 'vscode.changes', + handler: (accessor, title: string, resources: [UriComponents, UriComponents?, UriComponents?][]) => { + accessor.get(ICommandService).executeCommand('_workbench.changes', title, resources); + }, + metadata: { + description: 'Opens a list of resources in the changes editor to compare their contents.', + args: [ + { name: 'title', description: 'Human readable title for the diff editor' }, + { name: 'resources', description: 'List of resources to open in the changes editor' } + ] + } + }); + + CommandsRegistry.registerCommand('_workbench.changes', async (accessor: ServicesAccessor, title: string, resources: [UriComponents, UriComponents?, UriComponents?][]) => { + const editorService = accessor.get(IEditorService); + // const editorGroupService = accessor.get(IEditorGroupsService); + // const configurationService = accessor.get(IConfigurationService); + + const editor: (IResourceDiffEditorInput & { resource: URI })[] = []; + for (const [label, original, modified] of resources) { + editor.push({ + resource: URI.revive(label), + original: { resource: URI.revive(original) }, + modified: { resource: URI.revive(modified) }, + }); + } + + await editorService.openEditor({ resources: editor, label: title }); + }); } function registerOpenEditorAtIndexCommands(): void { diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index bb796afcae8..c812971023b 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -489,6 +489,17 @@ export interface IResourceDiffEditorInput extends IBaseUntypedEditorInput { readonly modified: IResourceEditorInput | ITextResourceEditorInput | IUntitledTextResourceEditorInput; } +/** + * A resource list diff editor input compares multiple resources side by side + * highlighting the differences. + */ +export interface IResourceMultiDiffEditorInput extends IBaseUntypedEditorInput { + /** + * The list of resources to compare. + */ + readonly resources: (IResourceDiffEditorInput & { resource: URI })[]; +} + export type IResourceMergeEditorInputSide = (IResourceEditorInput | ITextResourceEditorInput) & { detail?: string }; /** @@ -541,6 +552,16 @@ export function isResourceDiffEditorInput(editor: unknown): editor is IResourceD return candidate?.original !== undefined && candidate.modified !== undefined; } +export function isResourceDiffListEditorInput(editor: unknown): editor is IResourceMultiDiffEditorInput { + if (isEditorInput(editor)) { + return false; // make sure to not accidentally match on typed editor inputs + } + + const candidate = editor as IResourceMultiDiffEditorInput | undefined; + + return Array.isArray(candidate?.resources); +} + export function isResourceSideBySideEditorInput(editor: unknown): editor is IResourceSideBySideEditorInput { if (isEditorInput(editor)) { return false; // make sure to not accidentally match on typed editor inputs @@ -760,7 +781,7 @@ export const enum EditorInputCapabilities { AuxWindowUnsupported = 1 << 10 } -export type IUntypedEditorInput = IResourceEditorInput | ITextResourceEditorInput | IUntitledTextResourceEditorInput | IResourceDiffEditorInput | IResourceSideBySideEditorInput | IResourceMergeEditorInput; +export type IUntypedEditorInput = IResourceEditorInput | ITextResourceEditorInput | IUntitledTextResourceEditorInput | IResourceDiffEditorInput | IResourceMultiDiffEditorInput | IResourceSideBySideEditorInput | IResourceMergeEditorInput; export abstract class AbstractEditorInput extends Disposable { // Marker class for implementing `isEditorInput` @@ -1260,7 +1281,7 @@ class EditorResourceAccessorImpl { } } - if (isResourceDiffEditorInput(editor) || isResourceSideBySideEditorInput(editor) || isResourceMergeEditorInput(editor)) { + if (isResourceDiffEditorInput(editor) || isResourceDiffListEditorInput(editor) || isResourceSideBySideEditorInput(editor) || isResourceMergeEditorInput(editor)) { return undefined; } @@ -1329,7 +1350,7 @@ class EditorResourceAccessorImpl { } } - if (isResourceDiffEditorInput(editor) || isResourceSideBySideEditorInput(editor) || isResourceMergeEditorInput(editor)) { + if (isResourceDiffEditorInput(editor) || isResourceDiffListEditorInput(editor) || isResourceSideBySideEditorInput(editor) || isResourceMergeEditorInput(editor)) { return undefined; } diff --git a/src/vs/workbench/common/editor/sideBySideEditorInput.ts b/src/vs/workbench/common/editor/sideBySideEditorInput.ts index beee39963a2..e852dd7b2bb 100644 --- a/src/vs/workbench/common/editor/sideBySideEditorInput.ts +++ b/src/vs/workbench/common/editor/sideBySideEditorInput.ts @@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Registry } from 'vs/platform/registry/common/platform'; -import { EditorInputCapabilities, GroupIdentifier, ISaveOptions, IRevertOptions, EditorExtensions, IEditorFactoryRegistry, IEditorSerializer, ISideBySideEditorInput, IUntypedEditorInput, isResourceSideBySideEditorInput, isDiffEditorInput, isResourceDiffEditorInput, IResourceSideBySideEditorInput, findViewStateForEditor, IMoveResult, isEditorInput, isResourceEditorInput, Verbosity, isResourceMergeEditorInput } from 'vs/workbench/common/editor'; +import { EditorInputCapabilities, GroupIdentifier, ISaveOptions, IRevertOptions, EditorExtensions, IEditorFactoryRegistry, IEditorSerializer, ISideBySideEditorInput, IUntypedEditorInput, isResourceSideBySideEditorInput, isDiffEditorInput, isResourceDiffEditorInput, IResourceSideBySideEditorInput, findViewStateForEditor, IMoveResult, isEditorInput, isResourceEditorInput, Verbosity, isResourceMergeEditorInput, isResourceDiffListEditorInput } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -190,7 +190,7 @@ export class SideBySideEditorInput extends EditorInput implements ISideBySideEdi return new SideBySideEditorInput(this.preferredName, this.preferredDescription, primarySaveResult, primarySaveResult, this.editorService); } - if (!isResourceDiffEditorInput(primarySaveResult) && !isResourceSideBySideEditorInput(primarySaveResult) && !isResourceMergeEditorInput(primarySaveResult)) { + if (!isResourceDiffEditorInput(primarySaveResult) && !isResourceDiffListEditorInput(primarySaveResult) && !isResourceSideBySideEditorInput(primarySaveResult) && !isResourceMergeEditorInput(primarySaveResult)) { return { primary: primarySaveResult, secondary: primarySaveResult, @@ -259,6 +259,7 @@ export class SideBySideEditorInput extends EditorInput implements ISideBySideEdi if ( primaryResourceEditorInput && secondaryResourceEditorInput && !isResourceDiffEditorInput(primaryResourceEditorInput) && !isResourceDiffEditorInput(secondaryResourceEditorInput) && + !isResourceDiffListEditorInput(primaryResourceEditorInput) && !isResourceDiffListEditorInput(secondaryResourceEditorInput) && !isResourceSideBySideEditorInput(primaryResourceEditorInput) && !isResourceSideBySideEditorInput(secondaryResourceEditorInput) && !isResourceMergeEditorInput(primaryResourceEditorInput) && !isResourceMergeEditorInput(secondaryResourceEditorInput) ) { diff --git a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts index a6a66ffd952..666ea74dd6a 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts @@ -43,7 +43,7 @@ class DiffEditorHelperContribution extends Disposable implements IDiffEditorCont const isEmbeddedDiffEditor = this._diffEditor instanceof EmbeddedDiffEditorWidget; if (!isEmbeddedDiffEditor) { - const computationResult = observableFromEvent(e => this._diffEditor.onDidUpdateDiff(e), () => /** diffEditor.diffComputationResult */ this._diffEditor.getDiffComputationResult()); + const computationResult = observableFromEvent(e => this._diffEditor.onDidUpdateDiff(e), () => /** @description diffEditor.diffComputationResult */ this._diffEditor.getDiffComputationResult()); const onlyWhiteSpaceChange = computationResult.map(r => r && !r.identical && r.changes2.length === 0); this._register(autorunWithStore((reader, store) => { diff --git a/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor.contribution.ts b/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor.contribution.ts new file mode 100644 index 00000000000..19a8cc28e66 --- /dev/null +++ b/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor.contribution.ts @@ -0,0 +1,98 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor'; +import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; +import { DEFAULT_EDITOR_ASSOCIATION, EditorExtensions, EditorInputWithOptions, IEditorFactoryRegistry, IEditorSerializer, IResourceMultiDiffEditorInput } from 'vs/workbench/common/editor'; +import { EditorInput } from 'vs/workbench/common/editor/editorInput'; +import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; +import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; +import { parse } from 'vs/base/common/marshalling'; +import { onUnexpectedError } from 'vs/base/common/errors'; +import { MultiDiffEditorInput, MultiDiffEditorInputData } from 'vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput'; +import { MultiDiffEditor } from 'vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor'; + +class MultiDiffEditorResolverContribution extends Disposable { + + constructor( + @IEditorResolverService editorResolverService: IEditorResolverService, + @IInstantiationService instantiationService: IInstantiationService, + ) { + super(); + + this._register(editorResolverService.registerEditor( + `*`, + { + id: DEFAULT_EDITOR_ASSOCIATION.id, + label: DEFAULT_EDITOR_ASSOCIATION.displayName, + detail: DEFAULT_EDITOR_ASSOCIATION.providerDisplayName, + priority: RegisteredEditorPriority.builtin + }, + {}, + { + createMultiDiffEditorInput: (diffListEditor: IResourceMultiDiffEditorInput): EditorInputWithOptions => { + return { + editor: instantiationService.createInstance( + MultiDiffEditorInput, + diffListEditor.label, + diffListEditor.resources.map(resource => { + return new MultiDiffEditorInputData( + resource.resource, + resource.original.resource, + resource.modified.resource + ); + })) + }; + } + } + )); + } +} + +Registry + .as(WorkbenchExtensions.Workbench) + .registerWorkbenchContribution(MultiDiffEditorResolverContribution, LifecyclePhase.Starting); + +class MultiDiffEditorSerializer implements IEditorSerializer { + + canSerialize(editor: EditorInput): boolean { + return true; + } + + serialize(editor: MultiDiffEditorInput): string | undefined { + return JSON.stringify({ label: editor.label, resources: editor.resources }); + } + + deserialize(instantiationService: IInstantiationService, serializedEditor: string): EditorInput | undefined { + try { + const data = parse(serializedEditor) as { label: string | undefined; resources: MultiDiffEditorInputData[] }; + return instantiationService.createInstance(MultiDiffEditorInput, data.label, data.resources); + } catch (err) { + onUnexpectedError(err); + return undefined; + } + } +} + +Registry.as(EditorExtensions.EditorPane).registerEditorPane( + EditorPaneDescriptor.create( + MultiDiffEditor, + MultiDiffEditor.ID, + localize('name', "Multi Diff Editor") + ), + [ + new SyncDescriptor(MultiDiffEditorInput) + ] +); + +Registry.as(EditorExtensions.EditorFactory).registerEditorSerializer( + MultiDiffEditorInput.ID, + MultiDiffEditorSerializer +); diff --git a/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor.ts b/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor.ts new file mode 100644 index 00000000000..6ca92292e4c --- /dev/null +++ b/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor.ts @@ -0,0 +1,63 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as DOM from 'vs/base/browser/dom'; +import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; +import { IEditorOpenContext } from 'vs/workbench/common/editor'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IStorageService } from 'vs/platform/storage/common/storage'; +import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IEditorOptions } from 'vs/platform/editor/common/editor'; +import { ITextModelService } from 'vs/editor/common/services/resolverService'; +import { MultiDiffEditorInput } from 'vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput'; +import { MultiDiffEditorWidget } from 'vs/editor/browser/widget/multiDiffEditorWidget/multiDiffEditorWidget'; +import { toDisposable } from 'vs/base/common/lifecycle'; +import { ConstLazyPromise, IDiffEntry } from 'vs/editor/browser/widget/multiDiffEditorWidget/model'; + +export class MultiDiffEditor extends EditorPane { + static readonly ID = 'multiDiffEditor'; + + private _multiDiffEditorWidget: MultiDiffEditorWidget | undefined = undefined; + + constructor( + @IInstantiationService private readonly instantiationService: InstantiationService, + @ITelemetryService telemetryService: ITelemetryService, + @ITextModelService private readonly textModelService: ITextModelService, + @IThemeService themeService: IThemeService, + @IStorageService storageService: IStorageService + ) { + super(MultiDiffEditor.ID, telemetryService, themeService, storageService); + } + + protected createEditor(parent: HTMLElement): void { + this._multiDiffEditorWidget = this._register(this.instantiationService.createInstance(MultiDiffEditorWidget, parent)); + } + + override async setInput(input: MultiDiffEditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise { + await super.setInput(input, options, context, token); + + const rs = await Promise.all(input.resources.map(async r => ({ + originalRef: await this.textModelService.createModelReference(r.original!), + modifiedRef: await this.textModelService.createModelReference(r.modified!), + title: r.resource.fsPath, + }))); + + this._multiDiffEditorWidget?.setModel({ + onDidChange: () => toDisposable(() => { }), + diffs: rs.map(r => new ConstLazyPromise({ + original: r.originalRef.object.textEditorModel, + modified: r.modifiedRef.object.textEditorModel, + title: r.title, + })), + }); + } + + layout(dimension: DOM.Dimension): void { + this._multiDiffEditorWidget?.layout(dimension); + } +} diff --git a/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts b/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts new file mode 100644 index 00000000000..59b39f6e714 --- /dev/null +++ b/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { URI } from 'vs/base/common/uri'; +import { DEFAULT_EDITOR_ASSOCIATION, EditorInputCapabilities } from 'vs/workbench/common/editor'; +import { EditorInput } from 'vs/workbench/common/editor/editorInput'; + +export class MultiDiffEditorInput extends EditorInput { + static readonly ID: string = 'workbench.input.multiDiffEditor'; + + get resource(): URI | undefined { + return undefined; + } + + override get capabilities(): EditorInputCapabilities { + return EditorInputCapabilities.Readonly; + } + + override get typeId(): string { + return MultiDiffEditorInput.ID; + } + + override getName(): string { + return this.label ?? localize('name', "Multi Diff Editor"); + } + + override get editorId(): string { + return DEFAULT_EDITOR_ASSOCIATION.id; + } + + constructor(readonly label: string | undefined, readonly resources: readonly MultiDiffEditorInputData[]) { + super(); + } +} + +export class MultiDiffEditorInputData { + constructor( + readonly resource: URI, + readonly original: URI | undefined, + readonly modified: URI | undefined + ) { } +} diff --git a/src/vs/workbench/contrib/scm/common/scm.ts b/src/vs/workbench/contrib/scm/common/scm.ts index 5f36dd36800..61262c27ef7 100644 --- a/src/vs/workbench/contrib/scm/common/scm.ts +++ b/src/vs/workbench/contrib/scm/common/scm.ts @@ -227,3 +227,7 @@ export interface ISCMViewService { readonly onDidFocusRepository: Event; focus(repository: ISCMRepository): void; } + +export const SCM_CHANGES_EDITOR_ID = 'workbench.editor.scmChangesEditor'; + +export interface ISCMChangesEditor { } diff --git a/src/vs/workbench/services/editor/browser/editorResolverService.ts b/src/vs/workbench/services/editor/browser/editorResolverService.ts index a8b940dcf9a..b8d99e5772a 100644 --- a/src/vs/workbench/services/editor/browser/editorResolverService.ts +++ b/src/vs/workbench/services/editor/browser/editorResolverService.ts @@ -10,7 +10,7 @@ import { basename, extname, isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { EditorActivation, EditorResolution, IEditorOptions } from 'vs/platform/editor/common/editor'; -import { DEFAULT_EDITOR_ASSOCIATION, EditorResourceAccessor, EditorInputWithOptions, IResourceSideBySideEditorInput, isEditorInputWithOptions, isEditorInputWithOptionsAndGroup, isResourceDiffEditorInput, isResourceSideBySideEditorInput, isUntitledResourceEditorInput, isResourceMergeEditorInput, IUntypedEditorInput, SideBySideEditor } from 'vs/workbench/common/editor'; +import { DEFAULT_EDITOR_ASSOCIATION, EditorResourceAccessor, EditorInputWithOptions, IResourceSideBySideEditorInput, isEditorInputWithOptions, isEditorInputWithOptionsAndGroup, isResourceDiffEditorInput, isResourceSideBySideEditorInput, isUntitledResourceEditorInput, isResourceMergeEditorInput, IUntypedEditorInput, SideBySideEditor, isResourceDiffListEditorInput } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { Schemas } from 'vs/base/common/network'; @@ -463,6 +463,15 @@ export class EditorResolverService extends Disposable implements IEditorResolver return { editor: inputWithOptions.editor, options: inputWithOptions.options ?? options }; } + // If it's a diff list editor we trigger the create diff list editor input + if (isResourceDiffListEditorInput(editor)) { + if (!selectedEditor.editorFactoryObject.createMultiDiffEditorInput) { + return; + } + const inputWithOptions = await selectedEditor.editorFactoryObject.createMultiDiffEditorInput(editor, group); + return { editor: inputWithOptions.editor, options: inputWithOptions.options ?? options }; + } + if (isResourceSideBySideEditorInput(editor)) { throw new Error(`Untyped side by side editor input not supported here.`); } diff --git a/src/vs/workbench/services/editor/common/editorResolverService.ts b/src/vs/workbench/services/editor/common/editorResolverService.ts index 9c5d16f9abd..cd571b4d9e2 100644 --- a/src/vs/workbench/services/editor/common/editorResolverService.ts +++ b/src/vs/workbench/services/editor/common/editorResolverService.ts @@ -16,7 +16,7 @@ import { Extensions as ConfigurationExtensions, IConfigurationNode, IConfigurati import { IResourceEditorInput, ITextResourceEditorInput } from 'vs/platform/editor/common/editor'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { Registry } from 'vs/platform/registry/common/platform'; -import { EditorInputWithOptions, EditorInputWithOptionsAndGroup, IResourceDiffEditorInput, IResourceMergeEditorInput, IUntitledTextResourceEditorInput, IUntypedEditorInput } from 'vs/workbench/common/editor'; +import { EditorInputWithOptions, EditorInputWithOptionsAndGroup, IResourceDiffEditorInput, IResourceMultiDiffEditorInput, IResourceMergeEditorInput, IUntitledTextResourceEditorInput, IUntypedEditorInput } from 'vs/workbench/common/editor'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { PreferredGroup } from 'vs/workbench/services/editor/common/editorService'; import { AtLeastOne } from 'vs/base/common/types'; @@ -108,12 +108,15 @@ export type UntitledEditorInputFactoryFunction = (untitledEditorInput: IUntitled export type DiffEditorInputFactoryFunction = (diffEditorInput: IResourceDiffEditorInput, group: IEditorGroup) => EditorInputFactoryResult; +export type DiffListEditorInputFactoryFunction = (diffEditorInput: IResourceMultiDiffEditorInput, group: IEditorGroup) => EditorInputFactoryResult; + export type MergeEditorInputFactoryFunction = (mergeEditorInput: IResourceMergeEditorInput, group: IEditorGroup) => EditorInputFactoryResult; type EditorInputFactories = { createEditorInput?: EditorInputFactoryFunction; createUntitledEditorInput?: UntitledEditorInputFactoryFunction; createDiffEditorInput?: DiffEditorInputFactoryFunction; + createMultiDiffEditorInput?: DiffListEditorInputFactoryFunction; createMergeEditorInput?: MergeEditorInputFactoryFunction; }; diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 6175f84405c..30c9f21e421 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -233,6 +233,9 @@ import 'vs/workbench/contrib/markers/browser/markers.contribution'; // Merge Editor import 'vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution'; +// Multi Diff Editor +import 'vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor.contribution'; + // Mapped Edits import 'vs/workbench/contrib/mappedEdits/common/mappedEdits.contribution'; diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index f590f1f8815..85a55686e30 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -165,6 +165,9 @@ import 'vs/workbench/contrib/localHistory/electron-sandbox/localHistory.contribu // Merge Editor import 'vs/workbench/contrib/mergeEditor/electron-sandbox/mergeEditor.contribution'; +// Multi Diff Editor +import 'vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditor.contribution'; + // Remote Tunnel import 'vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution'; From c5203fecfb771f6630bbd62b10d166e0b3d1335c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 7 Nov 2023 17:16:13 +0100 Subject: [PATCH 069/240] make platform less dependent on DOM types (#197653) --- src/vs/base/common/platform.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index c752f32550f..67c42ecf861 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -241,7 +241,8 @@ export const setTimeout0 = (() => { callback: () => void; } const pending: IQueueElement[] = []; - globals.addEventListener('message', (e: MessageEvent) => { + + globals.addEventListener('message', (e: any) => { if (e.data && e.data.vscodeScheduleAsyncWork) { for (let i = 0, len = pending.length; i < len; i++) { const candidate = pending[i]; From ce40e7ce61f2ba02b64efadd4ca1f5376307163f Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 7 Nov 2023 17:36:06 +0100 Subject: [PATCH 070/240] Adopt Better-Less grammar (#197557) Consider adopting a new Less grammar Fixes #171239 --- extensions/less/build/update-grammar.js | 19 + extensions/less/cgmanifest.json | 6 +- extensions/less/package.json | 2 +- extensions/less/syntaxes/less.tmLanguage.json | 5367 +++++++++++- extensions/theme-defaults/themes/dark_vs.json | 12 +- .../theme-defaults/themes/hc_black.json | 12 +- .../theme-defaults/themes/hc_light.json | 7 +- .../theme-defaults/themes/light_vs.json | 7 +- .../themes/quietlight-color-theme.json | 3 +- .../tomorrow-night-blue-color-theme.json | 5 +- .../test/colorize-results/14119_less.json | 90 +- .../test-cssvariables_less.json | 366 +- .../test-cssvariables_scss.json | 32 +- .../colorize-results/test-variables_css.json | 32 +- .../test/colorize-results/test_css.json | 288 +- .../test/colorize-results/test_less.json | 7560 +++++++++-------- .../test/colorize-results/test_scss.json | 32 +- 17 files changed, 9286 insertions(+), 4554 deletions(-) create mode 100644 extensions/less/build/update-grammar.js diff --git a/extensions/less/build/update-grammar.js b/extensions/less/build/update-grammar.js new file mode 100644 index 00000000000..d0b2ec9025f --- /dev/null +++ b/extensions/less/build/update-grammar.js @@ -0,0 +1,19 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +var updateGrammar = require('vscode-grammar-updater'); + +function adaptLess(grammar) { + grammar.name = 'Less'; + grammar.scopeName = 'source.css.less'; +} + +async function updateGrammars() { + await updateGrammar.update('radium-v/Better-Less', 'Syntaxes/Better%20Less.tmLanguage', './syntaxes/less.tmLanguage.json', adaptLess, 'master'); +} + +updateGrammars(); + diff --git a/extensions/less/cgmanifest.json b/extensions/less/cgmanifest.json index 1951ef04bee..663e1cc4daf 100644 --- a/extensions/less/cgmanifest.json +++ b/extensions/less/cgmanifest.json @@ -5,12 +5,12 @@ "type": "git", "git": { "name": "language-less", - "repositoryUrl": "https://github.com/atom/language-less", - "commitHash": "87d4d59e8de6796b506b81a16e1dc1fafc99d30f" + "repositoryUrl": "https://github.com/radium-v/Better-Less", + "commitHash": "05de79f600227201e35f07a49f07acce80e49dbf" } }, "license": "MIT", - "version": "0.34.2" + "version": "0.6.1" } ], "version": 1 diff --git a/extensions/less/package.json b/extensions/less/package.json index 5974be71933..96301ba0fd1 100644 --- a/extensions/less/package.json +++ b/extensions/less/package.json @@ -9,7 +9,7 @@ "vscode": "*" }, "scripts": { - "update-grammar": "node ../node_modules/vscode-grammar-updater/bin atom/language-less grammars/less.cson ./syntaxes/less.tmLanguage.json" + "update-grammar": "node ./build/update-grammar.js" }, "contributes": { "languages": [ diff --git a/extensions/less/syntaxes/less.tmLanguage.json b/extensions/less/syntaxes/less.tmLanguage.json index 3f0b88a29d7..3d2c6bdaeb0 100644 --- a/extensions/less/syntaxes/less.tmLanguage.json +++ b/extensions/less/syntaxes/less.tmLanguage.json @@ -1,183 +1,155 @@ { "information_for_contributors": [ - "This file has been converted from https://github.com/atom/language-less/blob/master/grammars/less.cson", + "This file has been converted from https://github.com/radium-v/Better-Less/blob/master/Syntaxes/Better%20Less.tmLanguage", "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/atom/language-less/commit/87d4d59e8de6796b506b81a16e1dc1fafc99d30f", + "version": "https://github.com/radium-v/Better-Less/commit/05de79f600227201e35f07a49f07acce80e49dbf", "name": "Less", "scopeName": "source.css.less", "patterns": [ { - "include": "#strings" + "include": "#comment-block" }, { + "include": "#less-namespace-accessors" + }, + { + "include": "#less-extend" + }, + { + "include": "#at-rules" + }, + { + "include": "#less-variable-assignment" + }, + { + "include": "#property-list" + }, + { + "include": "#selector" + } + ], + "repository": { + "angle-type": { "captures": { "1": { - "name": "entity.other.attribute-name.class.mixin.css" + "name": "keyword.other.unit.less" } }, - "match": "(\\.[_a-zA-Z][a-zA-Z0-9_-]*(?=\\())" + "match": "(?i:[-+]?(?:(?:\\d*\\.\\d+(?:[eE](?:[-+]?\\d+))*)|(?:[-+]?\\d+))(deg|grad|rad|turn))\\b", + "name": "constant.numeric.less" }, - { + "at-charset": { + "begin": "\\s*((@)charset\\b)\\s*", "captures": { "1": { - "name": "entity.other.attribute-name.class.css" + "name": "keyword.control.at-rule.charset.less" }, "2": { - "name": "punctuation.definition.entity.css" - }, - "4": { - "name": "variable.other.interpolation.less" - } - }, - "match": "((\\.)([_a-zA-Z]|(@{[a-zA-Z0-9_-]+}))[a-zA-Z0-9_-]*)" - }, - { - "captures": { - "0": { - "name": "entity.other.attribute-name.parent-selector.css" - }, - "1": { - "name": "punctuation.definition.entity.css" - } - }, - "match": "(&)[a-zA-Z0-9_-]*" - }, - { - "begin": "(format|local|url|attr|counter|counters)\\s*(\\()", - "beginCaptures": { - "1": { - "name": "support.function.misc.css" - }, - "2": { - "name": "punctuation.section.function.css" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.function.css" + "name": "punctuation.definition.keyword.less" } }, + "end": "\\s*((?=;|$))", + "name": "meta.at-rule.charset.less", "patterns": [ { - "begin": "'", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.css" - } - }, - "end": "'", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.css" - } - }, - "name": "string.quoted.single.css", - "patterns": [ - { - "match": "\\\\.", - "name": "constant.character.escape.css" - } - ] - }, - { - "begin": "\"", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.css" - } - }, - "end": "\"", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.css" - } - }, - "name": "string.quoted.double.css", - "patterns": [ - { - "match": "\\\\(\\d{1,6}|.)", - "name": "constant.character.escape.css" - } - ] - }, - { - "match": "[^'\") \\t]+", - "name": "variable.parameter.misc.css" + "include": "#literal-string" } ] }, - { - "match": "(#)([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\\b(?!.*?(?(['\"])(?:[^\\\\]|\\\\.)*?(\\6)))))?\\s*(\\])", - "name": "meta.attribute-selector.css" + "end": "\\s*(\\})", + "endCaptures": { + "1": { + "name": "punctuation.definition.block.begin.less" + } + }, + "name": "meta.at-rule.counter-style.less", + "patterns": [ + { + "include": "#comment-block" + }, + { + "include": "#rule-list" + } + ] }, - { - "begin": "((@)import\\b)", + "at-custom-media": { + "begin": "(?=\\s*@custom-media\\b)", + "end": "\\s*(?=;)", + "name": "meta.at-rule.custom-media.less", + "patterns": [ + { + "captures": { + "0": { + "name": "punctuation.section.property-list.less" + } + }, + "match": "\\s*;" + }, + { + "captures": { + "1": { + "name": "keyword.control.at-rule.custom-media.less" + }, + "2": { + "name": "punctuation.definition.keyword.less" + }, + "3": { + "name": "support.constant.custom-media.less" + } + }, + "match": "\\s*((@)custom-media)(?=.*?)" + }, + { + "include": "#media-query-list" + } + ] + }, + "at-font-face": { + "begin": "\\s*((@)font-face)\\s*(?=\\{|$)", + "captures": { + "1": { + "name": "keyword.control.at-rule.font-face.less" + }, + "2": { + "name": "punctuation.definition.keyword.less" + } + }, + "end": "\\s*(\\})", + "endCaptures": { + "1": { + "name": "punctuation.definition.block.end.less" + } + }, + "name": "meta.at-rule.font-face.less", + "patterns": [ + { + "include": "#comment-block" + }, + { + "include": "#rule-list" + } + ] + }, + "at-import": { + "begin": "\\s*((@)import\\b)\\s*", "beginCaptures": { "1": { "name": "keyword.control.at-rule.import.less" @@ -186,357 +158,4860 @@ "name": "punctuation.definition.keyword.less" } }, - "end": ";", + "end": "\\;", "endCaptures": { "0": { - "name": "punctuation.terminator.rule.css" + "name": "punctuation.terminator.rule.less" } }, - "name": "meta.at-rule.import.css", + "name": "meta.at-rule.import.less", "patterns": [ { - "match": "(?<=\\(|,|\\s)\\b(reference|optional|once|multiple|less|inline)\\b(?=\\)|,)", - "name": "keyword.control.import.option.less" + "include": "#url-function" }, { - "include": "#brace_round" + "include": "#less-variables" }, { - "include": "source.css#commas" - }, - { - "include": "#strings" - } - ] - }, - { - "captures": { - "1": { - "name": "keyword.control.at-rule.fontface.css" - }, - "2": { - "name": "punctuation.definition.keyword.css" - } - }, - "match": "^\\s*((@)font-face\\b)", - "name": "meta.at-rule.fontface.css" - }, - { - "captures": { - "1": { - "name": "keyword.control.at-rule.media.css" - }, - "2": { - "name": "punctuation.definition.keyword.css" - } - }, - "match": "^\\s*((@)media\\b)", - "name": "meta.at-rule.media.css" - }, - { - "include": "source.css#media-features" - }, - { - "match": "\\b(tv|tty|screen|projection|print|handheld|embossed|braille|aural|all)\\b", - "name": "support.constant.media-type.media.css" - }, - { - "match": "\\b(portrait|landscape)\\b", - "name": "support.constant.property-value.media-property.media.css" - }, - { - "captures": { - "1": { - "name": "support.function.less" - } - }, - "match": "(\\.[a-zA-Z0-9_-]+)\\s*(;|\\()" - }, - { - "begin": "(^[ \\t]+)?(?=//)", - "beginCaptures": { - "1": { - "name": "punctuation.whitespace.comment.leading.less" - } - }, - "end": "(?!\\G)", - "patterns": [ - { - "begin": "//", - "beginCaptures": { - "0": { - "name": "punctuation.definition.comment.less" - } - }, - "end": "\\n", - "name": "comment.line.double-slash.less" - } - ] - }, - { - "match": "(@|\\-\\-)[\\w-]+(?=\\s*)", - "name": "variable.other.less", - "captures": { - "1": { - "name": "punctuation.definition.variable.less" - } - } - }, - { - "include": "#variable_interpolation" - }, - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.property-list.begin.bracket.curly.css" - } - }, - "end": "}", - "endCaptures": { - "0": { - "name": "punctuation.section.property-list.end.bracket.curly.css" - } - }, - "name": "meta.property-list.css", - "patterns": [ - { - "include": "source.css#pseudo-elements" - }, - { - "include": "source.css#pseudo-classes" - }, - { - "include": "source.css#tag-names" - }, - { - "include": "source.css#commas" - }, - { - "include": "#variable_interpolation" - }, - { - "include": "source.css#property-names" - }, - { - "include": "#property_values" - }, - { - "include": "$self" - } - ] - }, - { - "match": "\\!\\s*important", - "name": "keyword.other.important.css" - }, - { - "match": "\\*|\\/|\\-|\\+|~|=|<=|>=|<|>", - "name": "keyword.operator.less" - }, - { - "match": "\\b(not|and|when)\\b", - "name": "keyword.control.logical.operator.less" - }, - { - "include": "source.css#tag-names" - }, - { - "match": "(?)=?))\\s*" + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.group.less", + "patterns": [ + { + "include": "#less-logical-comparisons" + } + ] + }, + { + "match": "\\btrue|false\\b", + "name": "constant.language.less" + }, + { + "match": ",", + "name": "punctuation.separator.less" + }, + { + "include": "#property-values" + }, + { + "include": "#selectors" + }, + { + "include": "#unquoted-string" + } + ] + }, + "less-math": { + "patterns": [ + { + "match": "[-\\+\\*\\/]", + "name": "keyword.operator.arithmetic.less" + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.group.less", + "patterns": [ + { + "include": "#less-math" + } + ] + }, + { + "include": "#numeric-values" + }, + { + "include": "#less-variables" + } + ] + }, + "less-math-functions": { + "patterns": [ + { + "begin": "\\b(ceil|floor|percentage|round|sqrt|abs|a?(sin|cos|tan))(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.math.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#less-variables" + }, + { + "include": "#numeric-values" + } + ] + } + ] + }, + { + "captures": { + "2": { + "name": "support.function.math.less" + }, + "3": { + "name": "punctuation.definition.group.begin.less" + }, + "4": { + "name": "punctuation.definition.group.end.less" + } + }, + "match": "((pi)(\\()(\\)))", + "name": "meta.function-call.less" + }, + { + "begin": "\\b(pow|m(od|in|ax))(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.math.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#less-variables" + }, + { + "include": "#numeric-values" + }, + { + "include": "#comma-delimiter" + } + ] + } + ] + } + ] + }, + "less-misc-functions": { + "patterns": [ + { + "begin": "\\b(color)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.color.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#literal-string" + } + ] + } + ] + }, + { + "begin": "\\b(image-(size|width|height))(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.image.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#literal-string" + }, + { + "include": "#unquoted-string" + } + ] + } + ] + }, + { + "begin": "\\b(convert|unit)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.convert.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#less-variables" + }, + { + "include": "#dimensions" + }, + { + "include": "#numeric-values" + }, + { + "include": "#literal-string" + }, + { + "include": "#comma-delimiter" + }, + { + "match": "((c|m)?m|in|p(t|c|x)|m?s|g?rad|deg|turn|%|r?em|ex|ch)", + "name": "keyword.other.unit.less" + } + ] + } + ] + }, + { + "begin": "\\b(data-uri)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.data-uri.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#less-variables" + }, + { + "include": "#literal-string" + }, + { + "captures": { + "1": { + "name": "punctuation.separator.less" + } + }, + "match": "\\s*(?:(,))" + } + ] + } + ] + }, + { + "captures": { + "2": { + "name": "punctuation.definition.group.begin.less" + }, + "3": { + "name": "punctuation.definition.group.end.less" + } + }, + "match": "\\b(default(\\()(\\)))\\b", + "name": "support.function.default.less" + }, + { + "begin": "\\b(get-unit)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.get-unit.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#dimensions" + } + ] + } + ] + }, + { + "begin": "\\b(svg-gradient)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.svg-gradient.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#angle-type" + }, + { + "include": "#comma-delimiter" + }, + { + "include": "#color-values" + }, + { + "include": "#percentage-type" + }, + { + "include": "#length-type" + }, + { + "match": "\\bto\\b", + "name": "keyword.other.less" + }, + { + "match": "\\b(top|right|bottom|left|center)\\b", + "name": "support.constant.property-value.less" + }, + { + "match": "\\b(at|circle|ellipse)\\b", + "name": "keyword.other.less" + } + ] + } + ] + } + ] + }, + "less-mixin-guards": { + "patterns": [ + { + "begin": "\\s*(and|not|or)?\\s*(?=\\()", + "beginCaptures": { + "1": { + "name": "keyword.operator.logical.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "name": "meta.group.less", + "patterns": [ + { + "include": "#less-variable-comparison" + }, + { + "captures": { + "1": { + "name": "meta.group.less" + }, + "2": { + "name": "punctuation.definition.group.begin.less" + }, + "3": { + "name": "punctuation.definition.group.end.less" + } + }, + "match": "default((\\()(\\)))", + "name": "support.function.default.less" + }, + { + "include": "#property-values" + }, + { + "include": "#less-logical-comparisons" + }, + { + "include": "$self" + } + ] + } + ] + } + ] + }, + "less-namespace-accessors": { + "patterns": [ + { + "begin": "(?=\\s*when\\b)", + "end": "\\s*(?:(,)|(?=[{;]))", + "endCaptures": { + "1": { + "name": "punctuation.definition.block.end.less" + } + }, + "name": "meta.conditional.guarded-namespace.less", + "patterns": [ + { + "captures": { + "1": { + "name": "keyword.control.conditional.less" + }, + "2": { + "name": "punctuation.definition.keyword.less" + } + }, + "match": "\\s*(when)(?=.*?)" + }, + { + "include": "#less-mixin-guards" + }, + { + "include": "#comma-delimiter" + }, + { + "begin": "\\s*(\\{)", + "beginCaptures": { + "1": { + "name": "punctuation.section.property-list.begin.less" + } + }, + "end": "(?=\\})", + "name": "meta.block.less", + "patterns": [ + { + "include": "#rule-list-body" + } + ] + }, + { + "include": "#selectors" + } + ] + }, + { + "begin": "(\\()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.definition.group.end.less" + }, + "2": { + "name": "punctuation.terminator.rule.less" + } + }, + "name": "meta.group.less", + "patterns": [ + { + "include": "#less-variable-assignment" + }, + { + "include": "#comma-delimiter" + }, + { + "captures": { + "1": { + "name": "punctuation.terminator.rule.less" + } + }, + "match": "\\s*(;)|(?=[})])" + }, + { + "include": "#property-values" + }, + { + "include": "#rule-list-body" + } + ] + } + ] + }, + "less-number-units": { + "patterns": [ + { + "match": "\\b((c|m)?m|in|p(t|c)|m?s|g?rad|deg|turn)\\b", + "name": "keyword.other.unit.less" + }, + { + "match": "\\b(r?em|ex|ch|vw|vh|vmin|vmax|cm|mm|q|in|pt|pc|px|fr|s|ms|Hz|kHz|dpi|dpcm|dppx|deg|grad|rad|turn)\\b" + } + ] + }, + "less-string-functions": { + "patterns": [ + { + "begin": "\\b(e(scape)?)(?=\\()\\b", + "beginCaptures": { + "1": { + "name": "support.function.escape.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#less-variables" + }, + { + "include": "#comma-delimiter" + }, + { + "include": "#literal-string" + }, + { + "include": "#unquoted-string" + } + ] + } + ] + }, + { + "begin": "\\s*(%)(?=\\()\\s*", + "beginCaptures": { + "1": { + "name": "support.function.format.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#less-variables" + }, + { + "include": "#comma-delimiter" + }, + { + "include": "#literal-string" + }, + { + "include": "#property-values" + } + ] + } + ] + }, + { + "begin": "\\b(replace)(?=\\()\\b", + "beginCaptures": { + "1": { + "name": "support.function.replace.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#less-variables" + }, + { + "include": "#comma-delimiter" + }, + { + "include": "#literal-string" + }, + { + "include": "#property-values" + } + ] + } + ] + } + ] + }, + "less-strings": { + "patterns": [ + { + "begin": "(~)('|\")", + "beginCaptures": { + "1": { + "name": "constant.character.escape.less" + }, + "2": { + "name": "punctuation.definition.string.begin.less" + } + }, + "contentName": "markup.raw.inline.less", + "end": "('|\")|(\\n)", + "endCaptures": { + "1": { + "name": "punctuation.definition.string.end.less" + }, + "2": { + "name": "invalid.illegal.newline.less" + } + }, + "name": "string.quoted.other.less", + "patterns": [ + { + "include": "#string-content" + } + ] + } + ] + }, + "less-type-functions": { + "patterns": [ + { + "begin": "\\b(is(number|string|color|keyword|url|pixel|em|percentage|ruleset))(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.type.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#property-values" + } + ] + } + ] + }, + { + "begin": "\\b(isunit)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.type.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#property-values" + }, + { + "include": "#comma-delimiter" + }, + { + "match": "(?x)\\b((?i:em|ex|ch|rem)|(?i:vw|vh|vmin|vmax)|(?i:cm|mm|q|in|pt|pc|px|fr)|(?i:deg|grad|rad|turn)|(?i:s|ms)|(?i:Hz|kHz)|(?i:dpi|dpcm|dppx))\\b", + "name": "keyword.other.unit.less" + } + ] + } + ] + }, + { + "begin": "\\b(isdefined)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.type.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#less-variables" + } + ] + } + ] + } + ] + }, + "less-variable-assignment": { + "patterns": [ + { + "begin": "(@)(-?(?:[[-\\w][^\\x{00}-\\x{7F}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))(?:[[-\\w][^\\x{00}-\\x{7F}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))*)", + "beginCaptures": { + "0": { + "name": "variable.other.readwrite.less" + }, + "1": { + "name": "punctuation.definition.variable.less" + }, + "2": { + "name": "support.other.variable.less" + } + }, + "end": "\\s*(;|(\\.{3})|(?=\\)))", + "endCaptures": { + "1": { + "name": "punctuation.terminator.rule.less" + }, + "2": { + "name": "keyword.operator.spread.less" + } + }, + "name": "meta.property-value.less", + "patterns": [ + { + "captures": { + "1": { + "name": "punctuation.separator.key-value.less" + }, + "4": { + "name": "meta.property-value.less" + } + }, + "match": "(((\\+_?)?):)([\\s\\t]*)" + }, + { + "include": "#property-values" + }, + { + "include": "#comma-delimiter" + }, + { + "include": "#property-list" + }, + { + "include": "#unquoted-string" + } + ] + } + ] + }, + "less-variable-comparison": { + "patterns": [ + { + "begin": "(@{1,2})([-]?([_a-z]|[^\\x{00}-\\x{7F}]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))(?:[[-\\w][^\\x{00}-\\x{7F}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))*)", + "beginCaptures": { + "0": { + "name": "variable.other.readwrite.less" + }, + "1": { + "name": "punctuation.definition.variable.less" + }, + "2": { + "name": "support.other.variable.less" + } + }, + "end": "\\s*(?=\\))", + "endCaptures": { + "1": { + "name": "punctuation.terminator.rule.less" + } + }, + "patterns": [ + { + "captures": { + "1": { + "name": "keyword.operator.logical.less" + } + }, + "match": "\\s*(=|((<|>)=?))\\s*" + }, + { + "match": "\\btrue\\b", + "name": "constant.language.less" + }, + { + "include": "#property-values" + }, + { + "include": "#selectors" + }, + { + "include": "#unquoted-string" + }, + { + "match": ",", + "name": "punctuation.separator.less" + } + ] + } + ] + }, + "less-variable-interpolation": { + "captures": { + "1": { + "name": "punctuation.definition.variable.less" + }, + "2": { + "name": "punctuation.definition.expression.less" + }, + "3": { + "name": "support.other.variable.less" + }, + "4": { + "name": "punctuation.definition.expression.less" + } + }, + "match": "(@)(\\{)([-\\w]+)(\\})", + "name": "variable.other.readwrite.less" + }, + "less-variables": { + "captures": { + "1": { + "name": "punctuation.definition.variable.less" + }, + "2": { + "name": "support.other.variable.less" + } + }, + "match": "\\s*(@@?)([-\\w]+)", + "name": "variable.other.readwrite.less" + }, + "literal-string": { + "patterns": [ + { + "begin": "'", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.less" + } + }, + "end": "(')|(\\n)", + "endCaptures": { + "1": { + "name": "punctuation.definition.string.end.less" + }, + "2": { + "name": "invalid.illegal.newline.less" + } + }, + "name": "string.quoted.single.less", + "patterns": [ + { + "include": "#string-content" + } + ] + }, + { + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.less" + } + }, + "end": "(\")|(\\n)", + "endCaptures": { + "1": { + "name": "punctuation.definition.string.end.less" + }, + "2": { + "name": "invalid.illegal.newline.less" + } + }, + "name": "string.quoted.double.less", + "patterns": [ + { + "include": "#string-content" + } + ] + }, + { + "include": "#less-strings" + } + ] + }, + "local-function": { + "begin": "\\b(local)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.font-face.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#unquoted-string" + } + ] + } + ] + }, + "media-query": { + "begin": "\\s*(only|not)?\\s*(all|aural|braille|embossed|handheld|print|projection|screen|tty|tv)?", + "beginCaptures": { + "1": { + "name": "keyword.operator.logic.media.less" + }, + "2": { + "name": "support.constant.media.less" + } + }, + "end": "\\s*(?:(,)|(?=[{;]))", + "endCaptures": { + "1": { + "name": "punctuation.definition.arbitrary-repetition.less" + } + }, + "patterns": [ + { + "include": "#less-variables" + }, + { + "include": "#custom-property-name" + }, + { + "begin": "\\s*(and)?\\s*(\\()\\s*", + "beginCaptures": { + "1": { + "name": "keyword.operator.logic.media.less" + }, + "2": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.group.less", + "patterns": [ + { + "begin": "((-webkit-|-o-)?((min|max)-)?(-moz-)?(((device-)?(height|width|aspect-ratio|pixel-ratio))|(color(-index)?)|monochrome|resolution))|grid|scan|orientation\\s*(?=[:)])", + "beginCaptures": { + "0": { + "name": "support.type.property-name.media.less" + }, + "2": { + "name": "support.type.vendor-prefix.less" + }, + "5": { + "name": "support.type.vendor-prefix.less" + } + }, + "end": "(((\\+_?)?):)|(?=\\))", + "endCaptures": { + "1": { + "name": "punctuation.separator.key-value.less" + } + } + }, + { + "match": "\\b(portrait|landscape|progressive|interlace)", + "name": "support.constant.property-value.less" + }, + { + "captures": { + "1": { + "name": "constant.numeric.less" + }, + "2": { + "name": "keyword.operator.arithmetic.less" + }, + "3": { + "name": "constant.numeric.less" + } + }, + "match": "\\s*(\\d+)(/)(\\d+)" + }, + { + "include": "#less-math" + } + ] + } + ] + }, + "media-query-list": { + "begin": "\\s*(?=[^{;])", + "end": "\\s*(?=[{;])", + "patterns": [ + { + "include": "#media-query" + } + ] + }, + "minmax-function": { + "begin": "\\b(minmax)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.grid.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#less-variables" + }, + { + "include": "#length-type" + }, + { + "include": "#comma-delimiter" + }, + { + "match": "\\b(max-content|min-content)\\b", + "name": "support.constant.property-value.less" + } + ] + } + ] + }, + "number-type": { + "match": "[-+]?(?:(?:\\d*\\.\\d+(?:[eE](?:[-+]?\\d+))*)|(?:[-+]?\\d+))", + "name": "constant.numeric.less" + }, + "numeric-values": { + "patterns": [ + { + "include": "#dimensions" + }, + { + "include": "#percentage-type" + }, + { + "include": "#number-type" + } + ] + }, + "percentage-type": { + "captures": { + "1": { + "name": "keyword.other.unit.less" + } + }, + "match": "[-+]?(?:(?:\\d*\\.\\d+(?:[eE](?:[-+]?\\d+))*)|(?:[-+]?\\d+))(%)", + "name": "constant.numeric.less" + }, + "property-list": { + "patterns": [ + { + "begin": "(?=(?=[^;]*)\\{)", + "end": "\\}", + "endCaptures": { + "0": { + "name": "punctuation.definition.block.end.less" + } + }, + "patterns": [ + { + "include": "#rule-list" + } + ] + } + ] + }, + "property-value-constants": { + "patterns": [ + { + "match": "(?x)\\b(\n absolute|active|add\n |all(-(petite|small)-caps|-scroll)?\n |alpha(betic)?\n |alternate(-reverse)?\n |always|annotation|antialiased|at\n |auto(hiding-scrollbar)?\n |avoid(-column|-page|-region)?\n |background(-color|-image|-position|-size)?\n |backwards|balance|baseline|below|bevel|bicubic|bidi-override|blink\n |block(-line-height)?\n |blur\n |bold(er)?\n |border(-bottom|-left|-right|-top)?-(color|radius|width|style)\n |border-(bottom|top)-(left|right)-radius\n |border-image(-outset|-repeat|-slice|-source|-width)?\n |border(-bottom|-left|-right|-top|-collapse|-spacing|-box)?\n |both|bottom\n |box(-shadow)?\n |break-(all|word)\n |brightness\n |butt(on)?\n |capitalize\n |cent(er|ral)\n |char(acter-variant)?\n |cjk-ideographic|clip|clone|close-quote\n |closest-(corner|side)\n |col-resize|collapse\n |color(-stop|-burn|-dodge)?\n |column((-count|-gap|-reverse|-rule(-color|-width)?|-width)|s)?\n |common-ligatures|condensed|consider-shifts|contain\n |content(-box|s)?\n |contextual|contrast|cover\n |crisp(-e|E)dges\n |crop\n |cross(hair)?\n |da(rken|shed)\n |default|dense|diagonal-fractions|difference|disabled\n |discretionary-ligatures|disregard-shifts\n |distribute(-all-lines|-letter|-space)?\n |dotted|double|drop-shadow\n |(nwse|nesw|ns|ew|sw|se|nw|ne|w|s|e|n)-resize\n |ease(-in-out|-in|-out)?\n |element|ellipsis|embed|end|EndColorStr|evenodd\n |exclu(de(-ruby)?|sion)\n |expanded\n |(extra|semi|ultra)-(condensed|expanded)\n |farthest-(corner|side)?\n |fill(-box|-opacity)?\n |filter|fixed|flat\n |flex((-basis|-end|-grow|-shrink|-start)|box)?\n |flip|flood-color\n |font(-size(-adjust)?|-stretch|-weight)?\n |forwards\n |from(-image)?\n |full-width|geometricPrecision|glyphs|gradient|grayscale\n |grid(-height)?\n |groove|hand|hanging|hard-light|height|help|hidden|hide\n |historical-(forms|ligatures)\n |horizontal(-tb)?\n |hue\n |ideograph(-alpha|-numeric|-parenthesis|-space|ic)\n |inactive|include-ruby|infinite|inherit|initial\n |inline(-block|-box|-flex(box)?|-line-height|-table)?\n |inset|inside\n |inter(-ideograph|-word|sect)\n |invert|isolat(e|ion)|italic\n |jis(04|78|83|90)\n |justify(-all)?\n |keep-all\n |large[r]?\n |last|layout|left|letter-spacing\n |light(e[nr]|ing-color)\n |line(-edge|-height|-through)?\n |linear(-gradient|RGB)?\n |lining-nums|list-item|local|loose|lowercase|lr-tb|ltr\n |lumin(osity|ance)|manual\n |manipulation\n |margin(-bottom|-box|-left|-right|-top)?\n |marker(-offset|s)?\n |mathematical\n |max-(content|height|lines|size|width)\n |medium|middle\n |min-(content|height|width)\n |miter|mixed|move|multiply|newspaper\n |no-(change|clip|(close|open)-quote|(common|discretionary|historical)-ligatures|contextual|drop|repeat)\n |none|nonzero|normal|not-allowed|nowrap|oblique\n |offset(-after|-before|-end|-start)?\n |oldstyle-nums|opacity|open-quote\n |optimize(Legibility|Precision|Quality|Speed)\n |order|ordinal|ornaments\n |outline(-color|-offset|-width)?\n |outset|outside|over(line|-edge|lay)\n |padding(-bottom|-box|-left|-right|-top|-box)?\n |page|painted|paused\n |pan-(x|left|right|y|up|down)\n |perspective-origin\n |petite-caps|pixelated|pointer\n |pinch-zoom\n |pre(-line|-wrap)?\n |preserve-3d\n |progid:DXImageTransform.Microsoft.(Alpha|Blur|dropshadow|gradient|Shadow)\n |progress\n |proportional-(nums|width)\n |radial-gradient|recto|region|relative\n |repeat(-[xy])?\n |repeating-(linear|radial)-gradient\n |replaced|reset-size|reverse|ridge|right\n |round\n |row(-resize|-reverse)?\n |rtl|ruby|running|saturat(e|ion)|screen\n |scroll(-position|bar)?\n |separate|sepia\n |scale-down\n |shape-(image-threshold|margin|outside)\n |show\n |sideways(-lr|-rl)?\n |simplified\n |size\n |slashed-zero|slice\n |small(-caps|er)?\n |smooth|snap|solid|soft-light\n |space(-around|-between)?\n |span|sRGB\n |stack(ed-fractions)?\n |start(ColorStr)?\n |static\n |step-(end|start)\n |sticky\n |stop-(color|opacity)\n |stretch|strict\n |stroke(-box|-dash(array|offset)|-miterlimit|-opacity|-width)?\n |style(set)?\n |stylistic\n |sub(grid|pixel-antialiased|tract)?\n |super|swash\n |table(-caption|-cell|(-column|-footer|-header|-row)-group|-column|-row)?\n |tabular-nums|tb-rl\n |text((-bottom|-(decoration|emphasis)-color|-indent|-(over|under)-edge|-shadow|-size(-adjust)?|-top)|field)?\n |thi(ck|n)\n |titling-ca(ps|se)\n |to[p]?\n |touch|traditional\n |transform(-origin)?\n |under(-edge|line)?\n |unicase|unset|uppercase|upright\n |use-(glyph-orientation|script)\n |verso\n |vertical(-align|-ideographic|-lr|-rl|-text)?\n |view-box\n |viewport-fill(-opacity)?\n |visibility\n |visible(Fill|Painted|Stroke)?\n |wait|wavy|weight|whitespace|(device-)?width|word-spacing\n |wrap(-reverse)?\n |x{1,2}-(large|small)\n |z-index|zero\n |zoom(-in|-out)?\n |((?xi:arabic-indic|armenian|bengali|cambodian|circle|cjk-decimal|cjk-earthly-branch|cjk-heavenly-stem|decimal-leading-zero|decimal|devanagari|disclosure-closed|disclosure-open|disc|ethiopic-numeric|georgian|gujarati|gurmukhi|hebrew|hiragana-iroha|hiragana|japanese-formal|japanese-informal|kannada|katakana-iroha|katakana|khmer|korean-hangul-formal|korean-hanja-formal|korean-hanja-informal|lao|lower-alpha|lower-armenian|lower-greek|lower-latin|lower-roman|malayalam|mongolian|myanmar|oriya|persian|simp-chinese-formal|simp-chinese-informal|square|tamil|telugu|thai|tibetan|trad-chinese-formal|trad-chinese-informal|upper-alpha|upper-armenian|upper-latin|upper-roman)))\\b", + "name": "support.constant.property-value.less" + }, + { + "match": "\\b(?i:sans-serif|serif|monospace|fantasy|cursive)\\b(?=\\s*[;,\\n}])", + "name": "support.constant.font-name.less" + } + ] + }, + "property-values": { + "patterns": [ + { + "include": "#comment-block" + }, + { + "include": "#vendor-prefix" + }, + { + "include": "#builtin-functions" + }, + { + "include": "#color-functions" + }, + { + "include": "#less-math" + }, + { + "include": "#less-functions" + }, + { + "include": "#less-variables" + }, + { + "include": "#unicode-range" + }, + { + "include": "#numeric-values" + }, + { + "include": "#color-values" + }, + { + "include": "#property-value-constants" + }, + { + "include": "#literal-string" + }, + { + "captures": { + "1": { + "name": "punctuation.separator.less" + } + }, + "match": "(\\!)\\s*important", + "name": "keyword.other.important.less" + } + ] + }, + "pseudo-classes": { + "patterns": [ + { + "begin": "(:)(dir|lang)(?=\\()", + "captures": { + "1": { + "name": "punctuation.definition.entity.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "entity.other.attribute-name.pseudo-class.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#unquoted-string" + } + ] + } + ] + }, + { + "begin": "(:)(not)(?=\\()", + "captures": { + "1": { + "name": "punctuation.definition.entity.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "entity.other.attribute-name.pseudo-class.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#selectors" + } + ] + } + ] + }, + { + "begin": "(:)(nth(-last)?-(child|of-type))(?=\\()", + "captures": { + "1": { + "name": "punctuation.definition.entity.less" + }, + "2": { + "name": "entity.other.attribute-name.pseudo-class.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "name": "meta.group.less", + "patterns": [ + { + "match": "\\b(even|odd)\\b", + "name": "keyword.other.pseudo-class.less" + }, + { + "captures": { + "1": { + "name": "keyword.other.unit.less" + } + }, + "match": "(?:[-+]?(?:\\d+)?(n)(\\s*[-+]\\s*\\d+)?|[-+]?\\s*\\d+)", + "name": "constant.numeric.less" + }, + { + "include": "#less-math" + }, + { + "include": "#less-strings" + }, + { + "include": "#less-variable-interpolation" + } + ] + } + ] + }, + { + "begin": "(:)(host-context)(?=\\()", + "captures": { + "1": { + "name": "punctuation.definition.entity.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "entity.other.attribute-name.pseudo-class.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#selectors" + } + ] + } + ] + }, + { + "captures": { + "1": { + "name": "punctuation.definition.entity.less" + }, + "2": { + "name": "entity.other.attribute-name.pseudo-class.less" + } + }, + "match": "(:)(active|any|checked|default|disabled|empty|enabled|first(-(child|of-type))?|fullscreen|focus|host|hover|indeterminate|in-range|invalid|last-(child|of-type)|left|link|only-(child|of-type)|optional|out-of-range|read-(only|write)|required|right|root|scope|target|valid|visited)", + "name": "meta.function-call.less" + } + ] + }, + "pseudo-elements": { + "patterns": [ + { + "begin": "(::)(slotted)(?=\\()", + "captures": { + "1": { + "name": "punctuation.definition.entity.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "entity.other.attribute-name.pseudo-class.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#selectors" + } + ] + } + ] + }, + { + "captures": { + "1": { + "name": "punctuation.definition.entity.less" + }, + "2": { + "name": "punctuation.definition.entity.less" + }, + "3": { + "name": "support.type.vendor-prefix.less" + } + }, + "match": "(?:(:{1,2})(?:before|after|first-line|first-letter)|(::)(-(?:moz|ms|webkit)-)?(?:(-?(?:[[-\\w][^\\x{00}-\\x{7F}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))(?:[[-\\w][^\\x{00}-\\x{7F}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))*)))\\b", + "name": "entity.other.attribute-name.pseudo-element.less" + } + ] + }, + "qualified-name": { + "captures": { + "1": { + "name": "entity.name.constant.less" + }, + "2": { + "name": "entity.name.namespace.wildcard.less" + }, + "3": { + "name": "punctuation.separator.namespace.less" + } + }, + "match": "(?:(-?(?:[[-\\w][^\\x{00}-\\x{7F}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))(?:[[_a-zA-Z][^\\x{00}-\\x{7F}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))*)|(\\*))?([|])(?!=)" + }, + "regexp-function": { + "begin": "\\b(regexp)(?=\\()", + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "support.function.regexp.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "name": "meta.function-call.less", + "patterns": [ + { + "include": "#literal-string" + } + ] + } + ] + }, + "resolution-type": { + "captures": { + "1": { + "name": "keyword.other.unit.less" + } + }, + "match": "(?i:[-+]?(?:(?:\\d*\\.\\d+(?:[eE](?:[-+]?\\d+))*)|(?:[-+]?\\d+))(dpi|dpcm|dppx))\\b", + "name": "constant.numeric.less" + }, + "rule-list": { + "patterns": [ + { + "begin": "\\{", + "beginCaptures": { + "0": { + "name": "punctuation.definition.block.begin.less" + } + }, + "end": "(?=\\s*\\})", + "name": "meta.property-list.less", + "patterns": [ + { + "captures": { + "1": { + "name": "punctuation.terminator.rule.less" + } + }, + "match": "\\s*(;)|(?=[})])" + }, + { + "include": "#rule-list-body" + }, + { + "include": "#less-extend" + } + ] + } + ] + }, + "rule-list-body": { + "patterns": [ + { + "include": "#comment-block" + }, + { + "include": "#comment-line" + }, + { + "include": "#at-rules" + }, + { + "include": "#less-variable-assignment" + }, + { + "include": "#less-variable-interpolation" + }, + { + "begin": "(?=[-a-z])", + "end": "$|(?![-a-z])", + "patterns": [ + { + "include": "#vendor-prefix" + }, + { + "include": "#custom-property-name" + }, + { + "include": "#filter-function" + }, + { + "captures": { + "1": { + "name": "keyword.other.custom-property.prefix.less" + }, + "2": { + "name": "support.type.custom-property.name.less" + } + }, + "match": "\\b(var-)(-?(?:[[-\\w][^\\x{00}-\\x{9f}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))(?:[[_a-zA-Z][^\\x{00}-\\x{9f}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))*)(?=\\s)", + "name": "invalid.deprecated.custom-property.less" + }, + { + "begin": "\\bfont(-family)?(?!-)\\b", + "beginCaptures": { + "0": { + "name": "support.type.property-name.less" + } + }, + "end": "\\s*(;)|(?=[})])", + "endCaptures": { + "1": { + "name": "punctuation.terminator.rule.less" + } + }, + "name": "meta.property-name.less", + "patterns": [ + { + "captures": { + "1": { + "name": "punctuation.separator.key-value.less" + }, + "4": { + "name": "meta.property-value.less" + } + }, + "match": "(((\\+_?)?):)([\\s\\t]*)" + }, + { + "include": "#property-values" + }, + { + "match": "-?(?:[[_a-zA-Z][^\\x{00}-\\x{9f}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))(?:[[-\\w][^\\x{00}-\\x{9f}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))*(\\s+-?(?:[[_a-zA-Z][^\\x{00}-\\x{9f}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))(?:[[-\\w][^\\x{00}-\\x{9f}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))*)*", + "name": "string.unquoted.less" + }, + { + "match": ",", + "name": "punctuation.separator.less" + } + ] + }, + { + "begin": "\\banimation(-(delay|direction|duration|fill-mode|iteration-count|name|play-state|timing-function))?\\b", + "beginCaptures": { + "0": { + "name": "support.type.property-name.less" + } + }, + "end": "\\s*(;)|(?=[})])", + "endCaptures": { + "1": { + "name": "punctuation.terminator.rule.less" + } + }, + "patterns": [ + { + "begin": "(((\\+_?)?):)(?=[\\s\\t]*)", + "beginCaptures": { + "1": { + "name": "punctuation.separator.key-value.less" + } + }, + "captures": { + "1": { + "name": "punctuation.definition.arbitrary-repetition.less" + } + }, + "contentName": "meta.property-value.less", + "end": "(?=\\s*(;)|(?=[})]))", + "patterns": [ + { + "match": "\\b(linear|ease(-in)?(-out)?|step-(start|end)|none|forwards|backwards|both|normal|alternate(-reverse)?|reverse|running|paused)\\b", + "name": "support.constant.property-value.less" + }, + { + "include": "#cubic-bezier-function" + }, + { + "include": "#steps-function" + }, + { + "include": "#time-type" + }, + { + "include": "#number-type" + }, + { + "match": "-?(?:[_a-zA-Z]|[^\\x{00}-\\x{7F}]|(?:(:?\\\\[0-9a-f]{1,6}(\\r\\n|[\\s\\t\\r\\n\\f])?)|\\\\[^\\r\\n\\f0-9a-f]))(?:[-_a-zA-Z0-9]|[^\\x{00}-\\x{7F}]|(?:(:?\\\\[0-9a-f]{1,6}(\\r\\n|[\\t\\r\\n\\f])?)|\\\\[^\\r\\n\\f0-9a-f]))*", + "name": "variable.other.constant.animation-name.less" + }, + { + "include": "#literal-string" + }, + { + "include": "#property-values" + }, + { + "match": "\\s*(?:(,))" + } + ] + } + ] + }, + { + "begin": "\\b(transition(-(property|duration|delay|timing-function))?)\\b", + "beginCaptures": { + "0": { + "name": "meta.property-name.less" + }, + "1": { + "name": "support.type.property-name.less" + } + }, + "end": "\\s*(;)|(?=[})])", + "endCaptures": { + "1": { + "name": "punctuation.terminator.rule.less" + } + }, + "patterns": [ + { + "captures": { + "1": { + "name": "punctuation.separator.key-value.less" + }, + "4": { + "name": "meta.property-value.less" + } + }, + "match": "(((\\+_?)?):)([\\s\\t]*)" + }, + { + "include": "#time-type" + }, + { + "include": "#property-values" + }, + { + "include": "#cubic-bezier-function" + }, + { + "include": "#steps-function" + }, + { + "captures": { + "1": { + "name": "punctuation.definition.arbitrary-repetition.less" + } + }, + "match": "\\s*(?:(,))" + } + ] + }, + { + "begin": "\\bfilter\\b", + "beginCaptures": { + "0": { + "name": "support.type.property-name.less" + } + }, + "end": "\\s*(;)|(?=[})])", + "endCaptures": { + "1": { + "name": "punctuation.terminator.rule.less" + } + }, + "name": "meta.property-name.less", + "patterns": [ + { + "captures": { + "1": { + "name": "punctuation.separator.key-value.less" + }, + "4": { + "name": "meta.property-value.less" + } + }, + "match": "(((\\+_?)?):)([\\s\\t]*)" + }, + { + "match": "\\b(inherit|initial|unset|none)\\b", + "name": "meta.property-value.less" + }, + { + "include": "#filter-functions" + } + ] + }, + { + "begin": "\\bwill-change\\b", + "beginCaptures": { + "0": { + "name": "support.type.property-name.less" + } + }, + "end": "\\s*(;)|(?=[})])", + "endCaptures": { + "1": { + "name": "punctuation.terminator.rule.less" + } + }, + "name": "meta.property-name.less", + "patterns": [ + { + "captures": { + "1": { + "name": "punctuation.separator.key-value.less" + }, + "4": { + "name": "meta.property-value.less" + } + }, + "match": "(((\\+_?)?):)([\\s\\t]*)" + }, + { + "match": "unset|initial|inherit|will-change|auto|scroll-position|contents", + "name": "invalid.illegal.property-value.less" + }, + { + "match": "-?(?:[[-\\w][^\\x{00}-\\x{9f}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))(?:[[_a-zA-Z][^\\x{00}-\\x{9f}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))*", + "name": "support.constant.property-value.less" + }, + { + "captures": { + "1": { + "name": "punctuation.definition.arbitrary-repetition.less" + } + }, + "match": "\\s*(?:(,))" + } + ] + }, + { + "begin": "\\bcounter-(increment|(re)?set)\\b", + "beginCaptures": { + "0": { + "name": "support.type.property-name.less" + } + }, + "end": "\\s*(;)|(?=[})])", + "endCaptures": { + "1": { + "name": "punctuation.terminator.rule.less" + } + }, + "name": "meta.property-name.less", + "patterns": [ + { + "captures": { + "1": { + "name": "punctuation.separator.key-value.less" + }, + "4": { + "name": "meta.property-value.less" + } + }, + "match": "(((\\+_?)?):)([\\s\\t]*)" + }, + { + "match": "-?(?:[[-\\w][^\\x{00}-\\x{9f}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))(?:[[_a-zA-Z][^\\x{00}-\\x{9f}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))*", + "name": "entity.name.constant.counter-name.less" + }, + { + "include": "#integer-type" + }, + { + "match": "unset|initial|inherit|auto", + "name": "invalid.illegal.property-value.less" + } + ] + }, + { + "match": "(?x)\\b( accent-height | align-content | align-items | align-self | alignment-baseline | all | animation-timing-function | animation-play-state | animation-name | animation-iteration-count | animation-fill-mode | animation-duration | animation-direction | animation-delay | animation | appearance | ascent | azimuth | backface-visibility | background-size | background-repeat-y | background-repeat-x | background-repeat | background-position-y | background-position-x | background-position | background-origin | background-image | background-color | background-clip | background-blend-mode | background-attachment | background | baseline-shift | begin | bias | blend-mode | border-((top|right|bottom|left)-)?(width|style|color) | border-(top|bottom)-(right|left)-radius | border-image-(width|source|slice|repeat|outset) | border-(top|right|bottom|left|collapse|image|radius|spacing) | border | bottom | box-(align|decoration-break|direction|flex|ordinal-group|orient|pack|shadow|sizing) | break-(after|before|inside) | caption-side | clear | clip-path | clip-rule | clip | color(-(interpolation(-filters)?|profile|rendering))? | columns | column-(break-before|count|fill|gap|(rule(-(color|style|width))?)|span|width) | contain | content | counter-(increment|reset) | cursor | (c|d|f)(x|y) | direction | display | divisor | dominant-baseline | dur | elevation | empty-cells | enable-background | end | fallback | fill(-(opacity|rule))? | filter | flex(-(align|basis|direction|flow|grow|item-align|line-pack|negative|order|pack|positive|preferred-size|shrink|wrap))? | float | flood-(color|opacity) | font-display | font-family | font-feature-settings | font-kerning | font-language-override | font-size(-adjust)? | font-smoothing | font-stretch | font-style | font-synthesis | font-variant(-(alternates|caps|east-asian|ligatures|numeric|position))? | font-weight | font | fr | glyph-orientation-(horizontal|vertical) | grid-(area|gap) | grid-auto-(columns|flow|rows) | grid-(column|row)(-(end|gap|start))? | grid-template(-(areas|columns|rows))? | height | hyphens | image-(orientation|rendering|resolution) | isolation | justify-content | kerning | left | letter-spacing | lighting-color | line-(box-contain|break|clamp|height) | list-style(-(image|position|type))? | margin(-(bottom|left|right|top))? | marker(-(end|mid|start))? | mask(-(clip||composite|image|origin|position|repeat|size|type))? | (max|min)-(height|width) | mix-blend-mode | nbsp-mode | negative | object-(fit|position) | opacity | operator | order | orphans | outline(-(color|offset|style|width))? | overflow(-(scrolling|wrap|x|y))? | pad(ding(-(bottom|left|right|top))?)? | page(-break-(after|before|inside))? | paint-order | pause(-(after|before))? | perspective(-origin(-(x|y))?)? | pitch(-range)? | pointer-events | position | prefix | quotes | range | resize | right | rotate | scale | scroll-behavior | shape-(image-threshold|margin|outside|rendering) | size | speak(-as)? | src | stop-(color|opacity) | stroke(-(dash(array|offset)|line(cap|join)|miterlimit|opacity|width))? | suffix | symbols | system | tab-size | table-layout | tap-highlight-color | text-align(-last)? | text-decoration(-(color|line|style))? | text-emphasis(-(color|position|style))? | text-(anchor|fill-color|height|indent|justify|orientation|overflow|rendering|shadow|transform|underline-position) | top | touch-action | transform(-origin(-(x|y))?) | transform(-style)? | transition(-(delay|duration|property|timing-function))? | translate | unicode-(bidi|range) | user-(drag|select) | vertical-align | visibility | white-space | widows | width | will-change | word-(break|spacing|wrap) | writing-mode | z-index | zoom )\\b", + "name": "support.type.property-name.less" + }, + { + "include": "$self" + } + ] + }, + { + "begin": "\\b(((\\+_?)?):)([\\s\\t]*)", + "captures": { + "1": { + "name": "punctuation.separator.key-value.less" + }, + "4": { + "name": "meta.property-value.less" + } + }, + "contentName": "meta.property-value.less", + "end": "\\s*(;)|(?=[})])", + "endCaptures": { + "1": { + "name": "punctuation.terminator.rule.less" + } + }, + "patterns": [ + { + "include": "#property-values" + } + ] }, { "include": "$self" } ] }, - "less_builtin_functions": { - "match": "\\b(abs|acos|alpha|argb|asin|atan|average|blue|calc|ceil|color|contrast|convert|convert|cos|darken|data-uri|desaturate|difference|e|escape|exclusion|extract|fade|fadein|fadeout|floor|format|green|greyscale|hardlight|hsl|hsla|hsv|hsva|hsvhue|hsvsaturation|hsvvalue|hue|length|lighten|lightness|luma|max|min|mix|mod|multiply|negation|overlay|percentage|pi|pow|red|replace|round|saturate|saturation|screen|sin|softlight|spin|sqrt|tan|unit)\\b", - "name": "support.function.any-method.builtin.less" + "selector": { + "patterns": [ + { + "begin": "(?=[>~+/\\.*#a-zA-Z\\[&]|(\\:{1,2}[^\\s])|@\\{)", + "contentName": "meta.selector.less", + "end": "(?=@(?!\\{)|[{;])", + "patterns": [ + { + "include": "#comment-line" + }, + { + "include": "#selectors" + }, + { + "include": "#less-namespace-accessors" + }, + { + "include": "#less-variable-interpolation" + }, + { + "captures": { + "1": { + "name": "punctuation.separator.less" + } + }, + "match": "(\\!)\\s*important", + "name": "keyword.other.important.less" + } + ] + } + ] + }, + "selectors": { + "patterns": [ + { + "match": "\\b([a-z](?:(?:[-_a-z0-9\\x{00B7}]|\\\\\\.|[[\\x{00C0}-\\x{00D6}][\\x{00D8}-\\x{00F6}][\\x{00F8}-\\x{02FF}][\\x{0300}-\\x{037D}][\\x{037F}-\\x{1FFF}][\\x{200C}-\\x{200D}][\\x{203F}-\\x{2040}][\\x{2070}-\\x{218F}][\\x{2C00}-\\x{2FEF}][\\x{3001}-\\x{D7FF}][\\x{F900}-\\x{FDCF}][\\x{FDF0}-\\x{FFFD}][\\x{10000}-\\x{EFFFF}]]))*-(?:(?:[-_a-z0-9\\x{00B7}]|\\\\\\.|[[\\x{00C0}-\\x{00D6}][\\x{00D8}-\\x{00F6}][\\x{00F8}-\\x{02FF}][\\x{0300}-\\x{037D}][\\x{037F}-\\x{1FFF}][\\x{200C}-\\x{200D}][\\x{203F}-\\x{2040}][\\x{2070}-\\x{218F}][\\x{2C00}-\\x{2FEF}][\\x{3001}-\\x{D7FF}][\\x{F900}-\\x{FDCF}][\\x{FDF0}-\\x{FFFD}][\\x{10000}-\\x{EFFFF}]]))*)\\b", + "name": "entity.name.tag.custom.less" + }, + { + "match": "(?x)\\b( a | abbr | acronym | address | applet | area | article | aside | audio | b | base | basefont | bdi | bdo | big | blockquote | body | br | button | canvas | caption | circle | cite | clipPath | code | col | colgroup | content | data | dataList | dd | defs | del | details | dfn | dialog | dir | div | dl | dt | element | ellipse | em | embed | eventsource | fieldset | figcaption | figure | filter | footer | foreignObject | form | frame | frameset | g | glyph | glyphRef | h1 | h2 | h3 | h4 | h5 | h6 | head | header | hgroup | hr | html | i | iframe | image | img | input | ins | isindex | kbd | keygen | label | legend | li | line | linearGradient | link | main | map | mark | marker | mask | menu | meta | meter | nav | noframes | noscript | object | ol | optgroup | option | output | p | param | path | pattern | picture | polygon | polyline | pre | progress | q | radialGradient | rect | rp | ruby | rt | rtc | s | samp | script | section | select | shadow | small | source | span | stop | strike | strong | style | sub | summary | sup | svg | switch | symbol | table | tbody | td | template | textarea | textPath | tfoot | th | thead | time | title | tr | track | tref | tspan | tt | u | ul | use | var | video | wbr | xmp )\\b", + "name": "entity.name.tag.less" + }, + { + "begin": "(\\.)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.entity.less" + } + }, + "end": "(?![-\\w]|[^\\x{00}-\\x{9f}]|\\\\([A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9])|(\\@(?=\\{)))", + "name": "entity.other.attribute-name.class.less", + "patterns": [ + { + "include": "#less-variable-interpolation" + } + ] + }, + { + "begin": "(#)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.entity.less" + } + }, + "end": "(?![-\\w]|[^\\x{00}-\\x{9f}]|\\\\([A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9])|(\\@(?=\\{)))", + "name": "entity.other.attribute-name.id.less", + "patterns": [ + { + "include": "#less-variable-interpolation" + } + ] + }, + { + "begin": "(&)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.entity.less" + } + }, + "contentName": "entity.other.attribute-name.parent.less", + "end": "(?![-\\w]|[^\\x{00}-\\x{9f}]|\\\\([A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9])|(\\@(?=\\{)))", + "name": "entity.other.attribute-name.parent.less", + "patterns": [ + { + "include": "#less-variable-interpolation" + }, + { + "include": "#selectors" + } + ] + }, + { + "include": "#pseudo-elements" + }, + { + "include": "#pseudo-classes" + }, + { + "include": "#less-extend" + }, + { + "match": "(?!\\+_?:)(?:>{1,3}|[~+])(?![>~+;}])", + "name": "punctuation.separator.combinator.less" + }, + { + "match": "((?:>{1,3}|[~+])){2,}", + "name": "invalid.illegal.combinator.less" + }, + { + "match": "\\/deep\\/", + "name": "invalid.illegal.combinator.less" + }, + { + "begin": "\\[", + "captures": { + "0": { + "name": "punctuation.definition.entity.less" + } + }, + "end": "\\]", + "name": "meta.attribute-selector.less", + "patterns": [ + { + "include": "#less-variable-interpolation" + }, + { + "include": "#qualified-name" + }, + { + "match": "(-?(?:[[_a-zA-Z][^\\x{00}-\\x{7F}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))(?:[[-\\w][^\\x{00}-\\x{7F}]]|(?:\\\\\\h{1,6}[\\s\\t\\n\\f]?|\\\\[^\\n\\f\\h]))*)", + "name": "entity.other.attribute-name.less" + }, + { + "begin": "\\s*([~*|^$]?=)\\s*", + "captures": { + "1": { + "name": "keyword.operator.attribute-selector.less" + } + }, + "end": "(?=(\\s|\\]))", + "patterns": [ + { + "include": "#less-variable-interpolation" + }, + { + "match": "[^\\s\\]\\['\"]", + "name": "string.unquoted.less" + }, + { + "include": "#literal-string" + }, + { + "captures": { + "1": { + "name": "keyword.other.less" + } + }, + "match": "(?:\\s+([iI]))?" + }, + { + "match": "\\]", + "name": "punctuation.definition.entity.less" + } + ] + } + ] + }, + { + "captures": { + "1": { + "name": "punctuation.definition.arbitrary-repetition.less" + } + }, + "match": "\\s*(?:(,))" + }, + { + "match": "\\*", + "name": "entity.name.tag.wildcard.less" + } + ] + }, + "shape-functions": { + "patterns": [ + { + "begin": "\\b(rect)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.shape.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "match": "\\bauto\\b", + "name": "support.constant.property-value.less" + }, + { + "include": "#length-type" + }, + { + "include": "#comma-delimiter" + } + ] + } + ] + }, + { + "begin": "\\b(inset)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.shape.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "match": "\\bround\\b", + "name": "keyword.other.less" + }, + { + "include": "#length-type" + }, + { + "include": "#percentage-type" + } + ] + } + ] + }, + { + "begin": "\\b(circle|ellipse)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.shape.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "match": "\\bat\\b", + "name": "keyword.other.less" + }, + { + "match": "\\b(top|right|bottom|left|center|closest-side|farthest-side)\\b", + "name": "support.constant.property-value.less" + }, + { + "include": "#length-type" + }, + { + "include": "#percentage-type" + } + ] + } + ] + }, + { + "begin": "\\b(polygon)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.shape.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "match": "\\b(nonzero|evenodd)\\b", + "name": "support.constant.property-value.less" + }, + { + "include": "#length-type" + }, + { + "include": "#percentage-type" + } + ] + } + ] + } + ] + }, + "steps-function": { + "begin": "\\b(steps)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.timing.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#comma-delimiter" + }, + { + "include": "#integer-type" + }, + { + "match": "(end|middle|start)", + "name": "support.keyword.timing-direction.less" + } + ] + } + ] + }, + "string-content": { + "patterns": [ + { + "include": "#less-variable-interpolation" + }, + { + "match": "\\\\\\s*\\n", + "name": "constant.character.escape.newline.less" + }, + { + "match": "\\\\(\\h{1,6}|.)", + "name": "constant.character.escape.less" + } + ] + }, + "symbols-function": { + "begin": "\\b(symbols)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.counter.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "match": "\\b(cyclic|numeric|alphabetic|symbolic|fixed)\\b", + "name": "support.constant.symbol-type.less" + }, + { + "include": "#comma-delimiter" + }, + { + "include": "#literal-string" + }, + { + "include": "#image-type" + } + ] + } + ] + }, + "time-type": { + "captures": { + "1": { + "name": "keyword.other.unit.less" + } + }, + "match": "(?i:[-+]?(?:(?:\\d*\\.\\d+(?:[eE](?:[-+]?\\d+))*)|(?:[-+]?\\d+))(s|ms))\\b", + "name": "constant.numeric.less" + }, + "transform-functions": { + "patterns": [ + { + "begin": "\\b(matrix3d|scale3d|matrix|scale)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.transform.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#comma-delimiter" + }, + { + "include": "#number-type" + }, + { + "include": "#less-variables" + }, + { + "include": "#var-function" + } + ] + } + ] + }, + { + "begin": "\\b(translate(3d)?)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.transform.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#comma-delimiter" + }, + { + "include": "#percentage-type" + }, + { + "include": "#length-type" + }, + { + "include": "#number-type" + }, + { + "include": "#less-variables" + }, + { + "include": "#var-function" + } + ] + } + ] + }, + { + "begin": "\\b(translate[XY])(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.transform.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#percentage-type" + }, + { + "include": "#length-type" + }, + { + "include": "#number-type" + }, + { + "include": "#less-variables" + }, + { + "include": "#var-function" + } + ] + } + ] + }, + { + "begin": "\\b(rotate[XYZ]?|skew[XY])(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.transform.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#angle-type" + }, + { + "include": "#less-variables" + }, + { + "include": "#calc-function" + }, + { + "include": "#var-function" + } + ] + } + ] + }, + { + "begin": "\\b(skew)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.transform.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#comma-delimiter" + }, + { + "include": "#angle-type" + }, + { + "include": "#less-variables" + }, + { + "include": "#calc-function" + }, + { + "include": "#var-function" + } + ] + } + ] + }, + { + "begin": "\\b(translateZ|perspective)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.transform.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#length-type" + }, + { + "include": "#less-variables" + }, + { + "include": "#calc-function" + }, + { + "include": "#var-function" + } + ] + } + ] + }, + { + "begin": "\\b(rotate3d)(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.transform.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#comma-delimiter" + }, + { + "include": "#angle-type" + }, + { + "include": "#number-type" + }, + { + "include": "#less-variables" + }, + { + "include": "#calc-function" + }, + { + "include": "#var-function" + } + ] + } + ] + }, + { + "begin": "\\b(scale[XYZ])(?=\\()", + "beginCaptures": { + "0": { + "name": "support.function.transform.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#comma-delimiter" + }, + { + "include": "#number-type" + }, + { + "include": "#less-variables" + }, + { + "include": "#calc-function" + }, + { + "include": "#var-function" + } + ] + } + ] + } + ] + }, + "unicode-range": { + "captures": { + "1": { + "name": "support.constant.unicode-range.prefix.less" + }, + "2": { + "name": "constant.codepoint-range.less" + }, + "3": { + "name": "punctuation.section.range.less" + } + }, + "match": "(?i)(u\\+)([0-9a-f?]{1,6}(?:(-)[0-9a-f]{1,6})?)", + "name": "support.unicode-range.less" + }, + "unquoted-string": { + "match": "[^\\s'\"]", + "name": "string.unquoted.less" + }, + "url-function": { + "begin": "\\b(url)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.url.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#less-variables" + }, + { + "include": "#literal-string" + }, + { + "include": "#unquoted-string" + }, + { + "include": "#var-function" + } + ] + } + ] + }, + "var-function": { + "patterns": [ + { + "begin": "\\b(var)(?=\\()", + "beginCaptures": { + "1": { + "name": "support.function.var.less" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.group.end.less" + } + }, + "name": "meta.function-call.less", + "patterns": [ + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.group.begin.less" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#comma-delimiter" + }, + { + "include": "#custom-property-name" + }, + { + "include": "#less-variables" + } + ] + } + ] + } + ] + }, + "vendor-prefix": { + "match": "-(?:webkit|moz(-osx)?|ms|o)-", + "name": "support.type.vendor-prefix.less" } } } \ No newline at end of file diff --git a/extensions/theme-defaults/themes/dark_vs.json b/extensions/theme-defaults/themes/dark_vs.json index 54d69be0068..bbd2b232db2 100644 --- a/extensions/theme-defaults/themes/dark_vs.json +++ b/extensions/theme-defaults/themes/dark_vs.json @@ -94,7 +94,10 @@ } }, { - "scope": "entity.name.tag.css", + "scope": [ + "entity.name.tag.css", + "entity.name.tag.less" + ], "settings": { "foreground": "#d7ba7d" } @@ -108,10 +111,11 @@ { "scope": [ "entity.other.attribute-name.class.css", - "entity.other.attribute-name.class.mixin.css", + "source.css entity.other.attribute-name.class", "entity.other.attribute-name.id.css", "entity.other.attribute-name.parent-selector.css", - "entity.other.attribute-name.pseudo-class.css", + "entity.other.attribute-name.parent.less", + "source.css entity.other.attribute-name.pseudo-class", "entity.other.attribute-name.pseudo-element.css", "source.css.less entity.other.attribute-name.id", "entity.other.attribute-name.scss" @@ -308,7 +312,7 @@ "support.type.property-name", "variable.css", "variable.scss", - "variable.other.less", + "source.css.less variable.other", "source.coffee.embedded" ], "settings": { diff --git a/extensions/theme-defaults/themes/hc_black.json b/extensions/theme-defaults/themes/hc_black.json index 46ac7e671f8..07cf7df710e 100644 --- a/extensions/theme-defaults/themes/hc_black.json +++ b/extensions/theme-defaults/themes/hc_black.json @@ -86,7 +86,10 @@ } }, { - "scope": "entity.name.tag.css", + "scope": [ + "entity.name.tag.css", + "entity.name.tag.less" + ], "settings": { "foreground": "#d7ba7d" } @@ -100,10 +103,11 @@ { "scope": [ "entity.other.attribute-name.class.css", - "entity.other.attribute-name.class.mixin.css", + "source.css entity.other.attribute-name.class", "entity.other.attribute-name.id.css", "entity.other.attribute-name.parent-selector.css", - "entity.other.attribute-name.pseudo-class.css", + "entity.other.attribute-name.parent.less", + "source.css entity.other.attribute-name.pseudo-class", "entity.other.attribute-name.pseudo-element.css", "source.css.less entity.other.attribute-name.id", "entity.other.attribute-name.scss" @@ -268,7 +272,7 @@ "support.type.property-name", "variable.css", "variable.scss", - "variable.other.less", + "source.css.less variable.other", "source.coffee.embedded" ], "settings": { diff --git a/extensions/theme-defaults/themes/hc_light.json b/extensions/theme-defaults/themes/hc_light.json index aaf0e2f9cf3..ff22daa9d3d 100644 --- a/extensions/theme-defaults/themes/hc_light.json +++ b/extensions/theme-defaults/themes/hc_light.json @@ -80,10 +80,11 @@ { "scope": [ "entity.other.attribute-name.class.css", - "entity.other.attribute-name.class.mixin.css", + "source.css entity.other.attribute-name.class", "entity.other.attribute-name.id.css", "entity.other.attribute-name.parent-selector.css", - "entity.other.attribute-name.pseudo-class.css", + "entity.other.attribute-name.parent.less", + "source.css entity.other.attribute-name.pseudo-class", "entity.other.attribute-name.pseudo-element.css", "source.css.less entity.other.attribute-name.id", "entity.other.attribute-name.scss" @@ -281,7 +282,7 @@ "support.type.property-name", "variable.css", "variable.scss", - "variable.other.less", + "source.css.less variable.other", "source.coffee.embedded" ], "settings": { diff --git a/extensions/theme-defaults/themes/light_vs.json b/extensions/theme-defaults/themes/light_vs.json index b093cc73ca3..80fe7c7aaa7 100644 --- a/extensions/theme-defaults/themes/light_vs.json +++ b/extensions/theme-defaults/themes/light_vs.json @@ -114,10 +114,11 @@ { "scope": [ "entity.other.attribute-name.class.css", - "entity.other.attribute-name.class.mixin.css", + "source.css entity.other.attribute-name.class", "entity.other.attribute-name.id.css", "entity.other.attribute-name.parent-selector.css", - "entity.other.attribute-name.pseudo-class.css", + "entity.other.attribute-name.parent.less", + "source.css entity.other.attribute-name.pseudo-class", "entity.other.attribute-name.pseudo-element.css", "source.css.less entity.other.attribute-name.id", "entity.other.attribute-name.scss" @@ -329,7 +330,7 @@ "support.type.property-name", "variable.css", "variable.scss", - "variable.other.less", + "source.css.less variable.other", "source.coffee.embedded" ], "settings": { diff --git a/extensions/theme-quietlight/themes/quietlight-color-theme.json b/extensions/theme-quietlight/themes/quietlight-color-theme.json index 3705ed48608..0b6cd0be740 100644 --- a/extensions/theme-quietlight/themes/quietlight-color-theme.json +++ b/extensions/theme-quietlight/themes/quietlight-color-theme.json @@ -252,7 +252,8 @@ "meta.selector", "meta.selector entity", "meta.selector entity punctuation", - "entity.name.tag.css" + "entity.name.tag.css", + "entity.name.tag.less" ], "settings": { "foreground": "#7A3E9D" diff --git a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json index 840a1764bf1..28fb8cd7f28 100644 --- a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json +++ b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json @@ -140,7 +140,10 @@ }, { "name": "Keyword, Storage", - "scope": "keyword, storage, storage.type, entity.name.tag.css", + "scope": [ + "keyword, storage, storage.type, entity.name.tag.css", + "entity.name.tag.less" + ], "settings": { "fontStyle": "", "foreground": "#EBBBFF" diff --git a/extensions/vscode-colorize-tests/test/colorize-results/14119_less.json b/extensions/vscode-colorize-tests/test/colorize-results/14119_less.json index befc3ca8321..38a79e12ff6 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/14119_less.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/14119_less.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "source.css.less meta.selector.css entity.other.attribute-name.id punctuation.definition.entity.css", + "t": "source.css.less meta.selector.less entity.other.attribute-name.id.less punctuation.definition.entity.less", "r": { "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", "light_plus": "source.css.less entity.other.attribute-name.id: #800000", @@ -15,7 +15,7 @@ }, { "c": "f", - "t": "source.css.less meta.selector.css entity.other.attribute-name.id", + "t": "source.css.less meta.selector.less entity.other.attribute-name.id.less", "r": { "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", "light_plus": "source.css.less entity.other.attribute-name.id: #800000", @@ -29,7 +29,7 @@ }, { "c": "(", - "t": "source.css.less meta.brace.round.css", + "t": "source.css.less meta.selector.less meta.group.less punctuation.definition.group.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -43,35 +43,35 @@ }, { "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" } }, { "c": "hm", - "t": "source.css.less variable.other.less", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" } }, { "c": ":", - "t": "source.css.less punctuation.separator.key-value.css", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less punctuation.separator.key-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -85,7 +85,7 @@ }, { "c": " ", - "t": "source.css.less", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less meta.property-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -99,7 +99,7 @@ }, { "c": "\"", - "t": "source.css.less string.quoted.double.css punctuation.definition.string.begin.css", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less string.quoted.double.less punctuation.definition.string.begin.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -113,7 +113,7 @@ }, { "c": "broken highlighting in VS Code", - "t": "source.css.less string.quoted.double.css", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less string.quoted.double.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -127,7 +127,7 @@ }, { "c": "\"", - "t": "source.css.less string.quoted.double.css punctuation.definition.string.end.css", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less string.quoted.double.less punctuation.definition.string.end.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -141,7 +141,7 @@ }, { "c": ")", - "t": "source.css.less meta.brace.round.css", + "t": "source.css.less meta.selector.less meta.group.less punctuation.definition.group.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -155,7 +155,7 @@ }, { "c": " ", - "t": "source.css.less", + "t": "source.css.less meta.selector.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -169,7 +169,7 @@ }, { "c": "{", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", + "t": "source.css.less meta.property-list.less punctuation.definition.block.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -183,7 +183,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -197,21 +197,21 @@ }, { "c": "content", - "t": "source.css.less meta.property-list.css entity.name.tag.css", + "t": "source.css.less meta.property-list.less support.type.property-name.less", "r": { - "dark_plus": "entity.name.tag.css: #D7BA7D", - "light_plus": "entity.name.tag: #800000", - "dark_vs": "entity.name.tag.css: #D7BA7D", - "light_vs": "entity.name.tag: #800000", - "hc_black": "entity.name.tag.css: #D7BA7D", - "dark_modern": "entity.name.tag.css: #D7BA7D", - "hc_light": "entity.name.tag: #0F4A85", - "light_modern": "entity.name.tag: #800000" + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" } }, { "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -225,7 +225,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less meta.property-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -239,7 +239,7 @@ }, { "c": "\"", - "t": "source.css.less meta.property-list.css meta.property-value.css string.quoted.double.css punctuation.definition.string.begin.css", + "t": "source.css.less meta.property-list.less meta.property-value.less string.quoted.double.less punctuation.definition.string.begin.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -253,7 +253,7 @@ }, { "c": "\"", - "t": "source.css.less meta.property-list.css meta.property-value.css string.quoted.double.css punctuation.definition.string.end.css", + "t": "source.css.less meta.property-list.less meta.property-value.less string.quoted.double.less punctuation.definition.string.end.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -267,7 +267,7 @@ }, { "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -281,7 +281,7 @@ }, { "c": "}", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", + "t": "source.css.less punctuation.definition.block.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test-cssvariables_less.json b/extensions/vscode-colorize-tests/test/colorize-results/test-cssvariables_less.json index 859e808c155..856f013541b 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test-cssvariables_less.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test-cssvariables_less.json @@ -1,35 +1,35 @@ [ { "c": ":", - "t": "source.css.less entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", + "t": "source.css.less meta.selector.less meta.function-call.less punctuation.definition.entity.less", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" } }, { "c": "root", - "t": "source.css.less entity.other.attribute-name.pseudo-class.css", + "t": "source.css.less meta.selector.less meta.function-call.less entity.other.attribute-name.pseudo-class.less", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": " ", - "t": "source.css.less", + "t": "source.css.less meta.selector.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -43,7 +43,7 @@ }, { "c": "{", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", + "t": "source.css.less meta.property-list.less punctuation.definition.block.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -57,7 +57,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -71,35 +71,35 @@ }, { "c": "--", - "t": "source.css.less meta.property-list.css variable.other.less punctuation.definition.variable.less", + "t": "source.css.less meta.property-list.less support.type.custom-property.less punctuation.definition.custom-property.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "support.type: #4EC9B0", + "light_plus": "support.type: #267F99", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.type: #4EC9B0", + "dark_modern": "support.type: #4EC9B0", + "hc_light": "support.type: #185E73", + "light_modern": "support.type: #267F99" } }, { "c": "spacing-unit", - "t": "source.css.less meta.property-list.css variable.other.less", + "t": "source.css.less meta.property-list.less support.type.custom-property.less support.type.custom-property.name.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "support.type: #4EC9B0", + "light_plus": "support.type: #267F99", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.type: #4EC9B0", + "dark_modern": "support.type: #4EC9B0", + "hc_light": "support.type: #185E73", + "light_modern": "support.type: #267F99" } }, { "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -113,7 +113,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less meta.property-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -127,7 +127,7 @@ }, { "c": "6", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css", + "t": "source.css.less meta.property-list.less meta.property-value.less constant.numeric.less", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #098658", @@ -141,7 +141,7 @@ }, { "c": "px", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css keyword.other.unit.px.css", + "t": "source.css.less meta.property-list.less meta.property-value.less constant.numeric.less keyword.other.unit.less", "r": { "dark_plus": "keyword.other.unit: #B5CEA8", "light_plus": "keyword.other.unit: #098658", @@ -155,7 +155,7 @@ }, { "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -169,7 +169,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -183,35 +183,35 @@ }, { "c": "--", - "t": "source.css.less meta.property-list.css variable.other.less punctuation.definition.variable.less", + "t": "source.css.less meta.property-list.less support.type.custom-property.less punctuation.definition.custom-property.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "support.type: #4EC9B0", + "light_plus": "support.type: #267F99", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.type: #4EC9B0", + "dark_modern": "support.type: #4EC9B0", + "hc_light": "support.type: #185E73", + "light_modern": "support.type: #267F99" } }, { "c": "cell-padding", - "t": "source.css.less meta.property-list.css variable.other.less", + "t": "source.css.less meta.property-list.less support.type.custom-property.less support.type.custom-property.name.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "support.type: #4EC9B0", + "light_plus": "support.type: #267F99", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.type: #4EC9B0", + "dark_modern": "support.type: #4EC9B0", + "hc_light": "support.type: #185E73", + "light_modern": "support.type: #267F99" } }, { "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -225,7 +225,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less meta.property-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -239,7 +239,7 @@ }, { "c": "(", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less punctuation.definition.group.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -253,7 +253,7 @@ }, { "c": "4", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less constant.numeric.less", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #098658", @@ -267,7 +267,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -281,7 +281,7 @@ }, { "c": "*", - "t": "source.css.less meta.property-list.css meta.property-value.css keyword.operator.less", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less keyword.operator.arithmetic.less", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -294,8 +294,8 @@ } }, { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", + "c": " var", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -307,23 +307,9 @@ "light_modern": "default: #3B3B3B" } }, - { - "c": "var", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css support.function.misc.css", - "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA", - "dark_modern": "support.function: #DCDCAA", - "hc_light": "support.function: #5E2CBC", - "light_modern": "support.function: #795E26" - } - }, { "c": "(", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css punctuation.section.function.begin.bracket.round.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less meta.group.less punctuation.definition.group.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -336,22 +322,50 @@ } }, { - "c": "--spacing-unit", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css variable.argument.css", + "c": "--", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less meta.group.less keyword.operator.arithmetic.less", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE", - "dark_modern": "variable: #9CDCFE", - "hc_light": "variable: #001080", - "light_modern": "variable: #001080" + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" } }, { - "c": ")", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css punctuation.section.function.end.bracket.round.css", + "c": "spacing", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less meta.group.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "-", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less meta.group.less keyword.operator.arithmetic.less", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": "unit", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less meta.group.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -365,7 +379,21 @@ }, { "c": ")", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less meta.group.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ")", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less punctuation.definition.group.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -379,7 +407,7 @@ }, { "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -393,7 +421,7 @@ }, { "c": "}", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", + "t": "source.css.less punctuation.definition.block.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -407,21 +435,21 @@ }, { "c": "body", - "t": "source.css.less entity.name.tag.css", + "t": "source.css.less meta.selector.less entity.name.tag.less", "r": { - "dark_plus": "entity.name.tag.css: #D7BA7D", + "dark_plus": "entity.name.tag.less: #D7BA7D", "light_plus": "entity.name.tag: #800000", - "dark_vs": "entity.name.tag.css: #D7BA7D", + "dark_vs": "entity.name.tag.less: #D7BA7D", "light_vs": "entity.name.tag: #800000", - "hc_black": "entity.name.tag.css: #D7BA7D", - "dark_modern": "entity.name.tag.css: #D7BA7D", + "hc_black": "entity.name.tag.less: #D7BA7D", + "dark_modern": "entity.name.tag.less: #D7BA7D", "hc_light": "entity.name.tag: #0F4A85", "light_modern": "entity.name.tag: #800000" } }, { "c": " ", - "t": "source.css.less", + "t": "source.css.less meta.selector.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -435,7 +463,7 @@ }, { "c": "{", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", + "t": "source.css.less meta.property-list.less punctuation.definition.block.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -449,7 +477,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -463,7 +491,7 @@ }, { "c": "padding-left", - "t": "source.css.less meta.property-list.css support.type.property-name.css", + "t": "source.css.less meta.property-list.less support.type.property-name.less", "r": { "dark_plus": "support.type.property-name: #9CDCFE", "light_plus": "support.type.property-name: #E50000", @@ -477,7 +505,7 @@ }, { "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -491,7 +519,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less meta.property-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -505,7 +533,7 @@ }, { "c": "calc", - "t": "source.css.less meta.property-list.css meta.property-value.css support.function.any-method.builtin.less", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less support.function.calc.less", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -519,7 +547,7 @@ }, { "c": "(", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.definition.group.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -533,7 +561,7 @@ }, { "c": "4", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less constant.numeric.less", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #098658", @@ -547,7 +575,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -561,7 +589,7 @@ }, { "c": "*", - "t": "source.css.less meta.property-list.css meta.property-value.css keyword.operator.less", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less keyword.operator.arithmetic.less", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -575,7 +603,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -589,7 +617,7 @@ }, { "c": "var", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css support.function.misc.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less meta.function-call.less support.function.var.less", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -603,7 +631,7 @@ }, { "c": "(", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css punctuation.section.function.begin.bracket.round.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less meta.function-call.less punctuation.definition.group.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -616,22 +644,36 @@ } }, { - "c": "--spacing-unit", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css variable.argument.css", + "c": "--", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less meta.function-call.less support.type.custom-property.less punctuation.definition.custom-property.less", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", + "dark_plus": "support.type: #4EC9B0", + "light_plus": "support.type: #267F99", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE", - "dark_modern": "variable: #9CDCFE", - "hc_light": "variable: #001080", - "light_modern": "variable: #001080" + "hc_black": "support.type: #4EC9B0", + "dark_modern": "support.type: #4EC9B0", + "hc_light": "support.type: #185E73", + "light_modern": "support.type: #267F99" + } + }, + { + "c": "spacing-unit", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less meta.function-call.less support.type.custom-property.less support.type.custom-property.name.less", + "r": { + "dark_plus": "support.type: #4EC9B0", + "light_plus": "support.type: #267F99", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.type: #4EC9B0", + "dark_modern": "support.type: #4EC9B0", + "hc_light": "support.type: #185E73", + "light_modern": "support.type: #267F99" } }, { "c": ",", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css punctuation.separator.list.comma.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less meta.function-call.less punctuation.separator.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -644,50 +686,8 @@ } }, { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "5", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": "px", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css constant.numeric.css keyword.other.unit.px.css", - "r": { - "dark_plus": "keyword.other.unit: #B5CEA8", - "light_plus": "keyword.other.unit: #098658", - "dark_vs": "keyword.other.unit: #B5CEA8", - "light_vs": "keyword.other.unit: #098658", - "hc_black": "keyword.other.unit: #B5CEA8", - "dark_modern": "keyword.other.unit: #B5CEA8", - "hc_light": "keyword.other.unit: #096D48", - "light_modern": "keyword.other.unit: #098658" - } - }, - { - "c": ")", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.function.variable.css punctuation.section.function.end.bracket.round.css", + "c": " 5px", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less meta.function-call.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -701,7 +701,21 @@ }, { "c": ")", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less meta.function-call.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ")", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.definition.group.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -715,7 +729,7 @@ }, { "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -729,7 +743,7 @@ }, { "c": "}", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", + "t": "source.css.less punctuation.definition.block.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test-cssvariables_scss.json b/extensions/vscode-colorize-tests/test/colorize-results/test-cssvariables_scss.json index f5cddc27d06..ebeff26f98f 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test-cssvariables_scss.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test-cssvariables_scss.json @@ -3,28 +3,28 @@ "c": ":", "t": "source.css.scss entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "root", "t": "source.css.scss entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test-variables_css.json b/extensions/vscode-colorize-tests/test/colorize-results/test-variables_css.json index 8819269523a..b87252f2279 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test-variables_css.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test-variables_css.json @@ -3,28 +3,28 @@ "c": ":", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "root", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_css.json b/extensions/vscode-colorize-tests/test/colorize-results/test_css.json index 78a5ca00d07..0510fc82cd2 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_css.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_css.json @@ -3601,28 +3601,28 @@ "c": ":", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "link", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { @@ -3951,28 +3951,28 @@ "c": ":", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "visited", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { @@ -4385,28 +4385,28 @@ "c": ":", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "hover", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { @@ -4441,28 +4441,28 @@ "c": ":", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "focus", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { @@ -4497,28 +4497,28 @@ "c": ":", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "active", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { @@ -8879,28 +8879,28 @@ "c": ":", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "link", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { @@ -8963,28 +8963,28 @@ "c": ":", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "visited", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { @@ -10447,28 +10447,28 @@ "c": ":", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "link", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { @@ -10699,28 +10699,28 @@ "c": ":", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "visited", "t": "source.css meta.selector.css entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_less.json b/extensions/vscode-colorize-tests/test/colorize-results/test_less.json index 6937f0e26dc..3ab58551bd3 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_less.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_less.json @@ -1,7 +1,7 @@ [ { "c": "@", - "t": "source.css.less meta.at-rule.import.css keyword.control.at-rule.import.less punctuation.definition.keyword.less", + "t": "source.css.less meta.at-rule.import.less keyword.control.at-rule.import.less punctuation.definition.keyword.less", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -15,7 +15,7 @@ }, { "c": "import", - "t": "source.css.less meta.at-rule.import.css keyword.control.at-rule.import.less", + "t": "source.css.less meta.at-rule.import.less keyword.control.at-rule.import.less", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -29,7 +29,7 @@ }, { "c": " ", - "t": "source.css.less meta.at-rule.import.css", + "t": "source.css.less meta.at-rule.import.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -43,7 +43,7 @@ }, { "c": "\"", - "t": "source.css.less meta.at-rule.import.css string.quoted.double.css punctuation.definition.string.begin.css", + "t": "source.css.less meta.at-rule.import.less string.quoted.double.less punctuation.definition.string.begin.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -57,7 +57,7 @@ }, { "c": "mystyle.css", - "t": "source.css.less meta.at-rule.import.css string.quoted.double.css", + "t": "source.css.less meta.at-rule.import.less string.quoted.double.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -71,7 +71,7 @@ }, { "c": "\"", - "t": "source.css.less meta.at-rule.import.css string.quoted.double.css punctuation.definition.string.end.css", + "t": "source.css.less meta.at-rule.import.less string.quoted.double.less punctuation.definition.string.end.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -85,7 +85,7 @@ }, { "c": ";", - "t": "source.css.less meta.at-rule.import.css punctuation.terminator.rule.css", + "t": "source.css.less meta.at-rule.import.less punctuation.terminator.rule.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -99,7 +99,7 @@ }, { "c": "@", - "t": "source.css.less meta.at-rule.import.css keyword.control.at-rule.import.less punctuation.definition.keyword.less", + "t": "source.css.less meta.at-rule.import.less keyword.control.at-rule.import.less punctuation.definition.keyword.less", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -113,7 +113,7 @@ }, { "c": "import", - "t": "source.css.less meta.at-rule.import.css keyword.control.at-rule.import.less", + "t": "source.css.less meta.at-rule.import.less keyword.control.at-rule.import.less", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -126,8 +126,8 @@ } }, { - "c": " url", - "t": "source.css.less meta.at-rule.import.css", + "c": " ", + "t": "source.css.less meta.at-rule.import.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -139,9 +139,23 @@ "light_modern": "default: #3B3B3B" } }, + { + "c": "url", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less support.function.url.less", + "r": { + "dark_plus": "support.function: #DCDCAA", + "light_plus": "support.function: #795E26", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.function: #DCDCAA", + "dark_modern": "support.function: #DCDCAA", + "hc_light": "support.function: #5E2CBC", + "light_modern": "support.function: #795E26" + } + }, { "c": "(", - "t": "source.css.less meta.at-rule.import.css meta.brace.round.css", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less punctuation.definition.group.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -155,7 +169,7 @@ }, { "c": "\"", - "t": "source.css.less meta.at-rule.import.css string.quoted.double.css punctuation.definition.string.begin.css", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less string.quoted.double.less punctuation.definition.string.begin.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -169,7 +183,7 @@ }, { "c": "mystyle.css", - "t": "source.css.less meta.at-rule.import.css string.quoted.double.css", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less string.quoted.double.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -183,7 +197,7 @@ }, { "c": "\"", - "t": "source.css.less meta.at-rule.import.css string.quoted.double.css punctuation.definition.string.end.css", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less string.quoted.double.less punctuation.definition.string.end.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -197,7 +211,7 @@ }, { "c": ")", - "t": "source.css.less meta.at-rule.import.css meta.brace.round.css", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less punctuation.definition.group.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -211,7 +225,7 @@ }, { "c": ";", - "t": "source.css.less meta.at-rule.import.css punctuation.terminator.rule.css", + "t": "source.css.less meta.at-rule.import.less punctuation.terminator.rule.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -225,7 +239,7 @@ }, { "c": "@", - "t": "source.css.less meta.at-rule.import.css keyword.control.at-rule.import.less punctuation.definition.keyword.less", + "t": "source.css.less meta.at-rule.import.less keyword.control.at-rule.import.less punctuation.definition.keyword.less", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -239,7 +253,7 @@ }, { "c": "import", - "t": "source.css.less meta.at-rule.import.css keyword.control.at-rule.import.less", + "t": "source.css.less meta.at-rule.import.less keyword.control.at-rule.import.less", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -252,8 +266,8 @@ } }, { - "c": " url", - "t": "source.css.less meta.at-rule.import.css", + "c": " ", + "t": "source.css.less meta.at-rule.import.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -265,9 +279,23 @@ "light_modern": "default: #3B3B3B" } }, + { + "c": "url", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less support.function.url.less", + "r": { + "dark_plus": "support.function: #DCDCAA", + "light_plus": "support.function: #795E26", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.function: #DCDCAA", + "dark_modern": "support.function: #DCDCAA", + "hc_light": "support.function: #5E2CBC", + "light_modern": "support.function: #795E26" + } + }, { "c": "(", - "t": "source.css.less meta.at-rule.import.css meta.brace.round.css", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less punctuation.definition.group.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -281,7 +309,7 @@ }, { "c": "\"", - "t": "source.css.less meta.at-rule.import.css string.quoted.double.css punctuation.definition.string.begin.css", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less string.quoted.double.less punctuation.definition.string.begin.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -295,7 +323,7 @@ }, { "c": "bluish.css", - "t": "source.css.less meta.at-rule.import.css string.quoted.double.css", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less string.quoted.double.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -309,7 +337,7 @@ }, { "c": "\"", - "t": "source.css.less meta.at-rule.import.css string.quoted.double.css punctuation.definition.string.end.css", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less string.quoted.double.less punctuation.definition.string.end.less", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -323,7 +351,7 @@ }, { "c": ")", - "t": "source.css.less meta.at-rule.import.css meta.brace.round.css", + "t": "source.css.less meta.at-rule.import.less meta.function-call.less punctuation.definition.group.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -336,8 +364,8 @@ } }, { - "c": " projection", - "t": "source.css.less meta.at-rule.import.css", + "c": " ", + "t": "source.css.less meta.at-rule.import.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -349,9 +377,23 @@ "light_modern": "default: #3B3B3B" } }, + { + "c": "projection", + "t": "source.css.less meta.at-rule.import.less support.constant.media.less", + "r": { + "dark_plus": "support.constant.media: #CE9178", + "light_plus": "support.constant.media: #0451A5", + "dark_vs": "default: #D4D4D4", + "light_vs": "support.constant.media: #0451A5", + "hc_black": "support.constant.media: #CE9178", + "dark_modern": "support.constant.media: #CE9178", + "hc_light": "support.constant.media: #0451A5", + "light_modern": "support.constant.media: #0451A5" + } + }, { "c": ",", - "t": "source.css.less meta.at-rule.import.css punctuation.separator.list.comma.css", + "t": "source.css.less meta.at-rule.import.less punctuation.definition.arbitrary-repetition.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -364,8 +406,8 @@ } }, { - "c": " tv", - "t": "source.css.less meta.at-rule.import.css", + "c": " ", + "t": "source.css.less meta.at-rule.import.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -377,9 +419,23 @@ "light_modern": "default: #3B3B3B" } }, + { + "c": "tv", + "t": "source.css.less meta.at-rule.import.less support.constant.media.less", + "r": { + "dark_plus": "support.constant.media: #CE9178", + "light_plus": "support.constant.media: #0451A5", + "dark_vs": "default: #D4D4D4", + "light_vs": "support.constant.media: #0451A5", + "hc_black": "support.constant.media: #CE9178", + "dark_modern": "support.constant.media: #CE9178", + "hc_light": "support.constant.media: #0451A5", + "light_modern": "support.constant.media: #0451A5" + } + }, { "c": ";", - "t": "source.css.less meta.at-rule.import.css punctuation.terminator.rule.css", + "t": "source.css.less meta.at-rule.import.less punctuation.terminator.rule.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -393,35 +449,35 @@ }, { "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", + "t": "source.css.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" } }, { "c": "base", - "t": "source.css.less variable.other.less", + "t": "source.css.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" } }, { "c": ":", - "t": "source.css.less punctuation.separator.key-value.css", + "t": "source.css.less meta.property-value.less punctuation.separator.key-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -435,7 +491,7 @@ }, { "c": " ", - "t": "source.css.less", + "t": "source.css.less meta.property-value.less meta.property-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -448,1114 +504,36 @@ } }, { - "c": "#f938ab", - "t": "source.css.less constant.other.rgb-value.css", + "c": "#", + "t": "source.css.less meta.property-value.less constant.other.color.rgb-value.less punctuation.definition.constant.less", "r": { - "dark_plus": "constant.other.rgb-value: #CE9178", - "light_plus": "constant.other.rgb-value: #0451A5", + "dark_plus": "constant.other.color.rgb-value: #CE9178", + "light_plus": "constant.other.color.rgb-value: #0451A5", "dark_vs": "default: #D4D4D4", - "light_vs": "constant.other.rgb-value: #0451A5", - "hc_black": "constant.other.rgb-value: #CE9178", - "dark_modern": "constant.other.rgb-value: #CE9178", - "hc_light": "constant.other.rgb-value: #0451A5", - "light_modern": "constant.other.rgb-value: #0451A5" + "light_vs": "constant.other.color.rgb-value: #0451A5", + "hc_black": "constant.other.color.rgb-value: #CE9178", + "dark_modern": "constant.other.color.rgb-value: #CE9178", + "hc_light": "constant.other.color.rgb-value: #0451A5", + "light_modern": "constant.other.color.rgb-value: #0451A5" + } + }, + { + "c": "f938ab", + "t": "source.css.less meta.property-value.less constant.other.color.rgb-value.less", + "r": { + "dark_plus": "constant.other.color.rgb-value: #CE9178", + "light_plus": "constant.other.color.rgb-value: #0451A5", + "dark_vs": "default: #D4D4D4", + "light_vs": "constant.other.color.rgb-value: #0451A5", + "hc_black": "constant.other.color.rgb-value: #CE9178", + "dark_modern": "constant.other.color.rgb-value: #CE9178", + "hc_light": "constant.other.color.rgb-value: #0451A5", + "light_modern": "constant.other.color.rgb-value: #0451A5" } }, { "c": ";", - "t": "source.css.less punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ".box-shadow", - "t": "source.css.less entity.other.attribute-name.class.mixin.css", - "r": { - "dark_plus": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.class.mixin.css: #800000", - "dark_vs": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.class.mixin.css: #800000", - "hc_black": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.class.mixin.css: #0F4A85", - "light_modern": "entity.other.attribute-name.class.mixin.css: #800000" - } - }, - { - "c": "(", - "t": "source.css.less meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "style", - "t": "source.css.less variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ",", - "t": "source.css.less punctuation.separator.list.comma.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "c", - "t": "source.css.less variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ")", - "t": "source.css.less meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "when", - "t": "source.css.less keyword.control.logical.operator.less", - "r": { - "dark_plus": "keyword.control: #C586C0", - "light_plus": "keyword.control: #AF00DB", - "dark_vs": "keyword.control: #569CD6", - "light_vs": "keyword.control: #0000FF", - "hc_black": "keyword.control: #C586C0", - "dark_modern": "keyword.control: #C586C0", - "hc_light": "keyword.control: #B5200D", - "light_modern": "keyword.control: #AF00DB" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "(", - "t": "source.css.less meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "iscolor", - "t": "source.css.less support.function.type-checking.less", - "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA", - "dark_modern": "support.function: #DCDCAA", - "hc_light": "support.function: #5E2CBC", - "light_modern": "support.function: #795E26" - } - }, - { - "c": "(", - "t": "source.css.less meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "c", - "t": "source.css.less variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "))", - "t": "source.css.less meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "{", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "border-radius", - "t": "source.css.less meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "style", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "c", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "}", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ".box-shadow", - "t": "source.css.less entity.other.attribute-name.class.mixin.css", - "r": { - "dark_plus": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.class.mixin.css: #800000", - "dark_vs": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.class.mixin.css: #800000", - "hc_black": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.class.mixin.css: #0F4A85", - "light_modern": "entity.other.attribute-name.class.mixin.css: #800000" - } - }, - { - "c": "(", - "t": "source.css.less meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "style", - "t": "source.css.less variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ",", - "t": "source.css.less punctuation.separator.list.comma.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "alpha", - "t": "source.css.less variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "50", - "t": "source.css.less constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": "%", - "t": "source.css.less constant.numeric.css keyword.other.unit.percentage.css", - "r": { - "dark_plus": "keyword.other.unit: #B5CEA8", - "light_plus": "keyword.other.unit: #098658", - "dark_vs": "keyword.other.unit: #B5CEA8", - "light_vs": "keyword.other.unit: #098658", - "hc_black": "keyword.other.unit: #B5CEA8", - "dark_modern": "keyword.other.unit: #B5CEA8", - "hc_light": "keyword.other.unit: #096D48", - "light_modern": "keyword.other.unit: #098658" - } - }, - { - "c": ")", - "t": "source.css.less meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "when", - "t": "source.css.less keyword.control.logical.operator.less", - "r": { - "dark_plus": "keyword.control: #C586C0", - "light_plus": "keyword.control: #AF00DB", - "dark_vs": "keyword.control: #569CD6", - "light_vs": "keyword.control: #0000FF", - "hc_black": "keyword.control: #C586C0", - "dark_modern": "keyword.control: #C586C0", - "hc_light": "keyword.control: #B5200D", - "light_modern": "keyword.control: #AF00DB" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "(", - "t": "source.css.less meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "isnumber", - "t": "source.css.less support.function.type-checking.less", - "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA", - "dark_modern": "support.function: #DCDCAA", - "hc_light": "support.function: #5E2CBC", - "light_modern": "support.function: #795E26" - } - }, - { - "c": "(", - "t": "source.css.less meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "alpha", - "t": "source.css.less variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "))", - "t": "source.css.less meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "{", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ".box-shadow", - "t": "source.css.less meta.property-list.css entity.other.attribute-name.class.mixin.css", - "r": { - "dark_plus": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.class.mixin.css: #800000", - "dark_vs": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.class.mixin.css: #800000", - "hc_black": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.class.mixin.css: #0F4A85", - "light_modern": "entity.other.attribute-name.class.mixin.css: #800000" - } - }, - { - "c": "(", - "t": "source.css.less meta.property-list.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less meta.property-list.css variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "style", - "t": "source.css.less meta.property-list.css variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ",", - "t": "source.css.less meta.property-list.css punctuation.separator.list.comma.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "rgba", - "t": "source.css.less meta.property-list.css meta.function.color.css support.function.misc.css", - "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA", - "dark_modern": "support.function: #DCDCAA", - "hc_light": "support.function: #5E2CBC", - "light_modern": "support.function: #795E26" - } - }, - { - "c": "(", - "t": "source.css.less meta.property-list.css meta.function.color.css punctuation.section.function.begin.bracket.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "0", - "t": "source.css.less meta.property-list.css meta.function.color.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": ",", - "t": "source.css.less meta.property-list.css meta.function.color.css punctuation.separator.list.comma.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.function.color.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "0", - "t": "source.css.less meta.property-list.css meta.function.color.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": ",", - "t": "source.css.less meta.property-list.css meta.function.color.css punctuation.separator.list.comma.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.function.color.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "0", - "t": "source.css.less meta.property-list.css meta.function.color.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": ",", - "t": "source.css.less meta.property-list.css meta.function.color.css punctuation.separator.list.comma.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " @", - "t": "source.css.less meta.property-list.css meta.function.color.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "alpha", - "t": "source.css.less meta.property-list.css meta.function.color.css support.constant.property-value.css", - "r": { - "dark_plus": "support.constant.property-value: #CE9178", - "light_plus": "support.constant.property-value: #0451A5", - "dark_vs": "default: #D4D4D4", - "light_vs": "support.constant.property-value: #0451A5", - "hc_black": "support.constant.property-value: #CE9178", - "dark_modern": "support.constant.property-value: #CE9178", - "hc_light": "support.constant.property-value: #0451A5", - "light_modern": "support.constant.property-value: #0451A5" - } - }, - { - "c": ")", - "t": "source.css.less meta.property-list.css meta.function.color.css punctuation.section.function.end.bracket.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ")", - "t": "source.css.less meta.property-list.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "}", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", + "t": "source.css.less meta.property-value.less punctuation.terminator.rule.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1569,35 +547,287 @@ }, { "c": ".", - "t": "source.css.less entity.other.attribute-name.class.css punctuation.definition.entity.css", + "t": "source.css.less meta.selector.less entity.other.attribute-name.class.less punctuation.definition.entity.less", "r": { - "dark_plus": "entity.other.attribute-name.class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.class.css: #800000", - "dark_vs": "entity.other.attribute-name.class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.class.css: #800000", - "hc_black": "entity.other.attribute-name.class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.class: #800000", + "dark_vs": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.class: #800000", + "hc_black": "source.css entity.other.attribute-name.class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.class: #800000" } }, { - "c": "box", - "t": "source.css.less entity.other.attribute-name.class.css", + "c": "box-shadow", + "t": "source.css.less meta.selector.less entity.other.attribute-name.class.less", "r": { - "dark_plus": "entity.other.attribute-name.class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.class.css: #800000", - "dark_vs": "entity.other.attribute-name.class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.class.css: #800000", - "hc_black": "entity.other.attribute-name.class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.class: #800000", + "dark_vs": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.class: #800000", + "hc_black": "source.css entity.other.attribute-name.class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.class: #800000" + } + }, + { + "c": "(", + "t": "source.css.less meta.selector.less meta.group.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "style", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ",", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less punctuation.separator.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" } }, { "c": " ", - "t": "source.css.less", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "c", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ")", + "t": "source.css.less meta.selector.less meta.group.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "when", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less keyword.control.conditional.less", + "r": { + "dark_plus": "keyword.control: #C586C0", + "light_plus": "keyword.control: #AF00DB", + "dark_vs": "keyword.control: #569CD6", + "light_vs": "keyword.control: #0000FF", + "hc_black": "keyword.control: #C586C0", + "dark_modern": "keyword.control: #C586C0", + "hc_light": "keyword.control: #B5200D", + "light_modern": "keyword.control: #AF00DB" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "(", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "iscolor", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less meta.function-call.less support.function.type.less", + "r": { + "dark_plus": "support.function: #DCDCAA", + "light_plus": "support.function: #795E26", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.function: #DCDCAA", + "dark_modern": "support.function: #DCDCAA", + "hc_light": "support.function: #5E2CBC", + "light_modern": "support.function: #795E26" + } + }, + { + "c": "(", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less meta.function-call.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less meta.function-call.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "c", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less meta.function-call.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ")", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less meta.function-call.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ")", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1611,7 +841,7 @@ }, { "c": "{", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", + "t": "source.css.less meta.property-list.less punctuation.definition.block.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1625,7 +855,7 @@ }, { "c": "\t", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1638,8 +868,8 @@ } }, { - "c": "color", - "t": "source.css.less meta.property-list.css support.type.property-name.css", + "c": "border-radius", + "t": "source.css.less meta.property-list.less support.type.property-name.less", "r": { "dark_plus": "support.type.property-name: #9CDCFE", "light_plus": "support.type.property-name: #E50000", @@ -1653,7 +883,7 @@ }, { "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1667,7 +897,931 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-list.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "style", + "t": "source.css.less meta.property-list.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less variable.other.readwrite.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-list.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "c", + "t": "source.css.less meta.property-list.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.css.less punctuation.definition.block.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ".", + "t": "source.css.less meta.selector.less entity.other.attribute-name.class.less punctuation.definition.entity.less", + "r": { + "dark_plus": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.class: #800000", + "dark_vs": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.class: #800000", + "hc_black": "source.css entity.other.attribute-name.class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.class: #800000" + } + }, + { + "c": "box-shadow", + "t": "source.css.less meta.selector.less entity.other.attribute-name.class.less", + "r": { + "dark_plus": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.class: #800000", + "dark_vs": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.class: #800000", + "hc_black": "source.css entity.other.attribute-name.class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.class: #800000" + } + }, + { + "c": "(", + "t": "source.css.less meta.selector.less meta.group.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "style", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ",", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less punctuation.separator.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "alpha", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "50", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": "%", + "t": "source.css.less meta.selector.less meta.group.less meta.property-value.less constant.numeric.less keyword.other.unit.less", + "r": { + "dark_plus": "keyword.other.unit: #B5CEA8", + "light_plus": "keyword.other.unit: #098658", + "dark_vs": "keyword.other.unit: #B5CEA8", + "light_vs": "keyword.other.unit: #098658", + "hc_black": "keyword.other.unit: #B5CEA8", + "dark_modern": "keyword.other.unit: #B5CEA8", + "hc_light": "keyword.other.unit: #096D48", + "light_modern": "keyword.other.unit: #098658" + } + }, + { + "c": ")", + "t": "source.css.less meta.selector.less meta.group.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "when", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less keyword.control.conditional.less", + "r": { + "dark_plus": "keyword.control: #C586C0", + "light_plus": "keyword.control: #AF00DB", + "dark_vs": "keyword.control: #569CD6", + "light_vs": "keyword.control: #0000FF", + "hc_black": "keyword.control: #C586C0", + "dark_modern": "keyword.control: #C586C0", + "hc_light": "keyword.control: #B5200D", + "light_modern": "keyword.control: #AF00DB" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "(", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "isnumber", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less meta.function-call.less support.function.type.less", + "r": { + "dark_plus": "support.function: #DCDCAA", + "light_plus": "support.function: #795E26", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.function: #DCDCAA", + "dark_modern": "support.function: #DCDCAA", + "hc_light": "support.function: #5E2CBC", + "light_modern": "support.function: #795E26" + } + }, + { + "c": "(", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less meta.function-call.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less meta.function-call.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "alpha", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less meta.function-call.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ")", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less meta.group.less meta.function-call.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ")", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less meta.conditional.guarded-namespace.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.css.less meta.property-list.less punctuation.definition.block.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ".", + "t": "source.css.less meta.property-list.less meta.selector.less entity.other.attribute-name.class.less punctuation.definition.entity.less", + "r": { + "dark_plus": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.class: #800000", + "dark_vs": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.class: #800000", + "hc_black": "source.css entity.other.attribute-name.class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.class: #800000" + } + }, + { + "c": "box-shadow", + "t": "source.css.less meta.property-list.less meta.selector.less entity.other.attribute-name.class.less", + "r": { + "dark_plus": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.class: #800000", + "dark_vs": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.class: #800000", + "hc_black": "source.css entity.other.attribute-name.class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.class: #800000" + } + }, + { + "c": "(", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "style", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ",", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less punctuation.separator.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "rgba", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less support.function.color.less", + "r": { + "dark_plus": "support.function: #DCDCAA", + "light_plus": "support.function: #795E26", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.function: #DCDCAA", + "dark_modern": "support.function: #DCDCAA", + "hc_light": "support.function: #5E2CBC", + "light_modern": "support.function: #795E26" + } + }, + { + "c": "(", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "0", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": ",", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less punctuation.separator.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "0", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": ",", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less punctuation.separator.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "0", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": ",", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less punctuation.separator.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "alpha", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ")", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less meta.property-value.less meta.function-call.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ")", + "t": "source.css.less meta.property-list.less meta.selector.less meta.group.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.css.less punctuation.definition.block.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ".", + "t": "source.css.less meta.selector.less entity.other.attribute-name.class.less punctuation.definition.entity.less", + "r": { + "dark_plus": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.class: #800000", + "dark_vs": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.class: #800000", + "hc_black": "source.css entity.other.attribute-name.class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.class: #800000" + } + }, + { + "c": "box", + "t": "source.css.less meta.selector.less entity.other.attribute-name.class.less", + "r": { + "dark_plus": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.class: #800000", + "dark_vs": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.class: #800000", + "hc_black": "source.css entity.other.attribute-name.class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.class: #800000" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.css.less meta.property-list.less punctuation.definition.block.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "color", + "t": "source.css.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1681,7 +1835,7 @@ }, { "c": "saturate", - "t": "source.css.less meta.property-list.css meta.property-value.css support.function.any-method.builtin.less", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less support.function.color-operation.less", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -1695,7 +1849,7 @@ }, { "c": "(", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.definition.group.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1709,35 +1863,35 @@ }, { "c": "@", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less punctuation.definition.variable.less", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less variable.other.readwrite.less punctuation.definition.variable.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" } }, { "c": "base", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less variable.other.readwrite.less support.other.variable.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" } }, { "c": ",", - "t": "source.css.less meta.property-list.css meta.property-value.css punctuation.separator.list.comma.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.separator.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1751,7 +1905,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1765,7 +1919,7 @@ }, { "c": "5", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less constant.numeric.less", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #098658", @@ -1779,7 +1933,7 @@ }, { "c": "%", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css keyword.other.unit.percentage.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less constant.numeric.less keyword.other.unit.less", "r": { "dark_plus": "keyword.other.unit: #B5CEA8", "light_plus": "keyword.other.unit: #098658", @@ -1793,7 +1947,7 @@ }, { "c": ")", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.definition.group.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1807,7 +1961,7 @@ }, { "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1821,7 +1975,7 @@ }, { "c": "\t", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1835,7 +1989,7 @@ }, { "c": "border-color", - "t": "source.css.less meta.property-list.css support.type.property-name.css", + "t": "source.css.less meta.property-list.less support.type.property-name.less", "r": { "dark_plus": "support.type.property-name: #9CDCFE", "light_plus": "support.type.property-name: #E50000", @@ -1849,7 +2003,7 @@ }, { "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1863,7 +2017,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css", + "t": "source.css.less meta.property-list.less meta.property-value.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1877,2443 +2031,7 @@ }, { "c": "lighten", - "t": "source.css.less meta.property-list.css meta.property-value.css support.constant.property-value.css", - "r": { - "dark_plus": "support.constant.property-value: #CE9178", - "light_plus": "support.constant.property-value: #0451A5", - "dark_vs": "default: #D4D4D4", - "light_vs": "support.constant.property-value: #0451A5", - "hc_black": "support.constant.property-value: #CE9178", - "dark_modern": "support.constant.property-value: #CE9178", - "hc_light": "support.constant.property-value: #0451A5", - "light_modern": "support.constant.property-value: #0451A5" - } - }, - { - "c": "(", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "base", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ",", - "t": "source.css.less meta.property-list.css meta.property-value.css punctuation.separator.list.comma.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "30", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": "%", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css keyword.other.unit.percentage.css", - "r": { - "dark_plus": "keyword.other.unit: #B5CEA8", - "light_plus": "keyword.other.unit: #098658", - "dark_vs": "keyword.other.unit: #B5CEA8", - "light_vs": "keyword.other.unit: #098658", - "hc_black": "keyword.other.unit: #B5CEA8", - "dark_modern": "keyword.other.unit: #B5CEA8", - "hc_light": "keyword.other.unit: #096D48", - "light_modern": "keyword.other.unit: #098658" - } - }, - { - "c": ")", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "div", - "t": "source.css.less meta.property-list.css entity.name.tag.css", - "r": { - "dark_plus": "entity.name.tag.css: #D7BA7D", - "light_plus": "entity.name.tag: #800000", - "dark_vs": "entity.name.tag.css: #D7BA7D", - "light_vs": "entity.name.tag: #800000", - "hc_black": "entity.name.tag.css: #D7BA7D", - "dark_modern": "entity.name.tag.css: #D7BA7D", - "hc_light": "entity.name.tag: #0F4A85", - "light_modern": "entity.name.tag: #800000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "{", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t\t", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ".box-shadow", - "t": "source.css.less meta.property-list.css meta.property-list.css entity.other.attribute-name.class.mixin.css", - "r": { - "dark_plus": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.class.mixin.css: #800000", - "dark_vs": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.class.mixin.css: #800000", - "hc_black": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.class.mixin.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.class.mixin.css: #0F4A85", - "light_modern": "entity.other.attribute-name.class.mixin.css: #800000" - } - }, - { - "c": "((", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "0", - "t": "source.css.less meta.property-list.css meta.property-list.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "0", - "t": "source.css.less meta.property-list.css meta.property-list.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "5", - "t": "source.css.less meta.property-list.css meta.property-list.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": "px", - "t": "source.css.less meta.property-list.css meta.property-list.css constant.numeric.css keyword.other.unit.px.css", - "r": { - "dark_plus": "keyword.other.unit: #B5CEA8", - "light_plus": "keyword.other.unit: #098658", - "dark_vs": "keyword.other.unit: #B5CEA8", - "light_vs": "keyword.other.unit: #098658", - "hc_black": "keyword.other.unit: #B5CEA8", - "dark_modern": "keyword.other.unit: #B5CEA8", - "hc_light": "keyword.other.unit: #096D48", - "light_modern": "keyword.other.unit: #098658" - } - }, - { - "c": ")", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ",", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.separator.list.comma.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "30", - "t": "source.css.less meta.property-list.css meta.property-list.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": "%", - "t": "source.css.less meta.property-list.css meta.property-list.css constant.numeric.css keyword.other.unit.percentage.css", - "r": { - "dark_plus": "keyword.other.unit: #B5CEA8", - "light_plus": "keyword.other.unit: #098658", - "dark_vs": "keyword.other.unit: #B5CEA8", - "light_vs": "keyword.other.unit: #098658", - "hc_black": "keyword.other.unit: #B5CEA8", - "dark_modern": "keyword.other.unit: #B5CEA8", - "hc_light": "keyword.other.unit: #096D48", - "light_modern": "keyword.other.unit: #098658" - } - }, - { - "c": ")", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "}", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "}", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "#", - "t": "source.css.less meta.selector.css entity.other.attribute-name.id punctuation.definition.entity.css", - "r": { - "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_plus": "source.css.less entity.other.attribute-name.id: #800000", - "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_vs": "source.css.less entity.other.attribute-name.id: #800000", - "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", - "light_modern": "source.css.less entity.other.attribute-name.id: #800000" - } - }, - { - "c": "header", - "t": "source.css.less meta.selector.css entity.other.attribute-name.id", - "r": { - "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_plus": "source.css.less entity.other.attribute-name.id: #800000", - "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_vs": "source.css.less entity.other.attribute-name.id: #800000", - "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", - "light_modern": "source.css.less entity.other.attribute-name.id: #800000" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "{", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "h1", - "t": "source.css.less meta.property-list.css entity.name.tag.css", - "r": { - "dark_plus": "entity.name.tag.css: #D7BA7D", - "light_plus": "entity.name.tag: #800000", - "dark_vs": "entity.name.tag.css: #D7BA7D", - "light_vs": "entity.name.tag: #800000", - "hc_black": "entity.name.tag.css: #D7BA7D", - "dark_modern": "entity.name.tag.css: #D7BA7D", - "hc_light": "entity.name.tag: #0F4A85", - "light_modern": "entity.name.tag: #800000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "{", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t\t", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "font-size", - "t": "source.css.less meta.property-list.css meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "26", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-value.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": "px", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-value.css constant.numeric.css keyword.other.unit.px.css", - "r": { - "dark_plus": "keyword.other.unit: #B5CEA8", - "light_plus": "keyword.other.unit: #098658", - "dark_vs": "keyword.other.unit: #B5CEA8", - "light_vs": "keyword.other.unit: #098658", - "hc_black": "keyword.other.unit: #B5CEA8", - "dark_modern": "keyword.other.unit: #B5CEA8", - "hc_light": "keyword.other.unit: #096D48", - "light_modern": "keyword.other.unit: #098658" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t\t", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "font-weight", - "t": "source.css.less meta.property-list.css meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "bold", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-value.css support.constant.property-value.css", - "r": { - "dark_plus": "support.constant.property-value: #CE9178", - "light_plus": "support.constant.property-value: #0451A5", - "dark_vs": "default: #D4D4D4", - "light_vs": "support.constant.property-value: #0451A5", - "hc_black": "support.constant.property-value: #CE9178", - "dark_modern": "support.constant.property-value: #CE9178", - "hc_light": "support.constant.property-value: #0451A5", - "light_modern": "support.constant.property-value: #0451A5" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "}", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "p", - "t": "source.css.less meta.property-list.css entity.name.tag.css", - "r": { - "dark_plus": "entity.name.tag.css: #D7BA7D", - "light_plus": "entity.name.tag: #800000", - "dark_vs": "entity.name.tag.css: #D7BA7D", - "light_vs": "entity.name.tag: #800000", - "hc_black": "entity.name.tag.css: #D7BA7D", - "dark_modern": "entity.name.tag.css: #D7BA7D", - "hc_light": "entity.name.tag: #0F4A85", - "light_modern": "entity.name.tag: #800000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "{", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "font-size", - "t": "source.css.less meta.property-list.css meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "12", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-value.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": "px", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-value.css constant.numeric.css keyword.other.unit.px.css", - "r": { - "dark_plus": "keyword.other.unit: #B5CEA8", - "light_plus": "keyword.other.unit: #098658", - "dark_vs": "keyword.other.unit: #B5CEA8", - "light_vs": "keyword.other.unit: #098658", - "hc_black": "keyword.other.unit: #B5CEA8", - "dark_modern": "keyword.other.unit: #B5CEA8", - "hc_light": "keyword.other.unit: #096D48", - "light_modern": "keyword.other.unit: #098658" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t\t", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "a", - "t": "source.css.less meta.property-list.css meta.property-list.css entity.name.tag.css", - "r": { - "dark_plus": "entity.name.tag.css: #D7BA7D", - "light_plus": "entity.name.tag: #800000", - "dark_vs": "entity.name.tag.css: #D7BA7D", - "light_vs": "entity.name.tag: #800000", - "hc_black": "entity.name.tag.css: #D7BA7D", - "dark_modern": "entity.name.tag.css: #D7BA7D", - "hc_light": "entity.name.tag: #0F4A85", - "light_modern": "entity.name.tag: #800000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "{", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "text-decoration", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "none", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css meta.property-value.css support.constant.property-value.css", - "r": { - "dark_plus": "support.constant.property-value: #CE9178", - "light_plus": "support.constant.property-value: #0451A5", - "dark_vs": "default: #D4D4D4", - "light_vs": "support.constant.property-value: #0451A5", - "hc_black": "support.constant.property-value: #CE9178", - "dark_modern": "support.constant.property-value: #CE9178", - "hc_light": "support.constant.property-value: #0451A5", - "light_modern": "support.constant.property-value: #0451A5" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t\t\t", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "&", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css entity.other.attribute-name.parent-selector.css punctuation.definition.entity.css", - "r": { - "dark_plus": "entity.other.attribute-name.parent-selector.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.parent-selector.css: #800000", - "dark_vs": "entity.other.attribute-name.parent-selector.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.parent-selector.css: #800000", - "hc_black": "entity.other.attribute-name.parent-selector.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.parent-selector.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.parent-selector.css: #0F4A85", - "light_modern": "entity.other.attribute-name.parent-selector.css: #800000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", - "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" - } - }, - { - "c": "hover", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css entity.other.attribute-name.pseudo-class.css", - "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "{", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "border-width", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "1", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css meta.property-list.css meta.property-value.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": "px", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css meta.property-list.css meta.property-value.css constant.numeric.css keyword.other.unit.px.css", - "r": { - "dark_plus": "keyword.other.unit: #B5CEA8", - "light_plus": "keyword.other.unit: #098658", - "dark_vs": "keyword.other.unit: #B5CEA8", - "light_vs": "keyword.other.unit: #098658", - "hc_black": "keyword.other.unit: #B5CEA8", - "dark_modern": "keyword.other.unit: #B5CEA8", - "hc_light": "keyword.other.unit: #096D48", - "light_modern": "keyword.other.unit: #098658" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "}", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t\t", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "}", - "t": "source.css.less meta.property-list.css meta.property-list.css meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "}", - "t": "source.css.less meta.property-list.css meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "}", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "the-border", - "t": "source.css.less variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "1", - "t": "source.css.less constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": "px", - "t": "source.css.less constant.numeric.css keyword.other.unit.px.css", - "r": { - "dark_plus": "keyword.other.unit: #B5CEA8", - "light_plus": "keyword.other.unit: #098658", - "dark_vs": "keyword.other.unit: #B5CEA8", - "light_vs": "keyword.other.unit: #098658", - "hc_black": "keyword.other.unit: #B5CEA8", - "dark_modern": "keyword.other.unit: #B5CEA8", - "hc_light": "keyword.other.unit: #096D48", - "light_modern": "keyword.other.unit: #098658" - } - }, - { - "c": ";", - "t": "source.css.less punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "base-color", - "t": "source.css.less variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "#111", - "t": "source.css.less constant.other.rgb-value.css", - "r": { - "dark_plus": "constant.other.rgb-value: #CE9178", - "light_plus": "constant.other.rgb-value: #0451A5", - "dark_vs": "default: #D4D4D4", - "light_vs": "constant.other.rgb-value: #0451A5", - "hc_black": "constant.other.rgb-value: #CE9178", - "dark_modern": "constant.other.rgb-value: #CE9178", - "hc_light": "constant.other.rgb-value: #0451A5", - "light_modern": "constant.other.rgb-value: #0451A5" - } - }, - { - "c": ";", - "t": "source.css.less punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "red", - "t": "source.css.less variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "#842210", - "t": "source.css.less constant.other.rgb-value.css", - "r": { - "dark_plus": "constant.other.rgb-value: #CE9178", - "light_plus": "constant.other.rgb-value: #0451A5", - "dark_vs": "default: #D4D4D4", - "light_vs": "constant.other.rgb-value: #0451A5", - "hc_black": "constant.other.rgb-value: #CE9178", - "dark_modern": "constant.other.rgb-value: #CE9178", - "hc_light": "constant.other.rgb-value: #0451A5", - "light_modern": "constant.other.rgb-value: #0451A5" - } - }, - { - "c": ";", - "t": "source.css.less punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "#", - "t": "source.css.less meta.selector.css entity.other.attribute-name.id punctuation.definition.entity.css", - "r": { - "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_plus": "source.css.less entity.other.attribute-name.id: #800000", - "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_vs": "source.css.less entity.other.attribute-name.id: #800000", - "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", - "light_modern": "source.css.less entity.other.attribute-name.id: #800000" - } - }, - { - "c": "header", - "t": "source.css.less meta.selector.css entity.other.attribute-name.id", - "r": { - "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_plus": "source.css.less entity.other.attribute-name.id: #800000", - "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_vs": "source.css.less entity.other.attribute-name.id: #800000", - "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", - "light_modern": "source.css.less entity.other.attribute-name.id: #800000" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "{", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "color", - "t": "source.css.less meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "(", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "base-color", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "*", - "t": "source.css.less meta.property-list.css meta.property-value.css keyword.operator.less", - "r": { - "dark_plus": "keyword.operator: #D4D4D4", - "light_plus": "keyword.operator: #000000", - "dark_vs": "keyword.operator: #D4D4D4", - "light_vs": "keyword.operator: #000000", - "hc_black": "keyword.operator: #D4D4D4", - "dark_modern": "keyword.operator: #D4D4D4", - "hc_light": "keyword.operator: #000000", - "light_modern": "keyword.operator: #000000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "3", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": ")", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "border-left", - "t": "source.css.less meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "the-border", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "border-right", - "t": "source.css.less meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "(", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "the-border", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "*", - "t": "source.css.less meta.property-list.css meta.property-value.css keyword.operator.less", - "r": { - "dark_plus": "keyword.operator: #D4D4D4", - "light_plus": "keyword.operator: #000000", - "dark_vs": "keyword.operator: #D4D4D4", - "light_vs": "keyword.operator: #000000", - "hc_black": "keyword.operator: #D4D4D4", - "dark_modern": "keyword.operator: #D4D4D4", - "hc_light": "keyword.operator: #000000", - "light_modern": "keyword.operator: #000000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "2", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #098658", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #098658", - "hc_black": "constant.numeric: #B5CEA8", - "dark_modern": "constant.numeric: #B5CEA8", - "hc_light": "constant.numeric: #096D48", - "light_modern": "constant.numeric: #098658" - } - }, - { - "c": ")", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "}", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "#", - "t": "source.css.less meta.selector.css entity.other.attribute-name.id punctuation.definition.entity.css", - "r": { - "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_plus": "source.css.less entity.other.attribute-name.id: #800000", - "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_vs": "source.css.less entity.other.attribute-name.id: #800000", - "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", - "light_modern": "source.css.less entity.other.attribute-name.id: #800000" - } - }, - { - "c": "footer", - "t": "source.css.less meta.selector.css entity.other.attribute-name.id", - "r": { - "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_plus": "source.css.less entity.other.attribute-name.id: #800000", - "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "light_vs": "source.css.less entity.other.attribute-name.id: #800000", - "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", - "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", - "light_modern": "source.css.less entity.other.attribute-name.id: #800000" - } - }, - { - "c": " ", - "t": "source.css.less", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "{", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.begin.bracket.curly.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "color", - "t": "source.css.less meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "(", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "@", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less punctuation.definition.variable.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": "base-color", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less", - "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "+", - "t": "source.css.less meta.property-list.css meta.property-value.css keyword.operator.less", - "r": { - "dark_plus": "keyword.operator: #D4D4D4", - "light_plus": "keyword.operator: #000000", - "dark_vs": "keyword.operator: #D4D4D4", - "light_vs": "keyword.operator: #000000", - "hc_black": "keyword.operator: #D4D4D4", - "dark_modern": "keyword.operator: #D4D4D4", - "hc_light": "keyword.operator: #000000", - "light_modern": "keyword.operator: #000000" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "#003300", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.other.rgb-value.css", - "r": { - "dark_plus": "constant.other.rgb-value: #CE9178", - "light_plus": "constant.other.rgb-value: #0451A5", - "dark_vs": "default: #D4D4D4", - "light_vs": "constant.other.rgb-value: #0451A5", - "hc_black": "constant.other.rgb-value: #CE9178", - "dark_modern": "constant.other.rgb-value: #CE9178", - "hc_light": "constant.other.rgb-value: #0451A5", - "light_modern": "constant.other.rgb-value: #0451A5" - } - }, - { - "c": ")", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "\t", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "border-color", - "t": "source.css.less meta.property-list.css support.type.property-name.css", - "r": { - "dark_plus": "support.type.property-name: #9CDCFE", - "light_plus": "support.type.property-name: #E50000", - "dark_vs": "support.type.property-name: #9CDCFE", - "light_vs": "support.type.property-name: #E50000", - "hc_black": "support.type.property-name: #D4D4D4", - "dark_modern": "support.type.property-name: #9CDCFE", - "hc_light": "support.type.property-name: #264F78", - "light_modern": "support.type.property-name: #E50000" - } - }, - { - "c": ":", - "t": "source.css.less meta.property-list.css punctuation.separator.key-value.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": " ", - "t": "source.css.less meta.property-list.css", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF", - "dark_modern": "default: #CCCCCC", - "hc_light": "default: #292929", - "light_modern": "default: #3B3B3B" - } - }, - { - "c": "desaturate", - "t": "source.css.less meta.property-list.css meta.property-value.css support.function.any-method.builtin.less", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less support.function.color-operation.less", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -4327,7 +2045,7 @@ }, { "c": "(", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.definition.group.begin.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -4341,35 +2059,35 @@ }, { "c": "@", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less punctuation.definition.variable.less", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less variable.other.readwrite.less punctuation.definition.variable.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" } }, { - "c": "red", - "t": "source.css.less meta.property-list.css meta.property-value.css variable.other.less", + "c": "base", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less variable.other.readwrite.less support.other.variable.less", "r": { - "dark_plus": "variable.other.less: #9CDCFE", - "light_plus": "variable.other.less: #E50000", - "dark_vs": "variable.other.less: #9CDCFE", - "light_vs": "variable.other.less: #E50000", - "hc_black": "variable.other.less: #D4D4D4", - "dark_modern": "variable.other.less: #9CDCFE", - "hc_light": "variable.other.less: #264F78", - "light_modern": "variable.other.less: #E50000" + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" } }, { "c": ",", - "t": "source.css.less meta.property-list.css meta.property-value.css punctuation.separator.list.comma.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.separator.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -4383,7 +2101,7 @@ }, { "c": " ", - "t": "source.css.less meta.property-list.css meta.property-value.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -4396,8 +2114,8 @@ } }, { - "c": "10", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css", + "c": "30", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less constant.numeric.less", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #098658", @@ -4411,7 +2129,7 @@ }, { "c": "%", - "t": "source.css.less meta.property-list.css meta.property-value.css constant.numeric.css keyword.other.unit.percentage.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less constant.numeric.less keyword.other.unit.less", "r": { "dark_plus": "keyword.other.unit: #B5CEA8", "light_plus": "keyword.other.unit: #098658", @@ -4425,7 +2143,7 @@ }, { "c": ")", - "t": "source.css.less meta.property-list.css meta.property-value.css meta.brace.round.css", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.definition.group.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -4439,7 +2157,329 @@ }, { "c": ";", - "t": "source.css.less meta.property-list.css punctuation.terminator.rule.css", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "div", + "t": "source.css.less meta.property-list.less meta.selector.less entity.name.tag.less", + "r": { + "dark_plus": "entity.name.tag.less: #D7BA7D", + "light_plus": "entity.name.tag: #800000", + "dark_vs": "entity.name.tag.less: #D7BA7D", + "light_vs": "entity.name.tag: #800000", + "hc_black": "entity.name.tag.less: #D7BA7D", + "dark_modern": "entity.name.tag.less: #D7BA7D", + "hc_light": "entity.name.tag: #0F4A85", + "light_modern": "entity.name.tag: #800000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.selector.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.definition.block.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.css.less meta.property-list.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ".", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less entity.other.attribute-name.class.less punctuation.definition.entity.less", + "r": { + "dark_plus": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.class: #800000", + "dark_vs": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.class: #800000", + "hc_black": "source.css entity.other.attribute-name.class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.class: #800000" + } + }, + { + "c": "box-shadow", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less entity.other.attribute-name.class.less", + "r": { + "dark_plus": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.class: #800000", + "dark_vs": "source.css entity.other.attribute-name.class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.class: #800000", + "hc_black": "source.css entity.other.attribute-name.class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.class: #800000" + } + }, + { + "c": "(", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "(", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less meta.group.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "0", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less meta.group.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less meta.group.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "0", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less meta.group.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less meta.group.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "5", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less meta.group.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": "px", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less meta.group.less constant.numeric.less keyword.other.unit.less", + "r": { + "dark_plus": "keyword.other.unit: #B5CEA8", + "light_plus": "keyword.other.unit: #098658", + "dark_vs": "keyword.other.unit: #B5CEA8", + "light_vs": "keyword.other.unit: #098658", + "hc_black": "keyword.other.unit: #B5CEA8", + "dark_modern": "keyword.other.unit: #B5CEA8", + "hc_light": "keyword.other.unit: #096D48", + "light_modern": "keyword.other.unit: #098658" + } + }, + { + "c": ")", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less meta.group.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ",", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less punctuation.separator.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "30", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": "%", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less constant.numeric.less keyword.other.unit.less", + "r": { + "dark_plus": "keyword.other.unit: #B5CEA8", + "light_plus": "keyword.other.unit: #098658", + "dark_vs": "keyword.other.unit: #B5CEA8", + "light_vs": "keyword.other.unit: #098658", + "hc_black": "keyword.other.unit: #B5CEA8", + "dark_modern": "keyword.other.unit: #B5CEA8", + "hc_light": "keyword.other.unit: #096D48", + "light_modern": "keyword.other.unit: #098658" + } + }, + { + "c": ")", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less meta.group.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -4453,7 +2493,2177 @@ }, { "c": "}", - "t": "source.css.less meta.property-list.css punctuation.section.property-list.end.bracket.curly.css", + "t": "source.css.less meta.property-list.less punctuation.definition.block.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.css.less punctuation.definition.block.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "#", + "t": "source.css.less meta.selector.less entity.other.attribute-name.id.less punctuation.definition.entity.less", + "r": { + "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_plus": "source.css.less entity.other.attribute-name.id: #800000", + "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_vs": "source.css.less entity.other.attribute-name.id: #800000", + "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", + "light_modern": "source.css.less entity.other.attribute-name.id: #800000" + } + }, + { + "c": "header", + "t": "source.css.less meta.selector.less entity.other.attribute-name.id.less", + "r": { + "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_plus": "source.css.less entity.other.attribute-name.id: #800000", + "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_vs": "source.css.less entity.other.attribute-name.id: #800000", + "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", + "light_modern": "source.css.less entity.other.attribute-name.id: #800000" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.css.less meta.property-list.less punctuation.definition.block.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "h1", + "t": "source.css.less meta.property-list.less meta.selector.less entity.name.tag.less", + "r": { + "dark_plus": "entity.name.tag.less: #D7BA7D", + "light_plus": "entity.name.tag: #800000", + "dark_vs": "entity.name.tag.less: #D7BA7D", + "light_vs": "entity.name.tag: #800000", + "hc_black": "entity.name.tag.less: #D7BA7D", + "dark_modern": "entity.name.tag.less: #D7BA7D", + "hc_light": "entity.name.tag: #0F4A85", + "light_modern": "entity.name.tag: #800000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.selector.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.definition.block.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.css.less meta.property-list.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "font-size", + "t": "source.css.less meta.property-list.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "26", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-value.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": "px", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-value.less constant.numeric.less keyword.other.unit.less", + "r": { + "dark_plus": "keyword.other.unit: #B5CEA8", + "light_plus": "keyword.other.unit: #098658", + "dark_vs": "keyword.other.unit: #B5CEA8", + "light_vs": "keyword.other.unit: #098658", + "hc_black": "keyword.other.unit: #B5CEA8", + "dark_modern": "keyword.other.unit: #B5CEA8", + "hc_light": "keyword.other.unit: #096D48", + "light_modern": "keyword.other.unit: #098658" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.css.less meta.property-list.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "font-weight", + "t": "source.css.less meta.property-list.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "bold", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-value.less support.constant.property-value.less", + "r": { + "dark_plus": "support.constant.property-value: #CE9178", + "light_plus": "support.constant.property-value: #0451A5", + "dark_vs": "default: #D4D4D4", + "light_vs": "support.constant.property-value: #0451A5", + "hc_black": "support.constant.property-value: #CE9178", + "dark_modern": "support.constant.property-value: #CE9178", + "hc_light": "support.constant.property-value: #0451A5", + "light_modern": "support.constant.property-value: #0451A5" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.css.less meta.property-list.less punctuation.definition.block.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "p", + "t": "source.css.less meta.property-list.less meta.selector.less entity.name.tag.less", + "r": { + "dark_plus": "entity.name.tag.less: #D7BA7D", + "light_plus": "entity.name.tag: #800000", + "dark_vs": "entity.name.tag.less: #D7BA7D", + "light_vs": "entity.name.tag: #800000", + "hc_black": "entity.name.tag.less: #D7BA7D", + "dark_modern": "entity.name.tag.less: #D7BA7D", + "hc_light": "entity.name.tag: #0F4A85", + "light_modern": "entity.name.tag: #800000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.selector.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.definition.block.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "font-size", + "t": "source.css.less meta.property-list.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "12", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-value.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": "px", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-value.less constant.numeric.less keyword.other.unit.less", + "r": { + "dark_plus": "keyword.other.unit: #B5CEA8", + "light_plus": "keyword.other.unit: #098658", + "dark_vs": "keyword.other.unit: #B5CEA8", + "light_vs": "keyword.other.unit: #098658", + "hc_black": "keyword.other.unit: #B5CEA8", + "dark_modern": "keyword.other.unit: #B5CEA8", + "hc_light": "keyword.other.unit: #096D48", + "light_modern": "keyword.other.unit: #098658" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.css.less meta.property-list.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "a", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less entity.name.tag.less", + "r": { + "dark_plus": "entity.name.tag.less: #D7BA7D", + "light_plus": "entity.name.tag: #800000", + "dark_vs": "entity.name.tag.less: #D7BA7D", + "light_vs": "entity.name.tag: #800000", + "hc_black": "entity.name.tag.less: #D7BA7D", + "dark_modern": "entity.name.tag.less: #D7BA7D", + "hc_light": "entity.name.tag: #0F4A85", + "light_modern": "entity.name.tag: #800000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.selector.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less punctuation.definition.block.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "text-decoration", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "none", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-value.less support.constant.property-value.less", + "r": { + "dark_plus": "support.constant.property-value: #CE9178", + "light_plus": "support.constant.property-value: #0451A5", + "dark_vs": "default: #D4D4D4", + "light_vs": "support.constant.property-value: #0451A5", + "hc_black": "support.constant.property-value: #CE9178", + "dark_modern": "support.constant.property-value: #CE9178", + "hc_light": "support.constant.property-value: #0451A5", + "light_modern": "support.constant.property-value: #0451A5" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t\t", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "&", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.selector.less entity.other.attribute-name.parent.less punctuation.definition.entity.less", + "r": { + "dark_plus": "entity.other.attribute-name.parent.less: #D7BA7D", + "light_plus": "entity.other.attribute-name.parent.less: #800000", + "dark_vs": "entity.other.attribute-name.parent.less: #D7BA7D", + "light_vs": "entity.other.attribute-name.parent.less: #800000", + "hc_black": "entity.other.attribute-name.parent.less: #D7BA7D", + "dark_modern": "entity.other.attribute-name.parent.less: #D7BA7D", + "hc_light": "entity.other.attribute-name.parent.less: #0F4A85", + "light_modern": "entity.other.attribute-name.parent.less: #800000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.selector.less meta.function-call.less punctuation.definition.entity.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "hover", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.selector.less meta.function-call.less entity.other.attribute-name.pseudo-class.less", + "r": { + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.selector.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-list.less punctuation.definition.block.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "border-width", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "1", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-value.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": "px", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-value.less constant.numeric.less keyword.other.unit.less", + "r": { + "dark_plus": "keyword.other.unit: #B5CEA8", + "light_plus": "keyword.other.unit: #098658", + "dark_vs": "keyword.other.unit: #B5CEA8", + "light_vs": "keyword.other.unit: #098658", + "hc_black": "keyword.other.unit: #B5CEA8", + "dark_modern": "keyword.other.unit: #B5CEA8", + "hc_light": "keyword.other.unit: #096D48", + "light_modern": "keyword.other.unit: #098658" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.css.less meta.property-list.less meta.property-list.less meta.property-list.less punctuation.definition.block.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t\t", + "t": "source.css.less meta.property-list.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.css.less meta.property-list.less meta.property-list.less punctuation.definition.block.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.css.less meta.property-list.less punctuation.definition.block.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.css.less punctuation.definition.block.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "the-border", + "t": "source.css.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-value.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-value.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "1", + "t": "source.css.less meta.property-value.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": "px", + "t": "source.css.less meta.property-value.less constant.numeric.less keyword.other.unit.less", + "r": { + "dark_plus": "keyword.other.unit: #B5CEA8", + "light_plus": "keyword.other.unit: #098658", + "dark_vs": "keyword.other.unit: #B5CEA8", + "light_vs": "keyword.other.unit: #098658", + "hc_black": "keyword.other.unit: #B5CEA8", + "dark_modern": "keyword.other.unit: #B5CEA8", + "hc_light": "keyword.other.unit: #096D48", + "light_modern": "keyword.other.unit: #098658" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-value.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "base-color", + "t": "source.css.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-value.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-value.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "#", + "t": "source.css.less meta.property-value.less constant.other.color.rgb-value.less punctuation.definition.constant.less", + "r": { + "dark_plus": "constant.other.color.rgb-value: #CE9178", + "light_plus": "constant.other.color.rgb-value: #0451A5", + "dark_vs": "default: #D4D4D4", + "light_vs": "constant.other.color.rgb-value: #0451A5", + "hc_black": "constant.other.color.rgb-value: #CE9178", + "dark_modern": "constant.other.color.rgb-value: #CE9178", + "hc_light": "constant.other.color.rgb-value: #0451A5", + "light_modern": "constant.other.color.rgb-value: #0451A5" + } + }, + { + "c": "111", + "t": "source.css.less meta.property-value.less constant.other.color.rgb-value.less", + "r": { + "dark_plus": "constant.other.color.rgb-value: #CE9178", + "light_plus": "constant.other.color.rgb-value: #0451A5", + "dark_vs": "default: #D4D4D4", + "light_vs": "constant.other.color.rgb-value: #0451A5", + "hc_black": "constant.other.color.rgb-value: #CE9178", + "dark_modern": "constant.other.color.rgb-value: #CE9178", + "hc_light": "constant.other.color.rgb-value: #0451A5", + "light_modern": "constant.other.color.rgb-value: #0451A5" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-value.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "red", + "t": "source.css.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-value.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-value.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "#", + "t": "source.css.less meta.property-value.less constant.other.color.rgb-value.less punctuation.definition.constant.less", + "r": { + "dark_plus": "constant.other.color.rgb-value: #CE9178", + "light_plus": "constant.other.color.rgb-value: #0451A5", + "dark_vs": "default: #D4D4D4", + "light_vs": "constant.other.color.rgb-value: #0451A5", + "hc_black": "constant.other.color.rgb-value: #CE9178", + "dark_modern": "constant.other.color.rgb-value: #CE9178", + "hc_light": "constant.other.color.rgb-value: #0451A5", + "light_modern": "constant.other.color.rgb-value: #0451A5" + } + }, + { + "c": "842210", + "t": "source.css.less meta.property-value.less constant.other.color.rgb-value.less", + "r": { + "dark_plus": "constant.other.color.rgb-value: #CE9178", + "light_plus": "constant.other.color.rgb-value: #0451A5", + "dark_vs": "default: #D4D4D4", + "light_vs": "constant.other.color.rgb-value: #0451A5", + "hc_black": "constant.other.color.rgb-value: #CE9178", + "dark_modern": "constant.other.color.rgb-value: #CE9178", + "hc_light": "constant.other.color.rgb-value: #0451A5", + "light_modern": "constant.other.color.rgb-value: #0451A5" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-value.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "#", + "t": "source.css.less meta.selector.less entity.other.attribute-name.id.less punctuation.definition.entity.less", + "r": { + "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_plus": "source.css.less entity.other.attribute-name.id: #800000", + "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_vs": "source.css.less entity.other.attribute-name.id: #800000", + "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", + "light_modern": "source.css.less entity.other.attribute-name.id: #800000" + } + }, + { + "c": "header", + "t": "source.css.less meta.selector.less entity.other.attribute-name.id.less", + "r": { + "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_plus": "source.css.less entity.other.attribute-name.id: #800000", + "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_vs": "source.css.less entity.other.attribute-name.id: #800000", + "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", + "light_modern": "source.css.less entity.other.attribute-name.id: #800000" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.css.less meta.property-list.less punctuation.definition.block.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "color", + "t": "source.css.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "(", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "base-color", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "*", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less keyword.operator.arithmetic.less", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "3", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": ")", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "border-left", + "t": "source.css.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-list.less meta.property-value.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "the-border", + "t": "source.css.less meta.property-list.less meta.property-value.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "border-right", + "t": "source.css.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "(", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "the-border", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "*", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less keyword.operator.arithmetic.less", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "2", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": ")", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.css.less punctuation.definition.block.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "#", + "t": "source.css.less meta.selector.less entity.other.attribute-name.id.less punctuation.definition.entity.less", + "r": { + "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_plus": "source.css.less entity.other.attribute-name.id: #800000", + "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_vs": "source.css.less entity.other.attribute-name.id: #800000", + "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", + "light_modern": "source.css.less entity.other.attribute-name.id: #800000" + } + }, + { + "c": "footer", + "t": "source.css.less meta.selector.less entity.other.attribute-name.id.less", + "r": { + "dark_plus": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_plus": "source.css.less entity.other.attribute-name.id: #800000", + "dark_vs": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "light_vs": "source.css.less entity.other.attribute-name.id: #800000", + "hc_black": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "dark_modern": "source.css.less entity.other.attribute-name.id: #D7BA7D", + "hc_light": "source.css.less entity.other.attribute-name.id: #0F4A85", + "light_modern": "source.css.less entity.other.attribute-name.id: #800000" + } + }, + { + "c": " ", + "t": "source.css.less meta.selector.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "{", + "t": "source.css.less meta.property-list.less punctuation.definition.block.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "color", + "t": "source.css.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "(", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "base-color", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "+", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less keyword.operator.arithmetic.less", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4", + "dark_modern": "keyword.operator: #D4D4D4", + "hc_light": "keyword.operator: #000000", + "light_modern": "keyword.operator: #000000" + } + }, + { + "c": " #", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "003300", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": ")", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.group.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "\t", + "t": "source.css.less meta.property-list.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "border-color", + "t": "source.css.less meta.property-list.less support.type.property-name.less", + "r": { + "dark_plus": "support.type.property-name: #9CDCFE", + "light_plus": "support.type.property-name: #E50000", + "dark_vs": "support.type.property-name: #9CDCFE", + "light_vs": "support.type.property-name: #E50000", + "hc_black": "support.type.property-name: #D4D4D4", + "dark_modern": "support.type.property-name: #9CDCFE", + "hc_light": "support.type.property-name: #264F78", + "light_modern": "support.type.property-name: #E50000" + } + }, + { + "c": ":", + "t": "source.css.less meta.property-list.less punctuation.separator.key-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "desaturate", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less support.function.color-operation.less", + "r": { + "dark_plus": "support.function: #DCDCAA", + "light_plus": "support.function: #795E26", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "support.function: #DCDCAA", + "dark_modern": "support.function: #DCDCAA", + "hc_light": "support.function: #5E2CBC", + "light_modern": "support.function: #795E26" + } + }, + { + "c": "(", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.definition.group.begin.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "@", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less variable.other.readwrite.less punctuation.definition.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": "red", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less variable.other.readwrite.less support.other.variable.less", + "r": { + "dark_plus": "source.css.less variable.other: #9CDCFE", + "light_plus": "source.css.less variable.other: #E50000", + "dark_vs": "source.css.less variable.other: #9CDCFE", + "light_vs": "source.css.less variable.other: #E50000", + "hc_black": "source.css.less variable.other: #D4D4D4", + "dark_modern": "source.css.less variable.other: #9CDCFE", + "hc_light": "source.css.less variable.other: #264F78", + "light_modern": "source.css.less variable.other: #E50000" + } + }, + { + "c": ",", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.separator.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": " ", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "10", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less constant.numeric.less", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #098658", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #098658", + "hc_black": "constant.numeric: #B5CEA8", + "dark_modern": "constant.numeric: #B5CEA8", + "hc_light": "constant.numeric: #096D48", + "light_modern": "constant.numeric: #098658" + } + }, + { + "c": "%", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less constant.numeric.less keyword.other.unit.less", + "r": { + "dark_plus": "keyword.other.unit: #B5CEA8", + "light_plus": "keyword.other.unit: #098658", + "dark_vs": "keyword.other.unit: #B5CEA8", + "light_vs": "keyword.other.unit: #098658", + "hc_black": "keyword.other.unit: #B5CEA8", + "dark_modern": "keyword.other.unit: #B5CEA8", + "hc_light": "keyword.other.unit: #096D48", + "light_modern": "keyword.other.unit: #098658" + } + }, + { + "c": ")", + "t": "source.css.less meta.property-list.less meta.property-value.less meta.function-call.less punctuation.definition.group.end.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": ";", + "t": "source.css.less meta.property-list.less punctuation.terminator.rule.less", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF", + "dark_modern": "default: #CCCCCC", + "hc_light": "default: #292929", + "light_modern": "default: #3B3B3B" + } + }, + { + "c": "}", + "t": "source.css.less punctuation.definition.block.end.less", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", diff --git a/extensions/vscode-colorize-tests/test/colorize-results/test_scss.json b/extensions/vscode-colorize-tests/test/colorize-results/test_scss.json index 843cf288784..b316b8a0531 100644 --- a/extensions/vscode-colorize-tests/test/colorize-results/test_scss.json +++ b/extensions/vscode-colorize-tests/test/colorize-results/test_scss.json @@ -1333,28 +1333,28 @@ "c": ":", "t": "source.css.scss meta.property-list.scss meta.property-list.scss entity.other.attribute-name.pseudo-class.css punctuation.definition.entity.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { "c": "hover", "t": "source.css.scss meta.property-list.scss meta.property-list.scss entity.other.attribute-name.pseudo-class.css", "r": { - "dark_plus": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_plus": "entity.other.attribute-name.pseudo-class.css: #800000", - "dark_vs": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "light_vs": "entity.other.attribute-name.pseudo-class.css: #800000", - "hc_black": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "dark_modern": "entity.other.attribute-name.pseudo-class.css: #D7BA7D", - "hc_light": "entity.other.attribute-name.pseudo-class.css: #0F4A85", - "light_modern": "entity.other.attribute-name.pseudo-class.css: #800000" + "dark_plus": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_plus": "source.css entity.other.attribute-name.pseudo-class: #800000", + "dark_vs": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "light_vs": "source.css entity.other.attribute-name.pseudo-class: #800000", + "hc_black": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "dark_modern": "source.css entity.other.attribute-name.pseudo-class: #D7BA7D", + "hc_light": "source.css entity.other.attribute-name.pseudo-class: #0F4A85", + "light_modern": "source.css entity.other.attribute-name.pseudo-class: #800000" } }, { From 0f40f3512918df144131004a864ed26308677a4f Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 08:47:52 -0800 Subject: [PATCH 071/240] Don't show sticky scroll for null commands --- .../terminal.stickyScroll.contribution.ts | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index e5f5c9c6944..d787551aaaa 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -60,16 +60,19 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi xtermReady(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { this._xterm = xterm; + // Only show sticky scroll in the normal buffer this.add(xterm.raw.buffer.onBufferChange(buffer => { const element = this._ensureElement(); setVisibility(buffer.type === 'normal', element); })); + // Refresh sticky scroll on write/scroll events // TODO: Skip these when hidden this.add(xterm.raw.onScroll(() => this._refresh())); this.add(xterm.raw.onLineFeed(() => this._refresh())); this.add(addStandardDisposableListener(xterm.raw.element!.querySelector('.xterm-viewport')!, 'scroll', () => this._refresh())); + // Create the overlay TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { const overlay = new ctor({ rows: 1, @@ -127,27 +130,28 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi return; } - this._currentStickyMarker = marker; - if (element.textContent === '') { - hide(element); - } else { - show(element); - } - console.log('command!', command); - if (this._stickyScrollOverlay) { this._stickyScrollOverlay.write('\x1b[H\x1b[K'); // TODO: Serializing all content up to the required line is inefficient; support providing single line/range serialize addon const s = this._serializeAddon?.serialize({ scrollback: this._xterm.raw.buffer.active.baseY - marker.line }); - if (s) { - const content = s.substring(0, s.indexOf('\r')); - if (content) { - this._stickyScrollOverlay.write(content); - } + const content = s ? s.substring(0, s.indexOf('\r')) : undefined; + if (content) { + this._stickyScrollOverlay.write(content); + // Debug log to show the command + // this._stickyScrollOverlay.write(` [${command?.command}]`); + + // TODO: Only sync options when needed + this._syncOptions(this._stickyScrollOverlay, this._xterm.raw); + } + + if (command && ('commandStartMarker' in command ? !command.isInvalid : command?.command)) { + this._currentStickyMarker = marker; + show(element); + } else { + hide(element); } - this._syncOptions(this._stickyScrollOverlay, this._xterm.raw); } } @@ -159,6 +163,8 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi this._xterm!.raw.element!.parentElement!.append(this._element); const hoverOverlay = $('.hover-overlay'); + + // Scroll to the command on click this.add(addStandardDisposableListener(hoverOverlay, 'click', e => { if (this._xterm && this._currentStickyMarker) { this._xterm.scrollToLine(this._currentStickyMarker.line, ScrollPosition.Middle); From c5b893b621c4758020b25b71d38bb0a2dc08f4e9 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 08:53:02 -0800 Subject: [PATCH 072/240] Improve flow of refresh function --- .../terminal.stickyScroll.contribution.ts | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index d787551aaaa..95adcc3e635 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -100,25 +100,27 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi if (!this._xterm?.raw?.element) { return; } - this._currentStickyMarker = undefined; + // TODO: Cache const commandDetection = this._instance.capabilities.get(TerminalCapability.CommandDetection); if (!commandDetection) { return; } + // The command from viewportY + 1 is used because this one will not be obscured by sticky // scroll. const command = commandDetection.getCommandForLine(this._xterm.raw.buffer.active.viewportY + 1); const element = this._ensureElement(); + this._currentStickyMarker = undefined; - // TODO: Expose unified interface for fetching line content - const marker = command && 'commandStartMarker' in command - ? command.commandStartMarker - : command && 'marker' in command - ? command.marker - : undefined; + // Sticky scroll only works with non-partial commands + if (!command || !('marker' in command)) { + hide(element); + return; + } // Hide if the marker doesn't exist or has been trimmed from the scrollback + const marker = command.marker; if (!marker || marker.line === -1) { hide(element); return; @@ -130,6 +132,9 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi return; } + // TODO: Support multi-line prompts + // TODO: SUpport multi-line commands + if (this._stickyScrollOverlay) { this._stickyScrollOverlay.write('\x1b[H\x1b[K'); // TODO: Serializing all content up to the required line is inefficient; support providing single line/range serialize addon @@ -146,12 +151,14 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi this._syncOptions(this._stickyScrollOverlay, this._xterm.raw); } - if (command && ('commandStartMarker' in command ? !command.isInvalid : command?.command)) { + if (command.exitCode !== undefined) { this._currentStickyMarker = marker; show(element); } else { hide(element); } + } else { + hide(element); } } From 75c624fb11cd91d27f02cdc2b30af30b5a3ababe Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 09:13:57 -0800 Subject: [PATCH 073/240] Separate sticky scroll overlay logic and setup logic --- .../terminal.stickyScroll.contribution.ts | 256 +++--------------- .../terminalStickyScrollColorRegistry.ts | 25 ++ .../browser/terminalStickyScrollOverlay.ts | 223 +++++++++++++++ 3 files changed, 289 insertions(+), 215 deletions(-) create mode 100644 src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry.ts create mode 100644 src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index 95adcc3e635..1e758513772 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -3,32 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { CanvasAddon as CanvasAddonType } from '@xterm/addon-canvas'; -import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; -import type { IMarker, Terminal as RawXtermTerminal } from '@xterm/xterm'; -import { importAMDNodeModule } from 'vs/amdX'; -import { $, addStandardDisposableListener, append, hide, setVisibility, show } from 'vs/base/browser/dom'; -import { Color } from 'vs/base/common/color'; -import { throttle } from 'vs/base/common/decorators'; -import { DisposableStore } from 'vs/base/common/lifecycle'; +import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; +import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/stickyScroll'; -import { localize } from 'vs/nls'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; -import { registerColor } from 'vs/platform/theme/common/colorRegistry'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; import { ITerminalContribution, ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; -import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; -import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; -import { TERMINAL_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; - -let CanvasAddon: typeof CanvasAddonType; -let SerializeAddon: typeof SerializeAddonType; +import { TerminalStickyScrollOverlay } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay'; class TerminalStickyScrollContribution extends DisposableStore implements ITerminalContribution { static readonly ID = 'terminal.stickyScroll'; @@ -38,227 +22,69 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi } private _xterm?: IXtermTerminal & { raw: RawXtermTerminal }; - private _element?: HTMLElement; - private _stickyScrollOverlay?: RawXtermTerminal; - private _currentStickyMarker?: IMarker; + private _overlay = new MutableDisposable(); - private _serializeAddon?: SerializeAddonType; - private _canvasAddon?: CanvasAddonType; + private _enableListeners = new MutableDisposable(); + private _disableListeners = new MutableDisposable(); constructor( private readonly _instance: ITerminalInstance, processManager: ITerminalProcessManager | ITerminalProcessInfo, widgetManager: TerminalWidgetManager, - @IContextKeyService private readonly _contextKeyService: IContextKeyService, - @IKeybindingService private readonly _keybindingService: IKeybindingService, - @IThemeService private readonly _themeService: IThemeService, + @IInstantiationService private readonly _instantiationService: IInstantiationService, ) { super(); + + this._refreshState(); } xtermReady(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { this._xterm = xterm; + this._refreshState(); + } - // Only show sticky scroll in the normal buffer - this.add(xterm.raw.buffer.onBufferChange(buffer => { - const element = this._ensureElement(); - setVisibility(buffer.type === 'normal', element); - })); + private _refreshState(): void { + if (this._overlay.value) { + this._tryDisable(); + } else { + this._tryEnable(); + } - // Refresh sticky scroll on write/scroll events - // TODO: Skip these when hidden - this.add(xterm.raw.onScroll(() => this._refresh())); - this.add(xterm.raw.onLineFeed(() => this._refresh())); - this.add(addStandardDisposableListener(xterm.raw.element!.querySelector('.xterm-viewport')!, 'scroll', () => this._refresh())); - - // Create the overlay - TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { - const overlay = new ctor({ - rows: 1, - cols: xterm.raw.cols, - allowProposedApi: true - }); - this._syncOptions(overlay, xterm.raw); - this._stickyScrollOverlay = overlay; - this._getSerializeAddonConstructor().then(addonCtor => { - this._serializeAddon = new addonCtor(); - xterm.raw.loadAddon(this._serializeAddon); - }); - // TODO: Sync every render - if (xterm.isGpuAccelerated) { - this._getCanvasAddonConstructor().then(addonCtor => { - this._canvasAddon = new addonCtor(); - overlay.loadAddon(this._canvasAddon); + if (this._overlay.value) { + this._enableListeners.clear(); + if (!this._disableListeners.value) { + this._disableListeners.value = this._instance.capabilities.onDidRemoveCapability(e => { + if (e.id === TerminalCapability.CommandDetection) { + this._refreshState(); + } }); } - }); - } - - @throttle(0) - private _refresh(): void { - if (!this._xterm?.raw?.element) { - return; - } - - // TODO: Cache - const commandDetection = this._instance.capabilities.get(TerminalCapability.CommandDetection); - if (!commandDetection) { - return; - } - - // The command from viewportY + 1 is used because this one will not be obscured by sticky - // scroll. - const command = commandDetection.getCommandForLine(this._xterm.raw.buffer.active.viewportY + 1); - const element = this._ensureElement(); - this._currentStickyMarker = undefined; - - // Sticky scroll only works with non-partial commands - if (!command || !('marker' in command)) { - hide(element); - return; - } - - // Hide if the marker doesn't exist or has been trimmed from the scrollback - const marker = command.marker; - if (!marker || marker.line === -1) { - hide(element); - return; - } - - // Hide sticky scroll if it's on the same line - if (marker.line === this._xterm.raw.buffer.active.viewportY) { - hide(element); - return; - } - - // TODO: Support multi-line prompts - // TODO: SUpport multi-line commands - - if (this._stickyScrollOverlay) { - this._stickyScrollOverlay.write('\x1b[H\x1b[K'); - // TODO: Serializing all content up to the required line is inefficient; support providing single line/range serialize addon - const s = this._serializeAddon?.serialize({ - scrollback: this._xterm.raw.buffer.active.baseY - marker.line - }); - const content = s ? s.substring(0, s.indexOf('\r')) : undefined; - if (content) { - this._stickyScrollOverlay.write(content); - // Debug log to show the command - // this._stickyScrollOverlay.write(` [${command?.command}]`); - - // TODO: Only sync options when needed - this._syncOptions(this._stickyScrollOverlay, this._xterm.raw); - } - - if (command.exitCode !== undefined) { - this._currentStickyMarker = marker; - show(element); - } else { - hide(element); - } } else { - hide(element); + this._disableListeners.clear(); + if (!this._enableListeners.value) { + this._enableListeners.value = this._instance.capabilities.onDidAddCapability(e => { + if (e.id === TerminalCapability.CommandDetection) { + this._refreshState(); + } + }); + } } } - private _ensureElement(): HTMLElement { - if (!this._element) { - this._element = document.createElement('div'); - this._element.classList.add('terminal-sticky-scroll'); - // // TODO: Safety - this._xterm!.raw.element!.parentElement!.append(this._element); - - const hoverOverlay = $('.hover-overlay'); - - // Scroll to the command on click - this.add(addStandardDisposableListener(hoverOverlay, 'click', e => { - if (this._xterm && this._currentStickyMarker) { - this._xterm.scrollToLine(this._currentStickyMarker.line, ScrollPosition.Middle); - this._xterm.markTracker.registerTemporaryDecoration(this._currentStickyMarker); - } - })); - - // Instead of juggling decorations for hover styles, use the selection to indicate the - // hover state as the selection is inaccessible anyway - this.add(addStandardDisposableListener(hoverOverlay, 'mouseover', () => this._stickyScrollOverlay?.selectAll())); - this.add(addStandardDisposableListener(hoverOverlay, 'mouseleave', () => this._stickyScrollOverlay?.clearSelection())); - - // TODO: Add to a container outside the xterm instance? - // TODO: Remove ! - this._stickyScrollOverlay!.open(this._element); - - append(this._element, hoverOverlay); + private _tryEnable(): void { + const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection); + if (capability && this._xterm) { + this._overlay.value = this._instantiationService.createInstance(TerminalStickyScrollOverlay, this._xterm, capability); } - - return this._element; } - private _syncOptions(target: RawXtermTerminal, copyFrom: RawXtermTerminal): void { - const o = copyFrom.options; - const theme = this._themeService.getColorTheme(); - // TODO: BG should be editor-aware - const terminalBackground = theme.getColor(terminalStickyScrollBackground) || theme.getColor(TERMINAL_BACKGROUND_COLOR) || theme.getColor(PANEL_BACKGROUND); - target.resize(copyFrom.cols, 1); - target.options = { - cursorInactiveStyle: 'none', - scrollback: 0, - logLevel: 'off', - - // Selection is used for hover state in the overlay - theme: { - ...this._xterm!.getXtermTheme(), - background: terminalBackground?.toString(), - selectionBackground: theme.getColor(terminalStickyScrollHoverBackground)?.toString(), - selectionInactiveBackground: undefined - }, - - documentOverride: o.documentOverride, - fontFamily: o.fontFamily, - fontWeight: o.fontWeight, - fontWeightBold: o.fontWeightBold, - fontSize: o.fontSize, - letterSpacing: o.letterSpacing, - lineHeight: o.lineHeight, - drawBoldTextInBrightColors: o.drawBoldTextInBrightColors, - minimumContrastRatio: o.minimumContrastRatio, - tabStopWidth: o.tabStopWidth, - overviewRulerWidth: o.overviewRulerWidth, - }; - } - - - // TODO: Share ctor - protected async _getCanvasAddonConstructor(): Promise { - if (!CanvasAddon) { - CanvasAddon = (await importAMDNodeModule('@xterm/addon-canvas', 'lib/xterm-addon-canvas.js')).CanvasAddon; + private _tryDisable(): void { + const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection); + if (!capability || !this._xterm) { + this._overlay.clear(); } - return CanvasAddon; - } - - // TODO: Share ctor - protected async _getSerializeAddonConstructor(): Promise { - if (!SerializeAddon) { - SerializeAddon = (await importAMDNodeModule('@xterm/addon-serialize', 'lib/addon-serialize.js')).SerializeAddon; - } - return SerializeAddon; } } registerTerminalContribution(TerminalStickyScrollContribution.ID, TerminalStickyScrollContribution, true); - -// HACK: These are derived from the editor background, not the terminal background because -const terminalStickyScrollBackground = registerColor('terminalStickyScroll.background', { - light: null, - dark: null, - hcDark: null, - hcLight: null -}, localize('terminalStickyScroll.background', 'The background color of the sticky scroll overlay in the terminal.')); - -// TODO: These default values are from the editorStickyScrollHover.background and may not be ideal -const terminalStickyScrollHoverBackground = registerColor('terminalStickyScrollHover.background', { - dark: '#2A2D2E', - light: '#F0F0F0', - hcDark: null, - hcLight: Color.fromHex('#0F4A85').transparent(0.1) -}, localize('terminalStickyScrollHover.background', 'The background color of the sticky scroll overlay in the terminal when hovered.')); diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry.ts new file mode 100644 index 00000000000..697f210cfae --- /dev/null +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Color } from 'vs/base/common/color'; +import 'vs/css!./media/stickyScroll'; +import { localize } from 'vs/nls'; +import { registerColor } from 'vs/platform/theme/common/colorRegistry'; + +// HACK: These are derived from the editor background, not the terminal background because +export const terminalStickyScrollBackground = registerColor('terminalStickyScroll.background', { + light: null, + dark: null, + hcDark: null, + hcLight: null +}, localize('terminalStickyScroll.background', 'The background color of the sticky scroll overlay in the terminal.')); + +// TODO: These default values are from the editorStickyScrollHover.background and may not be ideal +export const terminalStickyScrollHoverBackground = registerColor('terminalStickyScrollHover.background', { + dark: '#2A2D2E', + light: '#F0F0F0', + hcDark: null, + hcLight: Color.fromHex('#0F4A85').transparent(0.1) +}, localize('terminalStickyScrollHover.background', 'The background color of the sticky scroll overlay in the terminal when hovered.')); diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts new file mode 100644 index 00000000000..ce3caca41ad --- /dev/null +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -0,0 +1,223 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import type { CanvasAddon as CanvasAddonType } from '@xterm/addon-canvas'; +import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; +import type { IMarker, Terminal as RawXtermTerminal } from '@xterm/xterm'; +import { importAMDNodeModule } from 'vs/amdX'; +import { $, addStandardDisposableListener, append, hide, setVisibility, show } from 'vs/base/browser/dom'; +import { throttle } from 'vs/base/common/decorators'; +import { Disposable } from 'vs/base/common/lifecycle'; +import 'vs/css!./media/stickyScroll'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { ICommandDetectionCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; +import { IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; +import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; +import { TERMINAL_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; +import { terminalStickyScrollBackground, terminalStickyScrollHoverBackground } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry'; + +let CanvasAddon: typeof CanvasAddonType; +let SerializeAddon: typeof SerializeAddonType; + +export class TerminalStickyScrollOverlay extends Disposable { + private _element?: HTMLElement; + private _stickyScrollOverlay?: RawXtermTerminal; + + private _currentStickyMarker?: IMarker; + + private _serializeAddon?: SerializeAddonType; + private _canvasAddon?: CanvasAddonType; + + constructor( + private readonly _xterm: IXtermTerminal & { raw: RawXtermTerminal }, + private readonly _commandDetection: ICommandDetectionCapability, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IKeybindingService private readonly _keybindingService: IKeybindingService, + @IThemeService private readonly _themeService: IThemeService, + ) { + super(); + + // Only show sticky scroll in the normal buffer + this._register(this._xterm.raw.buffer.onBufferChange(buffer => { + const element = this._ensureElement(); + setVisibility(buffer.type === 'normal', element); + })); + + // Refresh sticky scroll on write/scroll events + // TODO: Skip these when hidden + this._register(this._xterm.raw.onScroll(() => this._refresh())); + this._register(this._xterm.raw.onLineFeed(() => this._refresh())); + this._register(addStandardDisposableListener(this._xterm.raw.element!.querySelector('.xterm-viewport')!, 'scroll', () => this._refresh())); + + // Create the overlay + TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { + const overlay = new ctor({ + rows: 1, + cols: this._xterm.raw.cols, + allowProposedApi: true + }); + this._syncOptions(overlay, this._xterm.raw); + this._stickyScrollOverlay = overlay; + this._getSerializeAddonConstructor().then(addonCtor => { + this._serializeAddon = new addonCtor(); + this._xterm.raw.loadAddon(this._serializeAddon); + }); + // TODO: Sync every render + if (this._xterm.isGpuAccelerated) { + this._getCanvasAddonConstructor().then(addonCtor => { + this._canvasAddon = new addonCtor(); + overlay.loadAddon(this._canvasAddon); + }); + } + }); + } + + @throttle(0) + private _refresh(): void { + if (!this._xterm?.raw?.element) { + return; + } + + // The command from viewportY + 1 is used because this one will not be obscured by sticky + // scroll. + const command = this._commandDetection.getCommandForLine(this._xterm.raw.buffer.active.viewportY + 1); + const element = this._ensureElement(); + this._currentStickyMarker = undefined; + + // Sticky scroll only works with non-partial commands + if (!command || !('marker' in command)) { + hide(element); + return; + } + + // Hide if the marker doesn't exist or has been trimmed from the scrollback + const marker = command.marker; + if (!marker || marker.line === -1) { + hide(element); + return; + } + + // Hide sticky scroll if it's on the same line + if (marker.line === this._xterm.raw.buffer.active.viewportY) { + hide(element); + return; + } + + // TODO: Support multi-line prompts + // TODO: SUpport multi-line commands + + if (this._stickyScrollOverlay) { + this._stickyScrollOverlay.write('\x1b[H\x1b[K'); + // TODO: Serializing all content up to the required line is inefficient; support providing single line/range serialize addon + const s = this._serializeAddon?.serialize({ + scrollback: this._xterm.raw.buffer.active.baseY - marker.line + }); + const content = s ? s.substring(0, s.indexOf('\r')) : undefined; + if (content) { + this._stickyScrollOverlay.write(content); + // Debug log to show the command + // this._stickyScrollOverlay.write(` [${command?.command}]`); + + // TODO: Only sync options when needed + this._syncOptions(this._stickyScrollOverlay, this._xterm.raw); + } + + if (command.exitCode !== undefined) { + this._currentStickyMarker = marker; + show(element); + } else { + hide(element); + } + } else { + hide(element); + } + } + + private _ensureElement(): HTMLElement { + if (!this._element) { + this._element = document.createElement('div'); + this._element.classList.add('terminal-sticky-scroll'); + // // TODO: Safety + this._xterm!.raw.element!.parentElement!.append(this._element); + + const hoverOverlay = $('.hover-overlay'); + + // Scroll to the command on click + this._register(addStandardDisposableListener(hoverOverlay, 'click', e => { + if (this._xterm && this._currentStickyMarker) { + this._xterm.scrollToLine(this._currentStickyMarker.line, ScrollPosition.Middle); + this._xterm.markTracker.registerTemporaryDecoration(this._currentStickyMarker); + } + })); + + // Instead of juggling decorations for hover styles, use the selection to indicate the + // hover state as the selection is inaccessible anyway + this._register(addStandardDisposableListener(hoverOverlay, 'mouseover', () => this._stickyScrollOverlay?.selectAll())); + this._register(addStandardDisposableListener(hoverOverlay, 'mouseleave', () => this._stickyScrollOverlay?.clearSelection())); + + // TODO: Add to a container outside the xterm instance? + // TODO: Remove ! + this._stickyScrollOverlay!.open(this._element); + + append(this._element, hoverOverlay); + } + + return this._element; + } + + private _syncOptions(target: RawXtermTerminal, copyFrom: RawXtermTerminal): void { + const o = copyFrom.options; + const theme = this._themeService.getColorTheme(); + // TODO: BG should be editor-aware + const terminalBackground = theme.getColor(terminalStickyScrollBackground) || theme.getColor(TERMINAL_BACKGROUND_COLOR) || theme.getColor(PANEL_BACKGROUND); + target.resize(copyFrom.cols, 1); + target.options = { + cursorInactiveStyle: 'none', + scrollback: 0, + logLevel: 'off', + + // Selection is used for hover state in the overlay + theme: { + ...this._xterm!.getXtermTheme(), + background: terminalBackground?.toString(), + selectionBackground: theme.getColor(terminalStickyScrollHoverBackground)?.toString(), + selectionInactiveBackground: undefined + }, + + documentOverride: o.documentOverride, + fontFamily: o.fontFamily, + fontWeight: o.fontWeight, + fontWeightBold: o.fontWeightBold, + fontSize: o.fontSize, + letterSpacing: o.letterSpacing, + lineHeight: o.lineHeight, + drawBoldTextInBrightColors: o.drawBoldTextInBrightColors, + minimumContrastRatio: o.minimumContrastRatio, + tabStopWidth: o.tabStopWidth, + overviewRulerWidth: o.overviewRulerWidth, + }; + } + + + // TODO: Share ctor + protected async _getCanvasAddonConstructor(): Promise { + if (!CanvasAddon) { + CanvasAddon = (await importAMDNodeModule('@xterm/addon-canvas', 'lib/xterm-addon-canvas.js')).CanvasAddon; + } + return CanvasAddon; + } + + // TODO: Share ctor + protected async _getSerializeAddonConstructor(): Promise { + if (!SerializeAddon) { + SerializeAddon = (await importAMDNodeModule('@xterm/addon-serialize', 'lib/addon-serialize.js')).SerializeAddon; + } + return SerializeAddon; + } +} From 084ddc29caa692ebd06659a04af8f42820ef7364 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 7 Nov 2023 10:05:27 -0800 Subject: [PATCH 074/240] fire command executed once commandExecutedMarker has been assigned and the marker does not exist before command finished --- .../common/capabilities/commandDetectionCapability.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index 3cac93659ff..8246e83686a 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -621,8 +621,6 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe if (this._currentCommand.commandStartMarker) { this._commandMarkers.push(this._currentCommand.commandStartMarker); } - // Fire this now to prevent issues like #197409 - this._onCommandExecuted.fire(); } this._evaluateCommandMarkersWindows(); } @@ -642,6 +640,8 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe } } this._currentCommand.commandExecutedMarker = this._commandMarkers[this._commandMarkers.length - 1]; + // Fire this now to prevent issues like #197409 + this._onCommandExecuted.fire(); } setCommandLine(commandLine: string, isTrusted: boolean) { From ad3d46b6660cb3ab52291011780ec5aef0c2eaf7 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 7 Nov 2023 10:26:25 -0800 Subject: [PATCH 075/240] allow keybindings to be used by all --- .../chat/browser/actions/chatCodeblockActions.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts index c9f578dc2ec..77fe99c4a62 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts @@ -18,7 +18,6 @@ import { ITextModel } from 'vs/editor/common/model'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { CopyAction } from 'vs/editor/contrib/clipboard/browser/clipboard'; import { localize } from 'vs/nls'; -import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; @@ -196,7 +195,7 @@ export function registerChatCodeBlockActions() { when: CONTEXT_IN_CHAT_SESSION, }, keybinding: { - when: ContextKeyExpr.and(CONTEXT_IN_CHAT_SESSION, CONTEXT_ACCESSIBILITY_MODE_ENABLED), + when: CONTEXT_IN_CHAT_SESSION, primary: KeyMod.CtrlCmd | KeyCode.Enter, mac: { primary: KeyMod.WinCtrl | KeyCode.Enter }, weight: KeybindingWeight.WorkbenchContrib @@ -437,17 +436,8 @@ export function registerChatCodeBlockActions() { }], keybinding: [{ primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter, - mac: { - primary: KeyMod.WinCtrl | KeyCode.Enter, - }, weight: KeybindingWeight.EditorContrib, - when: ContextKeyExpr.and(CONTEXT_IN_CHAT_SESSION, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), - }, - { - primary: KeyMod.CtrlCmd | KeyCode.Slash, - mac: { primary: KeyMod.WinCtrl | KeyCode.Slash }, - weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(CONTEXT_IN_CHAT_SESSION, CONTEXT_ACCESSIBILITY_MODE_ENABLED), + when: CONTEXT_IN_CHAT_SESSION, }] }); } From e0d4c684e08af3b51491a78ce8699a3ffa6a7b8e Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 7 Nov 2023 10:31:59 -0800 Subject: [PATCH 076/240] use winCtrl --- .../contrib/chat/browser/actions/chatCodeblockActions.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts index 77fe99c4a62..f7cc45da136 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts @@ -436,6 +436,9 @@ export function registerChatCodeBlockActions() { }], keybinding: [{ primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter, + mac: { + primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.Enter + }, weight: KeybindingWeight.EditorContrib, when: CONTEXT_IN_CHAT_SESSION, }] From 273862296b9b511453b3a9148ecf287e9ce96053 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 7 Nov 2023 19:34:42 +0100 Subject: [PATCH 077/240] workaround layer breaker where dom-API is dependent on from common (#197662) workaround https://github.com/microsoft/vscode/issues/197661 --- src/vs/base/common/async.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index c0b656542da..a98470997ac 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -1274,7 +1274,7 @@ declare function cancelIdleCallback(handle: number): void; }; }; } else { - runWhenIdle = (targetWindow, runner, timeout?) => { + runWhenIdle = (targetWindow: any, runner, timeout?) => { const handle: number = targetWindow.requestIdleCallback(runner, typeof timeout === 'number' ? { timeout } : undefined); let disposed = false; return { From 2749de38081ed05ee185d897bcb17892893888ea Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 7 Nov 2023 10:37:37 -0800 Subject: [PATCH 078/240] testing: implement proposed active profiles api (#197664) testing: implement proposed active profiles api For https://github.com/microsoft/vscode/issues/193160 --- extensions/vscode-api-tests/package.json | 1 + src/vs/base/common/event.ts | 2 +- .../api/browser/mainThreadTesting.ts | 18 +++- .../workbench/api/common/extHost.protocol.ts | 2 + src/vs/workbench/api/common/extHostTesting.ts | 66 ++++++++++++- .../api/test/browser/extHostTesting.test.ts | 94 ++++++++++++++++++- .../api/test/common/testRPCProtocol.ts | 12 +++ .../common/extensionsApiProposals.ts | 1 + .../vscode.proposed.testingActiveProfile.d.ts | 21 +++++ 9 files changed, 205 insertions(+), 12 deletions(-) create mode 100644 src/vscode-dts/vscode.proposed.testingActiveProfile.d.ts diff --git a/extensions/vscode-api-tests/package.json b/extensions/vscode-api-tests/package.json index beb65ffb2e6..401b9a4da03 100644 --- a/extensions/vscode-api-tests/package.json +++ b/extensions/vscode-api-tests/package.json @@ -52,6 +52,7 @@ "treeViewReveal", "workspaceTrust", "telemetry", + "testingActiveProfile", "windowActivity", "interactiveUserActions" ], diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 9f76502f48a..07f7846157a 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -540,8 +540,8 @@ export namespace Event { export interface IChainableSythensis { map(fn: (i: T) => O): IChainableSythensis; forEach(fn: (i: T) => void): IChainableSythensis; + filter(fn: (e: T) => e is R): IChainableSythensis; filter(fn: (e: T) => boolean): IChainableSythensis; - filter(fn: (e: T | R) => e is R): IChainableSythensis; reduce(merge: (last: R, event: T) => R, initial: R): IChainableSythensis; reduce(merge: (last: R | undefined, event: T) => R): IChainableSythensis; latch(equals?: (a: T, b: T) => boolean): IChainableSythensis; diff --git a/src/vs/workbench/api/browser/mainThreadTesting.ts b/src/vs/workbench/api/browser/mainThreadTesting.ts index d4858ccb417..356310400ee 100644 --- a/src/vs/workbench/api/browser/mainThreadTesting.ts +++ b/src/vs/workbench/api/browser/mainThreadTesting.ts @@ -5,12 +5,13 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { CancellationToken } from 'vs/base/common/cancellation'; +import { Event } from 'vs/base/common/event'; import { Disposable, DisposableStore, IDisposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { revive } from 'vs/base/common/marshalling'; import { URI } from 'vs/base/common/uri'; import { Range } from 'vs/editor/common/core/range'; import { MutableObservableValue } from 'vs/workbench/contrib/testing/common/observableValue'; -import { ExtensionRunTestsRequest, IFileCoverage, ITestItem, ITestMessage, ITestRunProfile, ITestRunTask, ResolvedTestRunRequest, TestResultState, TestsDiffOp } from 'vs/workbench/contrib/testing/common/testTypes'; +import { ExtensionRunTestsRequest, IFileCoverage, ITestItem, ITestMessage, ITestRunProfile, ITestRunTask, ResolvedTestRunRequest, TestResultState, TestRunProfileBitset, TestsDiffOp } from 'vs/workbench/contrib/testing/common/testTypes'; import { TestCoverage } from 'vs/workbench/contrib/testing/common/testCoverage'; import { ITestProfileService } from 'vs/workbench/contrib/testing/common/testProfileService'; import { LiveTestResult } from 'vs/workbench/contrib/testing/common/testResult'; @@ -45,6 +46,21 @@ export class MainThreadTesting extends Disposable implements MainThreadTestingSh this.proxy.$cancelExtensionTestRun(runId); })); + this._register(Event.debounce(testProfiles.onDidChange, (_last, e) => e)(() => { + const defaults = new Set([ + ...testProfiles.getGroupDefaultProfiles(TestRunProfileBitset.Run), + ...testProfiles.getGroupDefaultProfiles(TestRunProfileBitset.Debug), + ...testProfiles.getGroupDefaultProfiles(TestRunProfileBitset.Coverage), + ]); + + const obj: Record = {}; + for (const { controller, profiles } of this.testProfiles.all()) { + obj[controller.id] = profiles.filter(p => defaults.has(p)).map(p => p.profileId); + } + + this.proxy.$setActiveRunProfiles(obj); + })); + this._register(resultService.onResultsChanged(evt => { const results = 'completed' in evt ? evt.completed : ('inserted' in evt ? evt.inserted : undefined); const serialized = results?.toJSONWithMessages(); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 18035b6cb54..4da9a5a9267 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -2638,6 +2638,8 @@ export interface ExtHostTestingShape { $refreshTests(controllerId: string, token: CancellationToken): Promise; /** Ensures any pending test diffs are flushed */ $syncTests(): Promise; + /** Sets the active test run profiles */ + $setActiveRunProfiles(profiles: Record): void; } export interface ExtHostLocalizationShape { diff --git a/src/vs/workbench/api/common/extHostTesting.ts b/src/vs/workbench/api/common/extHostTesting.ts index 65dd87b6e3f..7756fffa851 100644 --- a/src/vs/workbench/api/common/extHostTesting.ts +++ b/src/vs/workbench/api/common/extHostTesting.ts @@ -29,6 +29,7 @@ import { TestCommandId } from 'vs/workbench/contrib/testing/common/constants'; import { TestId, TestIdPathParts, TestPosition } from 'vs/workbench/contrib/testing/common/testId'; import { InvalidTestItemError } from 'vs/workbench/contrib/testing/common/testItemCollection'; import { AbstractIncrementalTestCollection, CoverageDetails, ICallProfileRunHandler, IFileCoverage, ISerializedTestResults, IStartControllerTests, IStartControllerTestsResult, ITestErrorMessage, ITestItem, ITestItemContext, ITestMessageMenuArgs, IncrementalChangeCollector, IncrementalTestCollectionItem, InternalTestItem, TestResultState, TestRunProfileBitset, TestsDiff, TestsDiffOp, isStartControllerTests } from 'vs/workbench/contrib/testing/common/testTypes'; +import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; import type * as vscode from 'vscode'; interface ControllerInfo { @@ -36,14 +37,18 @@ interface ControllerInfo { profiles: Map; collection: ExtHostTestItemCollection; extension: Readonly; + activeProfiles: Set; } -export class ExtHostTesting implements ExtHostTestingShape { - private readonly resultsChangedEmitter = new Emitter(); - private readonly controllers = new Map(); +type ActiveProfileChangeEvent = Map>; + +export class ExtHostTesting extends Disposable implements ExtHostTestingShape { + private readonly resultsChangedEmitter = this._register(new Emitter()); + protected readonly controllers = new Map(); private readonly proxy: MainThreadTestingShape; private readonly runTracker: TestRunCoordinator; private readonly observer: TestObservers; + private readonly activeProfilesChangedEmitter = this._register(new Emitter()); public onResultsChanged = this.resultsChangedEmitter.event; public results: ReadonlyArray = []; @@ -53,6 +58,7 @@ export class ExtHostTesting implements ExtHostTestingShape { commands: ExtHostCommands, private readonly editors: ExtHostDocumentsAndEditors, ) { + super(); this.proxy = rpc.getProxy(MainContext.MainThreadTesting); this.observer = new TestObservers(this.proxy); this.runTracker = new TestRunCoordinator(this.proxy); @@ -110,6 +116,7 @@ export class ExtHostTesting implements ExtHostTestingShape { collection.root.label = label; const profiles = new Map(); + const activeProfiles = new Set(); const proxy = this.proxy; const controller: vscode.TestController = { @@ -140,7 +147,7 @@ export class ExtHostTesting implements ExtHostTestingShape { profileId++; } - return new TestRunProfileImpl(this.proxy, profiles, controllerId, profileId, label, group, runHandler, isDefault, tag, supportsContinuousRun); + return new TestRunProfileImpl(this.proxy, profiles, extension, activeProfiles, this.activeProfilesChangedEmitter.event, controllerId, profileId, label, group, runHandler, isDefault, tag, supportsContinuousRun); }, createTestItem(id, label, uri) { return new TestItemImpl(controllerId, id, label, uri); @@ -170,7 +177,7 @@ export class ExtHostTesting implements ExtHostTestingShape { proxy.$registerTestController(controllerId, label, !!refreshHandler); disposable.add(toDisposable(() => proxy.$unregisterTestController(controllerId))); - const info: ControllerInfo = { controller, collection, profiles: profiles, extension }; + const info: ControllerInfo = { controller, collection, profiles, extension, activeProfiles }; this.controllers.set(controllerId, info); disposable.add(toDisposable(() => this.controllers.delete(controllerId))); @@ -245,6 +252,33 @@ export class ExtHostTesting implements ExtHostTestingShape { this.controllers.get(controllerId)?.profiles.get(profileId)?.configureHandler?.(); } + /** @inheritdoc */ + $setActiveRunProfiles(profiles: Record): void { + const evt: ActiveProfileChangeEvent = new Map(); + for (const [controllerId, profileIds] of Object.entries(profiles)) { + const ctrl = this.controllers.get(controllerId); + if (!ctrl) { + continue; + } + const changes = new Map(); + const added = profileIds.filter(id => !ctrl.activeProfiles.has(id)); + const removed = [...ctrl.activeProfiles].filter(id => !profileIds.includes(id)); + for (const id of added) { + changes.set(id, true); + ctrl.activeProfiles.add(id); + } + for (const id of removed) { + changes.set(id, false); + ctrl.activeProfiles.delete(id); + } + if (changes.size) { + evt.set(controllerId, changes); + } + } + + this.activeProfilesChangedEmitter.fire(evt); + } + /** @inheritdoc */ async $refreshTests(controllerId: string, token: CancellationToken) { await this.controllers.get(controllerId)?.controller.refreshHandler?.(token); @@ -1005,6 +1039,9 @@ class TestObservers { export class TestRunProfileImpl implements vscode.TestRunProfile { readonly #proxy: MainThreadTestingShape; + readonly #extension: IRelaxedExtensionDescription; + readonly #activeProfiles: ReadonlySet; + readonly #onDidChangeActiveProfiles: Event; #profiles?: Map; private _configureHandler?: (() => void); @@ -1065,9 +1102,25 @@ export class TestRunProfileImpl implements vscode.TestRunProfile { } } + public get isSelected() { + checkProposedApiEnabled(this.#extension, 'testingActiveProfile'); + return this.#activeProfiles.has(this.profileId); + } + + public get onDidChangeSelected() { + checkProposedApiEnabled(this.#extension, 'testingActiveProfile'); + return Event.chain(this.#onDidChangeActiveProfiles, $ => $ + .map(ev => ev.get(this.controllerId)?.get(this.profileId)) + .filter(isDefined) + ); + } + constructor( proxy: MainThreadTestingShape, profiles: Map, + extension: IRelaxedExtensionDescription, + activeProfiles: ReadonlySet, + onDidChangeActiveProfiles: Event, public readonly controllerId: string, public readonly profileId: number, private _label: string, @@ -1079,6 +1132,9 @@ export class TestRunProfileImpl implements vscode.TestRunProfile { ) { this.#proxy = proxy; this.#profiles = profiles; + this.#extension = extension; + this.#activeProfiles = activeProfiles; + this.#onDidChangeActiveProfiles = onDidChangeActiveProfiles; profiles.set(profileId, this); const groupBitset = profileGroupToBitset[kind]; diff --git a/src/vs/workbench/api/test/browser/extHostTesting.test.ts b/src/vs/workbench/api/test/browser/extHostTesting.test.ts index 0a7b6004539..11dfe6d72a1 100644 --- a/src/vs/workbench/api/test/browser/extHostTesting.test.ts +++ b/src/vs/workbench/api/test/browser/extHostTesting.test.ts @@ -7,21 +7,27 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import { VSBuffer } from 'vs/base/common/buffer'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { Event } from 'vs/base/common/event'; import { Iterable } from 'vs/base/common/iterator'; import { URI } from 'vs/base/common/uri'; -import { mockObject, MockObject } from 'vs/base/test/common/mock'; +import { mock, mockObject, MockObject } from 'vs/base/test/common/mock'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import * as editorRange from 'vs/editor/common/core/range'; -import { IRelaxedExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { ExtensionIdentifier, IRelaxedExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { NullLogService } from 'vs/platform/log/common/log'; import { MainThreadTestingShape } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { TestRunCoordinator, TestRunDto, TestRunProfileImpl } from 'vs/workbench/api/common/extHostTesting'; +import { IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry'; +import { ExtHostTesting, TestRunCoordinator, TestRunDto, TestRunProfileImpl } from 'vs/workbench/api/common/extHostTesting'; import { ExtHostTestItemCollection, TestItemImpl } from 'vs/workbench/api/common/extHostTestItem'; import * as convert from 'vs/workbench/api/common/extHostTypeConverters'; import { Location, Position, Range, TestMessage, TestResultState, TestRunProfileKind, TestRunRequest as TestRunRequestImpl, TestTag } from 'vs/workbench/api/common/extHostTypes'; +import { AnyCallRPCProtocol } from 'vs/workbench/api/test/common/testRPCProtocol'; import { TestId } from 'vs/workbench/contrib/testing/common/testId'; import { TestDiffOpType, TestItemExpandState, TestMessageType, TestsDiff } from 'vs/workbench/contrib/testing/common/testTypes'; -import type { TestItem, TestRunRequest } from 'vscode'; +import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; +import type { TestController, TestItem, TestRunProfile, TestRunRequest } from 'vscode'; const simplify = (item: TestItem) => ({ id: item.id, @@ -604,7 +610,7 @@ suite('ExtHost Testing', () => { cts = new CancellationTokenSource(); c = new TestRunCoordinator(proxy); - configuration = new TestRunProfileImpl(mockObject()(), new Map(), 'ctrlId', 42, 'Do Run', TestRunProfileKind.Run, () => { }, false); + configuration = new TestRunProfileImpl(mockObject()(), new Map(), nullExtensionDescription, new Set(), Event.None, 'ctrlId', 42, 'Do Run', TestRunProfileKind.Run, () => { }, false); await single.expand(single.root.id, Infinity); single.collectDiff(); @@ -867,4 +873,82 @@ suite('ExtHost Testing', () => { task1.end(); }); }); + + suite('service', () => { + let ctrl: TestExtHostTesting; + + class TestExtHostTesting extends ExtHostTesting { + public getProfileInternalId(ctrl: TestController, profile: TestRunProfile) { + for (const [id, p] of this.controllers.get(ctrl.id)!.profiles) { + if (profile === p) { + return id; + } + } + + throw new Error('profile not found'); + } + } + + setup(() => { + const rpcProtocol = AnyCallRPCProtocol(); + ctrl = ds.add(new TestExtHostTesting( + rpcProtocol, + new ExtHostCommands(rpcProtocol, new NullLogService(), new class extends mock() { + override onExtensionError(): boolean { + return true; + } + }), + new ExtHostDocumentsAndEditors(rpcProtocol, new NullLogService()), + )); + }); + + test('exposes active profiles correctly', async () => { + const extA = { ...nullExtensionDescription, identifier: new ExtensionIdentifier('ext.a'), enabledApiProposals: ['testingActiveProfile'] }; + const extB = { ...nullExtensionDescription, identifier: new ExtensionIdentifier('ext.b'), enabledApiProposals: ['testingActiveProfile'] }; + + const ctrlA = ds.add(ctrl.createTestController(extA, 'a', 'ctrla')); + const profAA = ds.add(ctrlA.createRunProfile('aa', TestRunProfileKind.Run, () => { })); + const profAB = ds.add(ctrlA.createRunProfile('ab', TestRunProfileKind.Run, () => { })); + + const ctrlB = ds.add(ctrl.createTestController(extB, 'b', 'ctrlb')); + const profBA = ds.add(ctrlB.createRunProfile('ba', TestRunProfileKind.Run, () => { })); + const profBB = ds.add(ctrlB.createRunProfile('bb', TestRunProfileKind.Run, () => { })); + const neverCalled = sinon.stub(); + + // empty default state: + assert.deepStrictEqual(profAA.isSelected, false); + assert.deepStrictEqual(profBA.isSelected, false); + assert.deepStrictEqual(profBB.isSelected, false); + + // fires a change event: + const changeA = Event.toPromise(profAA.onDidChangeSelected as Event); + const changeBA = Event.toPromise(profBA.onDidChangeSelected as Event); + const changeBB = Event.toPromise(profBB.onDidChangeSelected as Event); + + ds.add(profAB.onDidChangeSelected(neverCalled)); + assert.strictEqual(neverCalled.called, false); + + ctrl.$setActiveRunProfiles({ + a: [ctrl.getProfileInternalId(ctrlA, profAA)], + b: [ctrl.getProfileInternalId(ctrlB, profBA), ctrl.getProfileInternalId(ctrlB, profBB)] + }); + + assert.deepStrictEqual(await changeA, true); + assert.deepStrictEqual(await changeBA, true); + assert.deepStrictEqual(await changeBB, true); + + // updates internal state: + assert.deepStrictEqual(profAA.isSelected, true); + assert.deepStrictEqual(profBA.isSelected, true); + assert.deepStrictEqual(profBB.isSelected, true); + assert.deepStrictEqual(profAB.isSelected, false); + + // no-ops if equal + ds.add(profAA.onDidChangeSelected(neverCalled)); + ctrl.$setActiveRunProfiles({ + a: [ctrl.getProfileInternalId(ctrlA, profAA)], + }); + assert.strictEqual(neverCalled.called, false); + }); + }); }); diff --git a/src/vs/workbench/api/test/common/testRPCProtocol.ts b/src/vs/workbench/api/test/common/testRPCProtocol.ts index 7907665f711..abf854afa06 100644 --- a/src/vs/workbench/api/test/common/testRPCProtocol.ts +++ b/src/vs/workbench/api/test/common/testRPCProtocol.ts @@ -28,6 +28,18 @@ export function SingleProxyRPCProtocol(thing: any): IExtHostContext & IExtHostRp }; } +/** Makes a fake {@link SingleProxyRPCProtocol} on which any method can be called */ +export function AnyCallRPCProtocol(useCalls?: { [K in keyof T]: T[K] }) { + return SingleProxyRPCProtocol(new Proxy({}, { + get(_target, prop: string) { + if (useCalls && prop in useCalls) { + return (useCalls as any)[prop]; + } + return () => Promise.resolve(undefined); + } + })); +} + export class TestRPCProtocol implements IExtHostContext, IExtHostRpcService { public _serviceBrand: undefined; diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index 683efb3184f..577da2ca078 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -97,6 +97,7 @@ export const allApiProposals = Object.freeze({ terminalSelection: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalSelection.d.ts', testCoverage: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testCoverage.d.ts', testObserver: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testObserver.d.ts', + testingActiveProfile: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testingActiveProfile.d.ts', textSearchProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.textSearchProvider.d.ts', timeline: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.timeline.d.ts', tokenInformation: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.tokenInformation.d.ts', diff --git a/src/vscode-dts/vscode.proposed.testingActiveProfile.d.ts b/src/vscode-dts/vscode.proposed.testingActiveProfile.d.ts new file mode 100644 index 00000000000..8bce86f3347 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.testingActiveProfile.d.ts @@ -0,0 +1,21 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// https://github.com/microsoft/vscode/issues/193160 @connor4312 + +declare module 'vscode' { + export interface TestRunProfile { + /** + * Whether this profile is currently selected as a default by the user + */ + readonly isSelected: boolean; + + /** + * Fired when a user has changed whether this is a selected profile. The + * event contains the new value of {@link isSelected} + */ + onDidChangeSelected: Event; + } +} From de600a12dfc1d639f1c430d53094aab8fb63b0c2 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 11:43:43 -0800 Subject: [PATCH 079/240] Refactors for maintainability --- .../terminal.stickyScroll.contribution.ts | 10 +- .../browser/terminalStickyScrollOverlay.ts | 103 ++++++++++++------ 2 files changed, 73 insertions(+), 40 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index 1e758513772..2c9602645cb 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; -import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/stickyScroll'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; @@ -14,7 +14,7 @@ import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/wid import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalStickyScrollOverlay } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay'; -class TerminalStickyScrollContribution extends DisposableStore implements ITerminalContribution { +class TerminalStickyScrollContribution extends Disposable implements ITerminalContribution { static readonly ID = 'terminal.stickyScroll'; static get(instance: ITerminalInstance): TerminalStickyScrollContribution | null { @@ -23,10 +23,10 @@ class TerminalStickyScrollContribution extends DisposableStore implements ITermi private _xterm?: IXtermTerminal & { raw: RawXtermTerminal }; - private _overlay = new MutableDisposable(); + private _overlay = this._register(new MutableDisposable()); - private _enableListeners = new MutableDisposable(); - private _disableListeners = new MutableDisposable(); + private _enableListeners = this._register(new MutableDisposable()); + private _disableListeners = this._register(new MutableDisposable()); constructor( private readonly _instance: ITerminalInstance, diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index ce3caca41ad..094b3ae851c 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -8,8 +8,9 @@ import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serializ import type { IMarker, Terminal as RawXtermTerminal } from '@xterm/xterm'; import { importAMDNodeModule } from 'vs/amdX'; import { $, addStandardDisposableListener, append, hide, setVisibility, show } from 'vs/base/browser/dom'; -import { throttle } from 'vs/base/common/decorators'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { memoize, throttle } from 'vs/base/common/decorators'; +import { Event } from 'vs/base/common/event'; +import { Disposable, MutableDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/stickyScroll'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -22,18 +23,24 @@ import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/mark import { TERMINAL_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { terminalStickyScrollBackground, terminalStickyScrollHoverBackground } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry'; -let CanvasAddon: typeof CanvasAddonType; -let SerializeAddon: typeof SerializeAddonType; +const enum OverlayState { + /** Initial state/disabled by the alt buffer. */ + Off = 0, + On = 1 +} export class TerminalStickyScrollOverlay extends Disposable { - private _element?: HTMLElement; private _stickyScrollOverlay?: RawXtermTerminal; - - private _currentStickyMarker?: IMarker; - private _serializeAddon?: SerializeAddonType; private _canvasAddon?: CanvasAddonType; + private _element?: HTMLElement; + private _currentStickyMarker?: IMarker; + + private _refreshListeners = this._register(new MutableDisposable()); + + private _state: OverlayState = OverlayState.Off; + constructor( private readonly _xterm: IXtermTerminal & { raw: RawXtermTerminal }, private readonly _commandDetection: ICommandDetectionCapability, @@ -44,18 +51,11 @@ export class TerminalStickyScrollOverlay extends Disposable { super(); // Only show sticky scroll in the normal buffer - this._register(this._xterm.raw.buffer.onBufferChange(buffer => { - const element = this._ensureElement(); - setVisibility(buffer.type === 'normal', element); + this._register(Event.runAndSubscribe(this._xterm.raw.buffer.onBufferChange, buffer => { + this._setState((buffer ?? this._xterm.raw.buffer.active).type === 'normal' ? OverlayState.On : OverlayState.Off); })); - // Refresh sticky scroll on write/scroll events - // TODO: Skip these when hidden - this._register(this._xterm.raw.onScroll(() => this._refresh())); - this._register(this._xterm.raw.onLineFeed(() => this._refresh())); - this._register(addStandardDisposableListener(this._xterm.raw.element!.querySelector('.xterm-viewport')!, 'scroll', () => this._refresh())); - - // Create the overlay + // Eagerly create the overlay TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { const overlay = new ctor({ rows: 1, @@ -64,20 +64,57 @@ export class TerminalStickyScrollOverlay extends Disposable { }); this._syncOptions(overlay, this._xterm.raw); this._stickyScrollOverlay = overlay; - this._getSerializeAddonConstructor().then(addonCtor => { - this._serializeAddon = new addonCtor(); + + this._getSerializeAddonConstructor().then(SerializeAddon => { + this._serializeAddon = new SerializeAddon(); this._xterm.raw.loadAddon(this._serializeAddon); }); + // TODO: Sync every render if (this._xterm.isGpuAccelerated) { - this._getCanvasAddonConstructor().then(addonCtor => { - this._canvasAddon = new addonCtor(); + this._getCanvasAddonConstructor().then(CanvasAddon => { + this._canvasAddon = new CanvasAddon(); overlay.loadAddon(this._canvasAddon); }); } }); } + private _setState(state: OverlayState) { + if (this._state === state) { + return; + } + switch (state) { + case OverlayState.Off: { + if (this._element) { + setVisibility(false, this._element); + } + this._uninstallRefreshListeners(); + break; + } + case OverlayState.On: { + const element = this._ensureElement(); + setVisibility(true, element); + this._installRefreshListeners(); + break; + } + } + } + + private _installRefreshListeners() { + if (!this._refreshListeners.value) { + this._refreshListeners.value = combinedDisposable( + this._xterm.raw.onScroll(() => this._refresh()), + this._xterm.raw.onLineFeed(() => this._refresh()), + addStandardDisposableListener(this._xterm.raw.element!.querySelector('.xterm-viewport')!, 'scroll', () => this._refresh()), + ); + } + } + + private _uninstallRefreshListeners() { + this._refreshListeners.clear(); + } + @throttle(0) private _refresh(): void { if (!this._xterm?.raw?.element) { @@ -142,6 +179,7 @@ export class TerminalStickyScrollOverlay extends Disposable { private _ensureElement(): HTMLElement { if (!this._element) { this._element = document.createElement('div'); + // TODO: Use display in a class over hide/show/setVisibility this._element.classList.add('terminal-sticky-scroll'); // // TODO: Safety this._xterm!.raw.element!.parentElement!.append(this._element); @@ -204,20 +242,15 @@ export class TerminalStickyScrollOverlay extends Disposable { }; } - - // TODO: Share ctor - protected async _getCanvasAddonConstructor(): Promise { - if (!CanvasAddon) { - CanvasAddon = (await importAMDNodeModule('@xterm/addon-canvas', 'lib/xterm-addon-canvas.js')).CanvasAddon; - } - return CanvasAddon; + @memoize + private async _getCanvasAddonConstructor(): Promise { + const m = await importAMDNodeModule('@xterm/addon-canvas', 'lib/xterm-addon-canvas.js'); + return m.CanvasAddon; } - // TODO: Share ctor - protected async _getSerializeAddonConstructor(): Promise { - if (!SerializeAddon) { - SerializeAddon = (await importAMDNodeModule('@xterm/addon-serialize', 'lib/addon-serialize.js')).SerializeAddon; - } - return SerializeAddon; + @memoize + private async _getSerializeAddonConstructor(): Promise { + const m = await importAMDNodeModule('@xterm/addon-serialize', 'lib/addon-serialize.js'); + return m.SerializeAddon; } } From e8d840d3bd286c4f94705a5c81cd44380e7238df Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 11:49:01 -0800 Subject: [PATCH 080/240] Improve setting of visibility --- .../browser/media/stickyScroll.css | 5 +++ .../browser/terminalStickyScrollOverlay.ts | 33 +++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css index cd2c7a079a6..5aeb7d6d374 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ .terminal-sticky-scroll { + display: none; position: absolute; left: 0; right: 0; @@ -13,6 +14,10 @@ box-shadow: var(--vscode-scrollbar-shadow) 0 3px 2px -2px; } +.terminal-sticky-scroll.visible { + display:block; +} + .terminal-sticky-scroll:hover { cursor: pointer !important; } diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index 094b3ae851c..19749bf3038 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -7,7 +7,7 @@ import type { CanvasAddon as CanvasAddonType } from '@xterm/addon-canvas'; import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; import type { IMarker, Terminal as RawXtermTerminal } from '@xterm/xterm'; import { importAMDNodeModule } from 'vs/amdX'; -import { $, addStandardDisposableListener, append, hide, setVisibility, show } from 'vs/base/browser/dom'; +import { $, addStandardDisposableListener, append } from 'vs/base/browser/dom'; import { memoize, throttle } from 'vs/base/common/decorators'; import { Event } from 'vs/base/common/event'; import { Disposable, MutableDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; @@ -29,6 +29,10 @@ const enum OverlayState { On = 1 } +const enum CssClasses { + Visible = 'visible' +} + export class TerminalStickyScrollOverlay extends Disposable { private _stickyScrollOverlay?: RawXtermTerminal; private _serializeAddon?: SerializeAddonType; @@ -86,15 +90,12 @@ export class TerminalStickyScrollOverlay extends Disposable { } switch (state) { case OverlayState.Off: { - if (this._element) { - setVisibility(false, this._element); - } + this._setVisible(false); this._uninstallRefreshListeners(); break; } case OverlayState.On: { - const element = this._ensureElement(); - setVisibility(true, element); + this._refresh(); this._installRefreshListeners(); break; } @@ -115,6 +116,13 @@ export class TerminalStickyScrollOverlay extends Disposable { this._refreshListeners.clear(); } + private _setVisible(isVisible: boolean) { + if (isVisible) { + this._ensureElement(); + } + this._element?.classList.toggle(CssClasses.Visible, isVisible); + } + @throttle(0) private _refresh(): void { if (!this._xterm?.raw?.element) { @@ -124,25 +132,24 @@ export class TerminalStickyScrollOverlay extends Disposable { // The command from viewportY + 1 is used because this one will not be obscured by sticky // scroll. const command = this._commandDetection.getCommandForLine(this._xterm.raw.buffer.active.viewportY + 1); - const element = this._ensureElement(); this._currentStickyMarker = undefined; // Sticky scroll only works with non-partial commands if (!command || !('marker' in command)) { - hide(element); + this._setVisible(false); return; } // Hide if the marker doesn't exist or has been trimmed from the scrollback const marker = command.marker; if (!marker || marker.line === -1) { - hide(element); + this._setVisible(false); return; } // Hide sticky scroll if it's on the same line if (marker.line === this._xterm.raw.buffer.active.viewportY) { - hide(element); + this._setVisible(false); return; } @@ -167,12 +174,12 @@ export class TerminalStickyScrollOverlay extends Disposable { if (command.exitCode !== undefined) { this._currentStickyMarker = marker; - show(element); + this._setVisible(true); } else { - hide(element); + this._setVisible(false); } } else { - hide(element); + this._setVisible(false); } } From 21cc54e39b8b89e4259125797a7ef9f537d42498 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 7 Nov 2023 11:53:40 -0800 Subject: [PATCH 081/240] resolve final newline regression for notebooks (#197671) --- .../browser/contrib/saveParticipants/saveParticipants.ts | 5 ++++- .../contrib/notebook/browser/notebook.contribution.ts | 8 ++++++-- .../workbench/contrib/notebook/common/notebookCommon.ts | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/saveParticipants/saveParticipants.ts b/src/vs/workbench/contrib/notebook/browser/contrib/saveParticipants/saveParticipants.ts index 1195c7767b2..04cdc764d38 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/saveParticipants/saveParticipants.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/saveParticipants/saveParticipants.ts @@ -253,7 +253,10 @@ class FinalNewLineParticipant implements IStoredFileWorkingCopySaveParticipant { ) { } async participate(workingCopy: IStoredFileWorkingCopy, context: { reason: SaveReason }, progress: IProgress, _token: CancellationToken): Promise { - if (this.configurationService.getValue('files.insertFinalNewline')) { + // waiting on notebook-specific override before this feature can sync with 'files.insertFinalNewline' + // if (this.configurationService.getValue('files.insertFinalNewline')) { + + if (this.configurationService.getValue(NotebookSetting.insertFinalNewline)) { await this.doInsertFinalNewLine(workingCopy, context.reason === SaveReason.AUTO, progress); } } diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index 96edb0787a4..9689de4040b 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -964,6 +964,12 @@ configurationRegistry.registerConfiguration({ tags: ['notebookLayout'], default: false }, + [NotebookSetting.insertFinalNewline]: { + markdownDescription: nls.localize('notebook.insertFinalNewline', "When enabled, insert a final new line into the end of code cells when saving a notebook."), + type: 'boolean', + tags: ['notebookLayout'], + default: false + }, [NotebookSetting.codeActionsOnSave]: { markdownDescription: nls.localize('notebook.codeActionsOnSave', 'Run a series of Code Actions for a notebook on save. Code Actions must be specified, the file must not be saved after delay, and the editor must not be shutting down. Example: `"notebook.source.organizeImports": "explicit"`'), type: 'object', @@ -1044,5 +1050,3 @@ configurationRegistry.registerConfiguration({ } } }); - - diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 98d58e5bf3f..3c5e49d88c6 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -950,6 +950,7 @@ export const NotebookSetting = { outputScrolling: 'notebook.output.scrolling', textOutputLineLimit: 'notebook.output.textLineLimit', formatOnSave: 'notebook.formatOnSave.enabled', + insertFinalNewline: 'notebook.insertFinalNewline', formatOnCellExecution: 'notebook.formatOnCellExecution', codeActionsOnSave: 'notebook.codeActionsOnSave', outputWordWrap: 'notebook.output.wordWrap', From 80ada7fde244ccdd7ba657506e00dbd04a6beccf Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 11:55:49 -0800 Subject: [PATCH 082/240] Reduce unnecessary option syncing --- .../browser/terminalStickyScrollOverlay.ts | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index 19749bf3038..0bbc21a3b3d 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -5,13 +5,14 @@ import type { CanvasAddon as CanvasAddonType } from '@xterm/addon-canvas'; import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; -import type { IMarker, Terminal as RawXtermTerminal } from '@xterm/xterm'; +import type { IMarker, ITerminalOptions, Terminal as RawXtermTerminal } from '@xterm/xterm'; import { importAMDNodeModule } from 'vs/amdX'; import { $, addStandardDisposableListener, append } from 'vs/base/browser/dom'; import { memoize, throttle } from 'vs/base/common/decorators'; import { Event } from 'vs/base/common/event'; import { Disposable, MutableDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/stickyScroll'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ICommandDetectionCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; @@ -20,6 +21,7 @@ import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; import { IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; +import { TERMINAL_CONFIG_SECTION } from 'vs/workbench/contrib/terminal/common/terminal'; import { TERMINAL_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { terminalStickyScrollBackground, terminalStickyScrollHoverBackground } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry'; @@ -49,6 +51,7 @@ export class TerminalStickyScrollOverlay extends Disposable { private readonly _xterm: IXtermTerminal & { raw: RawXtermTerminal }, private readonly _commandDetection: ICommandDetectionCapability, @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IConfigurationService configurationService: IConfigurationService, @IKeybindingService private readonly _keybindingService: IKeybindingService, @IThemeService private readonly _themeService: IThemeService, ) { @@ -59,14 +62,23 @@ export class TerminalStickyScrollOverlay extends Disposable { this._setState((buffer ?? this._xterm.raw.buffer.active).type === 'normal' ? OverlayState.On : OverlayState.Off); })); + this._register(configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(TERMINAL_CONFIG_SECTION)) { + this._syncOptions(); + } + })); + this._register(this._themeService.onDidColorThemeChange(() => { + this._syncOptions(); + })); + // Eagerly create the overlay TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { const overlay = new ctor({ rows: 1, cols: this._xterm.raw.cols, - allowProposedApi: true + allowProposedApi: true, + ...this._getOptions() }); - this._syncOptions(overlay, this._xterm.raw); this._stickyScrollOverlay = overlay; this._getSerializeAddonConstructor().then(SerializeAddon => { @@ -154,7 +166,7 @@ export class TerminalStickyScrollOverlay extends Disposable { } // TODO: Support multi-line prompts - // TODO: SUpport multi-line commands + // TODO: Support multi-line commands if (this._stickyScrollOverlay) { this._stickyScrollOverlay.write('\x1b[H\x1b[K'); @@ -167,9 +179,6 @@ export class TerminalStickyScrollOverlay extends Disposable { this._stickyScrollOverlay.write(content); // Debug log to show the command // this._stickyScrollOverlay.write(` [${command?.command}]`); - - // TODO: Only sync options when needed - this._syncOptions(this._stickyScrollOverlay, this._xterm.raw); } if (command.exitCode !== undefined) { @@ -194,7 +203,7 @@ export class TerminalStickyScrollOverlay extends Disposable { const hoverOverlay = $('.hover-overlay'); // Scroll to the command on click - this._register(addStandardDisposableListener(hoverOverlay, 'click', e => { + this._register(addStandardDisposableListener(hoverOverlay, 'click', () => { if (this._xterm && this._currentStickyMarker) { this._xterm.scrollToLine(this._currentStickyMarker.line, ScrollPosition.Middle); this._xterm.markTracker.registerTemporaryDecoration(this._currentStickyMarker); @@ -216,20 +225,28 @@ export class TerminalStickyScrollOverlay extends Disposable { return this._element; } - private _syncOptions(target: RawXtermTerminal, copyFrom: RawXtermTerminal): void { - const o = copyFrom.options; + @throttle(0) + private _syncOptions(): void { + if (!this._stickyScrollOverlay) { + return; + } + this._stickyScrollOverlay.resize(this._xterm.raw.cols, 1); + this._stickyScrollOverlay.options = this._getOptions(); + } + + private _getOptions(): ITerminalOptions { + const o = this._xterm.raw.options; const theme = this._themeService.getColorTheme(); // TODO: BG should be editor-aware const terminalBackground = theme.getColor(terminalStickyScrollBackground) || theme.getColor(TERMINAL_BACKGROUND_COLOR) || theme.getColor(PANEL_BACKGROUND); - target.resize(copyFrom.cols, 1); - target.options = { + return { cursorInactiveStyle: 'none', scrollback: 0, logLevel: 'off', // Selection is used for hover state in the overlay theme: { - ...this._xterm!.getXtermTheme(), + ...this._xterm.getXtermTheme(), background: terminalBackground?.toString(), selectionBackground: theme.getColor(terminalStickyScrollHoverBackground)?.toString(), selectionInactiveBackground: undefined From fa39026a87db756f15152b523fc1be6ee5bfec94 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:01:47 -0800 Subject: [PATCH 083/240] Simplify early returns --- .../browser/terminalStickyScrollOverlay.ts | 81 ++++++++++--------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index 0bbc21a3b3d..826e404c4ec 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -152,15 +152,15 @@ export class TerminalStickyScrollOverlay extends Disposable { return; } - // Hide if the marker doesn't exist or has been trimmed from the scrollback const marker = command.marker; - if (!marker || marker.line === -1) { - this._setVisible(false); - return; - } - - // Hide sticky scroll if it's on the same line - if (marker.line === this._xterm.raw.buffer.active.viewportY) { + if ( + // The marker doesn't exist + !marker || + // The marker was trimmed from the scrollback + marker.line === -1 || + // Hide sticky scroll if it's on the same line + marker.line === this._xterm.raw.buffer.active.viewportY + ) { this._setVisible(false); return; } @@ -192,37 +192,44 @@ export class TerminalStickyScrollOverlay extends Disposable { } } - private _ensureElement(): HTMLElement { - if (!this._element) { - this._element = document.createElement('div'); - // TODO: Use display in a class over hide/show/setVisibility - this._element.classList.add('terminal-sticky-scroll'); - // // TODO: Safety - this._xterm!.raw.element!.parentElement!.append(this._element); - - const hoverOverlay = $('.hover-overlay'); - - // Scroll to the command on click - this._register(addStandardDisposableListener(hoverOverlay, 'click', () => { - if (this._xterm && this._currentStickyMarker) { - this._xterm.scrollToLine(this._currentStickyMarker.line, ScrollPosition.Middle); - this._xterm.markTracker.registerTemporaryDecoration(this._currentStickyMarker); - } - })); - - // Instead of juggling decorations for hover styles, use the selection to indicate the - // hover state as the selection is inaccessible anyway - this._register(addStandardDisposableListener(hoverOverlay, 'mouseover', () => this._stickyScrollOverlay?.selectAll())); - this._register(addStandardDisposableListener(hoverOverlay, 'mouseleave', () => this._stickyScrollOverlay?.clearSelection())); - - // TODO: Add to a container outside the xterm instance? - // TODO: Remove ! - this._stickyScrollOverlay!.open(this._element); - - append(this._element, hoverOverlay); + private _ensureElement() { + if ( + // The element is already created + this._element || + // If the overlay is yet to be created, the terminal cannot be opened so defer to next call + !this._stickyScrollOverlay || + // The xterm.js instance isn't opened yet + !this._xterm?.raw.element?.parentElement + ) { + return; } - return this._element; + const overlay = this._stickyScrollOverlay; + + this._element = $('.terminal-sticky-scroll'); + // // TODO: Safety + this._xterm!.raw.element!.parentElement!.append(this._element); + + const hoverOverlay = $('.hover-overlay'); + + // Scroll to the command on click + this._register(addStandardDisposableListener(hoverOverlay, 'click', () => { + if (this._xterm && this._currentStickyMarker) { + this._xterm.scrollToLine(this._currentStickyMarker.line, ScrollPosition.Middle); + this._xterm.markTracker.registerTemporaryDecoration(this._currentStickyMarker); + } + })); + + // Instead of juggling decorations for hover styles, use the selection to indicate the + // hover state as the selection is inaccessible anyway + this._register(addStandardDisposableListener(hoverOverlay, 'mouseover', () => overlay.selectAll())); + this._register(addStandardDisposableListener(hoverOverlay, 'mouseleave', () => overlay.clearSelection())); + + // TODO: Add to a container outside the xterm instance? + // TODO: Remove ! + this._stickyScrollOverlay.open(this._element); + + append(this._element, hoverOverlay); } @throttle(0) From 80e6659815dd6256b3c94d47589229545c9875b2 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:08:12 -0800 Subject: [PATCH 084/240] Add terminal sticky scroll setting --- src/vs/platform/terminal/common/terminal.ts | 1 + .../terminal/common/terminalConfiguration.ts | 7 ++ .../terminal.stickyScroll.contribution.ts | 27 +++++-- .../browser/terminalStickyScrollOverlay.ts | 81 +++++++++++++------ 4 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 52cb584712a..430097703dc 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -118,6 +118,7 @@ export const enum TerminalSettingId { FocusAfterRun = 'terminal.integrated.focusAfterRun', AccessibleViewPreserveCursorPosition = 'terminal.integrated.accessibleViewPreserveCursorPosition', AccessibleViewFocusOnCommandExecution = 'terminal.integrated.accessibleViewFocusOnCommandExecution', + EnableStickyScroll = 'terminal.integrated.enableStickyScroll', // Debug settings that are hidden from user diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index d26dfe59220..7149dfd2fa6 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -625,6 +625,13 @@ const terminalConfiguration: IConfigurationNode = { type: 'boolean', default: false }, + [TerminalSettingId.EnableStickyScroll]: { + markdownDescription: localize('terminal.integrated.enableStickyScroll', "Experimental: Whether to enable the sticky scroll overlay at the top of the terminal."), + type: 'boolean', + default: false, + // TODO: Prevent setting at folder level after it becomes stable, + // scope: ConfigurationScope.RESOURCE + } } }; diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index 2c9602645cb..7c8615211a7 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; +import { IDimension } from 'vs/base/browser/dom'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/stickyScroll'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { ITerminalContribution, ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; @@ -32,11 +35,17 @@ class TerminalStickyScrollContribution extends Disposable implements ITerminalCo private readonly _instance: ITerminalInstance, processManager: ITerminalProcessManager | ITerminalProcessInfo, widgetManager: TerminalWidgetManager, + @IConfigurationService private readonly _configurationService: IConfigurationService, @IInstantiationService private readonly _instantiationService: IInstantiationService, ) { super(); this._refreshState(); + this._configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(TerminalSettingId.EnableStickyScroll)) { + this._refreshState(); + } + }); } xtermReady(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { @@ -44,6 +53,10 @@ class TerminalStickyScrollContribution extends Disposable implements ITerminalCo this._refreshState(); } + layout(xterm: IXtermTerminal & { raw: RawXtermTerminal }, dimension: IDimension): void { + this._refreshState(); + } + private _refreshState(): void { if (this._overlay.value) { this._tryDisable(); @@ -73,18 +86,22 @@ class TerminalStickyScrollContribution extends Disposable implements ITerminalCo } private _tryEnable(): void { - const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection); - if (capability && this._xterm) { - this._overlay.value = this._instantiationService.createInstance(TerminalStickyScrollOverlay, this._xterm, capability); + if (this._shouldBeEnabled()) { + // TODO: Ensure open has happened to prevent race condition where not attached + this._overlay.value = this._instantiationService.createInstance(TerminalStickyScrollOverlay, this._xterm!, this._instance.capabilities.get(TerminalCapability.CommandDetection)!); } } private _tryDisable(): void { - const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection); - if (!capability || !this._xterm) { + if (!this._shouldBeEnabled()) { this._overlay.clear(); } } + + private _shouldBeEnabled(): boolean { + const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection); + return !!(this._configurationService.getValue(TerminalSettingId.EnableStickyScroll) && capability && this._xterm?.raw?.element); + } } registerTerminalContribution(TerminalStickyScrollContribution.ID, TerminalStickyScrollContribution, true); diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index 826e404c4ec..aad6f46b450 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -7,10 +7,11 @@ import type { CanvasAddon as CanvasAddonType } from '@xterm/addon-canvas'; import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; import type { IMarker, ITerminalOptions, Terminal as RawXtermTerminal } from '@xterm/xterm'; import { importAMDNodeModule } from 'vs/amdX'; -import { $, addStandardDisposableListener, append } from 'vs/base/browser/dom'; +import { $, addStandardDisposableListener } from 'vs/base/browser/dom'; +import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; import { memoize, throttle } from 'vs/base/common/decorators'; import { Event } from 'vs/base/common/event'; -import { Disposable, MutableDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, MutableDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/stickyScroll'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; @@ -38,7 +39,9 @@ const enum CssClasses { export class TerminalStickyScrollOverlay extends Disposable { private _stickyScrollOverlay?: RawXtermTerminal; private _serializeAddon?: SerializeAddonType; - private _canvasAddon?: CanvasAddonType; + + private _canvasAddon = new MutableDisposable(); + private _pendingCanvasAddon?: CancelablePromise; private _element?: HTMLElement; private _currentStickyMarker?: IMarker; @@ -62,6 +65,7 @@ export class TerminalStickyScrollOverlay extends Disposable { this._setState((buffer ?? this._xterm.raw.buffer.active).type === 'normal' ? OverlayState.On : OverlayState.Off); })); + // React to option changes this._register(configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(TERMINAL_CONFIG_SECTION)) { this._syncOptions(); @@ -73,26 +77,21 @@ export class TerminalStickyScrollOverlay extends Disposable { // Eagerly create the overlay TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { - const overlay = new ctor({ + this._stickyScrollOverlay = new ctor({ rows: 1, cols: this._xterm.raw.cols, allowProposedApi: true, ...this._getOptions() }); - this._stickyScrollOverlay = overlay; this._getSerializeAddonConstructor().then(SerializeAddon => { this._serializeAddon = new SerializeAddon(); this._xterm.raw.loadAddon(this._serializeAddon); + // Trigger a render as the serialize addon is required to render + this._refresh(); }); - // TODO: Sync every render - if (this._xterm.isGpuAccelerated) { - this._getCanvasAddonConstructor().then(CanvasAddon => { - this._canvasAddon = new CanvasAddon(); - overlay.loadAddon(this._canvasAddon); - }); - } + this._syncGpuAccelerationState(); }); } @@ -119,6 +118,7 @@ export class TerminalStickyScrollOverlay extends Disposable { this._refreshListeners.value = combinedDisposable( this._xterm.raw.onScroll(() => this._refresh()), this._xterm.raw.onLineFeed(() => this._refresh()), + // TODO: This may not exist!!! addStandardDisposableListener(this._xterm.raw.element!.querySelector('.xterm-viewport')!, 'scroll', () => this._refresh()), ); } @@ -131,13 +131,16 @@ export class TerminalStickyScrollOverlay extends Disposable { private _setVisible(isVisible: boolean) { if (isVisible) { this._ensureElement(); + // The GPU acceleration state may be changes at any time and there is no event to listen + // to currently. + this._syncGpuAccelerationState(); } this._element?.classList.toggle(CssClasses.Visible, isVisible); } @throttle(0) private _refresh(): void { - if (!this._xterm?.raw?.element) { + if (!this._xterm?.raw?.element || !this._serializeAddon) { return; } @@ -164,17 +167,19 @@ export class TerminalStickyScrollOverlay extends Disposable { this._setVisible(false); return; } - // TODO: Support multi-line prompts // TODO: Support multi-line commands if (this._stickyScrollOverlay) { - this._stickyScrollOverlay.write('\x1b[H\x1b[K'); + // Clear attrs, reset cursor position, clear right + this._stickyScrollOverlay.write('\x1b[0m\x1b[H\x1b[K'); // TODO: Serializing all content up to the required line is inefficient; support providing single line/range serialize addon - const s = this._serializeAddon?.serialize({ + const s = this._serializeAddon.serialize({ scrollback: this._xterm.raw.buffer.active.baseY - marker.line }); const content = s ? s.substring(0, s.indexOf('\r')) : undefined; + + // TODO: Don't write if it's the same if (content) { this._stickyScrollOverlay.write(content); // Debug log to show the command @@ -207,10 +212,12 @@ export class TerminalStickyScrollOverlay extends Disposable { const overlay = this._stickyScrollOverlay; this._element = $('.terminal-sticky-scroll'); - // // TODO: Safety - this._xterm!.raw.element!.parentElement!.append(this._element); - const hoverOverlay = $('.hover-overlay'); + this._element.append(hoverOverlay); + this._xterm.raw.element.parentElement.append(this._element); + this._register(toDisposable(() => this._element?.remove())); + + this._stickyScrollOverlay.open(this._element); // Scroll to the command on click this._register(addStandardDisposableListener(hoverOverlay, 'click', () => { @@ -224,21 +231,43 @@ export class TerminalStickyScrollOverlay extends Disposable { // hover state as the selection is inaccessible anyway this._register(addStandardDisposableListener(hoverOverlay, 'mouseover', () => overlay.selectAll())); this._register(addStandardDisposableListener(hoverOverlay, 'mouseleave', () => overlay.clearSelection())); - - // TODO: Add to a container outside the xterm instance? - // TODO: Remove ! - this._stickyScrollOverlay.open(this._element); - - append(this._element, hoverOverlay); } @throttle(0) - private _syncOptions(): void { + private _syncOptions() { if (!this._stickyScrollOverlay) { return; } this._stickyScrollOverlay.resize(this._xterm.raw.cols, 1); this._stickyScrollOverlay.options = this._getOptions(); + this._syncGpuAccelerationState(); + } + + private _syncGpuAccelerationState() { + if (!this._stickyScrollOverlay) { + return; + } + const overlay = this._stickyScrollOverlay; + + // The Webgl renderer isn't used here as there are a limited number of webgl contexts + // available within a given page. This is a single row that isn't rendered to often so the + // performance isn't as important + if (this._xterm.isGpuAccelerated) { + if (!this._canvasAddon.value && !this._pendingCanvasAddon) { + this._pendingCanvasAddon = createCancelablePromise(async token => { + const CanvasAddon = await this._getCanvasAddonConstructor(); + if (!token.isCancellationRequested) { + this._canvasAddon.value = new CanvasAddon(); + overlay.loadAddon(this._canvasAddon.value); + } + this._pendingCanvasAddon = undefined; + }); + } + } else { + this._canvasAddon.clear(); + this._pendingCanvasAddon?.cancel(); + this._pendingCanvasAddon = undefined; + } } private _getOptions(): ITerminalOptions { From 42a2de206f073e9224f7eeefc5b42331e84bf6fa Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:20:57 -0800 Subject: [PATCH 085/240] Set default terminal sticky scroll in vscode temporarily --- .vscode/settings.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 98bd618b14f..4959b16d094 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -164,5 +164,8 @@ "vscode-notebook-renderer", "src/vs/workbench/workbench.web.main.ts", "src/vs/workbench/api/common/extHostTypes.ts" - ] + ], + + // Temporarily enabled for self-hosting + "terminal.integrated.enableStickyScroll": true, } From 1baf7828f00c1c8e3326be6cec2c0e2a511a1e5e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:23:58 -0800 Subject: [PATCH 086/240] Improve lifecycle/registering in term sticky scroll --- .../browser/terminal.stickyScroll.contribution.ts | 9 ++++----- .../stickyScroll/browser/terminalStickyScrollOverlay.ts | 8 ++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index 7c8615211a7..b05e23d8b5c 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -5,6 +5,7 @@ import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; import { IDimension } from 'vs/base/browser/dom'; +import { Event } from 'vs/base/common/event'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/stickyScroll'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -40,12 +41,11 @@ class TerminalStickyScrollContribution extends Disposable implements ITerminalCo ) { super(); - this._refreshState(); - this._configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration(TerminalSettingId.EnableStickyScroll)) { + this._register(Event.runAndSubscribe(this._configurationService.onDidChangeConfiguration, e => { + if (!e || e.affectsConfiguration(TerminalSettingId.EnableStickyScroll)) { this._refreshState(); } - }); + })); } xtermReady(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { @@ -87,7 +87,6 @@ class TerminalStickyScrollContribution extends Disposable implements ITerminalCo private _tryEnable(): void { if (this._shouldBeEnabled()) { - // TODO: Ensure open has happened to prevent race condition where not attached this._overlay.value = this._instantiationService.createInstance(TerminalStickyScrollOverlay, this._xterm!, this._instance.capabilities.get(TerminalCapability.CommandDetection)!); } } diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index aad6f46b450..51bad0a2f4f 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -40,7 +40,7 @@ export class TerminalStickyScrollOverlay extends Disposable { private _stickyScrollOverlay?: RawXtermTerminal; private _serializeAddon?: SerializeAddonType; - private _canvasAddon = new MutableDisposable(); + private _canvasAddon = this._register(new MutableDisposable()); private _pendingCanvasAddon?: CancelablePromise; private _element?: HTMLElement; @@ -77,15 +77,15 @@ export class TerminalStickyScrollOverlay extends Disposable { // Eagerly create the overlay TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { - this._stickyScrollOverlay = new ctor({ + this._stickyScrollOverlay = this._register(new ctor({ rows: 1, cols: this._xterm.raw.cols, allowProposedApi: true, ...this._getOptions() - }); + })); this._getSerializeAddonConstructor().then(SerializeAddon => { - this._serializeAddon = new SerializeAddon(); + this._serializeAddon = this._register(new SerializeAddon()); this._xterm.raw.loadAddon(this._serializeAddon); // Trigger a render as the serialize addon is required to render this._refresh(); From b69e183352afc521be9eb2b05f2b5601f9ea4882 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:28:05 -0800 Subject: [PATCH 087/240] Don't write content if it didn't change --- .../stickyScroll/browser/media/stickyScroll.css | 1 - .../browser/terminalStickyScrollOverlay.ts | 13 +++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css index 5aeb7d6d374..e4ed9dfcf73 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/media/stickyScroll.css @@ -23,7 +23,6 @@ } .terminal-sticky-scroll .xterm { - /* TODO: Remove !important */ position: relative !important; pointer-events: none; padding-bottom: 0 !important; diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index 51bad0a2f4f..ffe0653777a 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -45,6 +45,7 @@ export class TerminalStickyScrollOverlay extends Disposable { private _element?: HTMLElement; private _currentStickyMarker?: IMarker; + private _currentContent?: string; private _refreshListeners = this._register(new MutableDisposable()); @@ -118,7 +119,6 @@ export class TerminalStickyScrollOverlay extends Disposable { this._refreshListeners.value = combinedDisposable( this._xterm.raw.onScroll(() => this._refresh()), this._xterm.raw.onLineFeed(() => this._refresh()), - // TODO: This may not exist!!! addStandardDisposableListener(this._xterm.raw.element!.querySelector('.xterm-viewport')!, 'scroll', () => this._refresh()), ); } @@ -172,21 +172,22 @@ export class TerminalStickyScrollOverlay extends Disposable { if (this._stickyScrollOverlay) { // Clear attrs, reset cursor position, clear right - this._stickyScrollOverlay.write('\x1b[0m\x1b[H\x1b[K'); // TODO: Serializing all content up to the required line is inefficient; support providing single line/range serialize addon const s = this._serializeAddon.serialize({ scrollback: this._xterm.raw.buffer.active.baseY - marker.line }); - const content = s ? s.substring(0, s.indexOf('\r')) : undefined; - // TODO: Don't write if it's the same - if (content) { + // Write content if it differs + const content = s ? s.substring(0, s.indexOf('\r')) : undefined; + if (content && this._currentContent !== content) { + this._stickyScrollOverlay.write('\x1b[0m\x1b[H\x1b[K'); this._stickyScrollOverlay.write(content); + this._currentContent = content; // Debug log to show the command // this._stickyScrollOverlay.write(` [${command?.command}]`); } - if (command.exitCode !== undefined) { + if (content && command.exitCode !== undefined) { this._currentStickyMarker = marker; this._setVisible(true); } else { From e778bc57d47ef8031e572fa58b7ac5c2a0456884 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:29:53 -0800 Subject: [PATCH 088/240] Remove done todos --- .../stickyScroll/browser/terminalStickyScrollColorRegistry.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry.ts index 697f210cfae..3fb4a9f9322 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry.ts @@ -8,7 +8,6 @@ import 'vs/css!./media/stickyScroll'; import { localize } from 'vs/nls'; import { registerColor } from 'vs/platform/theme/common/colorRegistry'; -// HACK: These are derived from the editor background, not the terminal background because export const terminalStickyScrollBackground = registerColor('terminalStickyScroll.background', { light: null, dark: null, @@ -16,7 +15,6 @@ export const terminalStickyScrollBackground = registerColor('terminalStickyScrol hcLight: null }, localize('terminalStickyScroll.background', 'The background color of the sticky scroll overlay in the terminal.')); -// TODO: These default values are from the editorStickyScrollHover.background and may not be ideal export const terminalStickyScrollHoverBackground = registerColor('terminalStickyScrollHover.background', { dark: '#2A2D2E', light: '#F0F0F0', From c204ef06857909ceacdbe8066ac9322f61fda226 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:54:27 -0800 Subject: [PATCH 089/240] Make sticky scroll terminal editor aware --- .../browser/terminal.stickyScroll.contribution.ts | 2 +- .../browser/terminalStickyScrollOverlay.ts | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index b05e23d8b5c..924ae91006b 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -87,7 +87,7 @@ class TerminalStickyScrollContribution extends Disposable implements ITerminalCo private _tryEnable(): void { if (this._shouldBeEnabled()) { - this._overlay.value = this._instantiationService.createInstance(TerminalStickyScrollOverlay, this._xterm!, this._instance.capabilities.get(TerminalCapability.CommandDetection)!); + this._overlay.value = this._instantiationService.createInstance(TerminalStickyScrollOverlay, this._instance, this._xterm!, this._instance.capabilities.get(TerminalCapability.CommandDetection)!); } } diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index ffe0653777a..cfbef437710 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -17,9 +17,11 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ICommandDetectionCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { TerminalLocation } from 'vs/platform/terminal/common/terminal'; +import { editorBackground } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; -import { IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; import { TERMINAL_CONFIG_SECTION } from 'vs/workbench/contrib/terminal/common/terminal'; @@ -52,6 +54,7 @@ export class TerminalStickyScrollOverlay extends Disposable { private _state: OverlayState = OverlayState.Off; constructor( + private readonly _instance: ITerminalInstance, private readonly _xterm: IXtermTerminal & { raw: RawXtermTerminal }, private readonly _commandDetection: ICommandDetectionCapability, @IContextKeyService private readonly _contextKeyService: IContextKeyService, @@ -274,8 +277,9 @@ export class TerminalStickyScrollOverlay extends Disposable { private _getOptions(): ITerminalOptions { const o = this._xterm.raw.options; const theme = this._themeService.getColorTheme(); - // TODO: BG should be editor-aware - const terminalBackground = theme.getColor(terminalStickyScrollBackground) || theme.getColor(TERMINAL_BACKGROUND_COLOR) || theme.getColor(PANEL_BACKGROUND); + const terminalBackground = theme.getColor(terminalStickyScrollBackground) || theme.getColor(TERMINAL_BACKGROUND_COLOR) || ( + theme.getColor(this._instance.target === TerminalLocation.Editor ? editorBackground : PANEL_BACKGROUND) + ); return { cursorInactiveStyle: 'none', scrollback: 0, From 3a21f7e2bc12bd0475632c72eab45500157a078f Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:57:35 -0800 Subject: [PATCH 090/240] Reduce CommandDetectionCapability.getCommandForLine GC pressure --- .../capabilities/commandDetectionCapability.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index 3dfa5449188..b936bee3378 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -303,10 +303,14 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe return undefined; } - // TODO: It would be more reliable to take the closest cwd above the line if it isn't found for the line - // TODO: Use a reverse for loop to find the line to avoid creating another array - const reversed = [...this._commands].reverse(); - return reversed.find(c => c.marker!.line <= line - 1); + // Iterate backwards through commands to find the right one + for (let i = this.commands.length - 1; i >= 0; i--) { + if (this.commands[i].marker!.line <= line - 1) { + return this.commands[i]; + } + } + + return undefined; } getCwdForLine(line: number): string | undefined { From 54d14103d683ac9235af627941b0dd153d44d957 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:59:19 -0800 Subject: [PATCH 091/240] Share code in command detection --- .../common/capabilities/commandDetectionCapability.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index b936bee3378..f91a529451f 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -319,10 +319,13 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe if (this._currentCommand.promptStartMarker && line >= this._currentCommand.promptStartMarker?.line) { return this._cwd; } - // TODO: It would be more reliable to take the closest cwd above the line if it isn't found for the line - // TODO: Use a reverse for loop to find the line to avoid creating another array - const reversed = [...this._commands].reverse(); - return reversed.find(c => c.marker!.line <= line - 1)?.cwd; + + const command = this.getCommandForLine(line); + if (command && 'cwd' in command) { + return command.cwd; + } + + return undefined; } handlePromptStart(options?: IHandleCommandOptions): void { From 0bbbea768005660f97c3028943d20b42e3710aba Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:22:28 -0800 Subject: [PATCH 092/240] Tidy up --- .../terminal/browser/terminalInstance.ts | 45 ++++--- .../terminal/browser/xterm/xtermTerminal.ts | 4 +- .../terminal.stickyScroll.contribution.ts | 100 +-------------- .../terminalStickyScrollContribution.ts | 115 ++++++++++++++++++ .../browser/terminalStickyScrollOverlay.ts | 26 ++-- 5 files changed, 154 insertions(+), 136 deletions(-) create mode 100644 src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollContribution.ts diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 4345fac23a4..d89dee6a9e7 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -52,13 +52,13 @@ import { IProcessDataEvent, IProcessPropertyMap, IReconnectionProperties, IShell import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings'; import { editorBackground } from 'vs/platform/theme/common/colorRegistry'; import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/workspaceTrust'; import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; import { IViewDescriptorService, IViewsService, ViewContainerLocation } from 'vs/workbench/common/views'; import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; -import { IRequestAddInstanceToGroupEvent, ITerminalContribution, ITerminalInstance, TerminalDataTransfers } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { IRequestAddInstanceToGroupEvent, ITerminalContribution, ITerminalInstance, IXtermColorProvider, TerminalDataTransfers } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalLaunchHelpAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput'; @@ -718,22 +718,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._configHelper, this._cols, this._rows, - { - getBackgroundColor: (theme) => { - const terminalBackground = theme.getColor(TERMINAL_BACKGROUND_COLOR); - if (terminalBackground) { - return terminalBackground; - } - if (this.target === TerminalLocation.Editor) { - return theme.getColor(editorBackground); - } - const location = this._viewDescriptorService.getViewLocationById(TERMINAL_VIEW_ID)!; - if (location === ViewContainerLocation.Panel) { - return theme.getColor(PANEL_BACKGROUND); - } - return theme.getColor(SIDE_BAR_BACKGROUND); - } - }, + this._scopedInstantiationService.createInstance(TerminalInstanceColorProvider, this), this.capabilities, this._processManager.shellIntegrationNonce, this._terminalSuggestWidgetVisibleContextKey, @@ -2565,3 +2550,27 @@ export function parseExitResult( return { code, message }; } + + +export class TerminalInstanceColorProvider implements IXtermColorProvider { + constructor( + private readonly _instance: ITerminalInstance, + @IViewDescriptorService private readonly _viewDescriptorService: IViewDescriptorService, + ) { + } + + getBackgroundColor(theme: IColorTheme) { + const terminalBackground = theme.getColor(TERMINAL_BACKGROUND_COLOR); + if (terminalBackground) { + return terminalBackground; + } + if (this._instance.target === TerminalLocation.Editor) { + return theme.getColor(editorBackground); + } + const location = this._viewDescriptorService.getViewLocationById(TERMINAL_VIEW_ID)!; + if (location === ViewContainerLocation.Panel) { + return theme.getColor(PANEL_BACKGROUND); + } + return theme.getColor(SIDE_BAR_BACKGROUND); + } +} diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index c959b0cf5f8..6aa94b24164 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -195,7 +195,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach private readonly _configHelper: TerminalConfigHelper, cols: number, rows: number, - private readonly _backgroundColorProvider: IXtermColorProvider, + private readonly _xtermColorProvider: IXtermColorProvider, private readonly _capabilities: ITerminalCapabilityStore, shellIntegrationNonce: string, private readonly _terminalSuggestWidgetVisibleContextKey: IContextKey | undefined, @@ -908,7 +908,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach } const foregroundColor = theme.getColor(TERMINAL_FOREGROUND_COLOR); - const backgroundColor = this._backgroundColorProvider.getBackgroundColor(theme); + const backgroundColor = this._xtermColorProvider.getBackgroundColor(theme); const cursorColor = theme.getColor(TERMINAL_CURSOR_FOREGROUND_COLOR) || foregroundColor; const cursorAccentColor = theme.getColor(TERMINAL_CURSOR_BACKGROUND_COLOR) || backgroundColor; const selectionBackgroundColor = theme.getColor(TERMINAL_SELECTION_BACKGROUND_COLOR); diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts index 924ae91006b..93a11026354 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution.ts @@ -3,104 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; -import { IDimension } from 'vs/base/browser/dom'; -import { Event } from 'vs/base/common/event'; -import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import 'vs/css!./media/stickyScroll'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; -import { TerminalSettingId } from 'vs/platform/terminal/common/terminal'; -import { ITerminalContribution, ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; -import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; -import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; -import { TerminalStickyScrollOverlay } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay'; +import { TerminalStickyScrollContribution } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollContribution'; -class TerminalStickyScrollContribution extends Disposable implements ITerminalContribution { - static readonly ID = 'terminal.stickyScroll'; - - static get(instance: ITerminalInstance): TerminalStickyScrollContribution | null { - return instance.getContribution(TerminalStickyScrollContribution.ID); - } - - private _xterm?: IXtermTerminal & { raw: RawXtermTerminal }; - - private _overlay = this._register(new MutableDisposable()); - - private _enableListeners = this._register(new MutableDisposable()); - private _disableListeners = this._register(new MutableDisposable()); - - constructor( - private readonly _instance: ITerminalInstance, - processManager: ITerminalProcessManager | ITerminalProcessInfo, - widgetManager: TerminalWidgetManager, - @IConfigurationService private readonly _configurationService: IConfigurationService, - @IInstantiationService private readonly _instantiationService: IInstantiationService, - ) { - super(); - - this._register(Event.runAndSubscribe(this._configurationService.onDidChangeConfiguration, e => { - if (!e || e.affectsConfiguration(TerminalSettingId.EnableStickyScroll)) { - this._refreshState(); - } - })); - } - - xtermReady(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { - this._xterm = xterm; - this._refreshState(); - } - - layout(xterm: IXtermTerminal & { raw: RawXtermTerminal }, dimension: IDimension): void { - this._refreshState(); - } - - private _refreshState(): void { - if (this._overlay.value) { - this._tryDisable(); - } else { - this._tryEnable(); - } - - if (this._overlay.value) { - this._enableListeners.clear(); - if (!this._disableListeners.value) { - this._disableListeners.value = this._instance.capabilities.onDidRemoveCapability(e => { - if (e.id === TerminalCapability.CommandDetection) { - this._refreshState(); - } - }); - } - } else { - this._disableListeners.clear(); - if (!this._enableListeners.value) { - this._enableListeners.value = this._instance.capabilities.onDidAddCapability(e => { - if (e.id === TerminalCapability.CommandDetection) { - this._refreshState(); - } - }); - } - } - } - - private _tryEnable(): void { - if (this._shouldBeEnabled()) { - this._overlay.value = this._instantiationService.createInstance(TerminalStickyScrollOverlay, this._instance, this._xterm!, this._instance.capabilities.get(TerminalCapability.CommandDetection)!); - } - } - - private _tryDisable(): void { - if (!this._shouldBeEnabled()) { - this._overlay.clear(); - } - } - - private _shouldBeEnabled(): boolean { - const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection); - return !!(this._configurationService.getValue(TerminalSettingId.EnableStickyScroll) && capability && this._xterm?.raw?.element); - } -} +import 'vs/css!./media/stickyScroll'; +import './terminalStickyScrollColorRegistry'; registerTerminalContribution(TerminalStickyScrollContribution.ID, TerminalStickyScrollContribution, true); diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollContribution.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollContribution.ts new file mode 100644 index 00000000000..b25dc5a5bdb --- /dev/null +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollContribution.ts @@ -0,0 +1,115 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; +import { IDimension } from 'vs/base/browser/dom'; +import { Event } from 'vs/base/common/event'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import 'vs/css!./media/stickyScroll'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { TerminalSettingId } from 'vs/platform/terminal/common/terminal'; +import { ITerminalContribution, ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { TerminalInstance, TerminalInstanceColorProvider } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; +import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; +import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; +import { TerminalStickyScrollOverlay } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay'; + +export class TerminalStickyScrollContribution extends Disposable implements ITerminalContribution { + static readonly ID = 'terminal.stickyScroll'; + + static get(instance: ITerminalInstance): TerminalStickyScrollContribution | null { + return instance.getContribution(TerminalStickyScrollContribution.ID); + } + + private _xterm?: IXtermTerminal & { raw: RawXtermTerminal }; + + private _overlay = this._register(new MutableDisposable()); + + private _enableListeners = this._register(new MutableDisposable()); + private _disableListeners = this._register(new MutableDisposable()); + + constructor( + private readonly _instance: ITerminalInstance, + processManager: ITerminalProcessManager | ITerminalProcessInfo, + widgetManager: TerminalWidgetManager, + @IConfigurationService private readonly _configurationService: IConfigurationService, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IKeybindingService private readonly _keybindingService: IKeybindingService, + ) { + super(); + + this._register(Event.runAndSubscribe(this._configurationService.onDidChangeConfiguration, e => { + if (!e || e.affectsConfiguration(TerminalSettingId.EnableStickyScroll)) { + this._refreshState(); + } + })); + } + + xtermReady(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { + this._xterm = xterm; + this._refreshState(); + } + + layout(xterm: IXtermTerminal & { raw: RawXtermTerminal }, dimension: IDimension): void { + this._refreshState(); + } + + private _refreshState(): void { + if (this._overlay.value) { + this._tryDisable(); + } else { + this._tryEnable(); + } + + if (this._overlay.value) { + this._enableListeners.clear(); + if (!this._disableListeners.value) { + this._disableListeners.value = this._instance.capabilities.onDidRemoveCapability(e => { + if (e.id === TerminalCapability.CommandDetection) { + this._refreshState(); + } + }); + } + } else { + this._disableListeners.clear(); + if (!this._enableListeners.value) { + this._enableListeners.value = this._instance.capabilities.onDidAddCapability(e => { + if (e.id === TerminalCapability.CommandDetection) { + this._refreshState(); + } + }); + } + } + } + + private _tryEnable(): void { + if (this._shouldBeEnabled()) { + const xtermCtorEventually = TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService); + this._overlay.value = this._instantiationService.createInstance( + TerminalStickyScrollOverlay, + this._xterm!, + this._instantiationService.createInstance(TerminalInstanceColorProvider, this._instance), + this._instance.capabilities.get(TerminalCapability.CommandDetection)!, + xtermCtorEventually + ); + } + } + + private _tryDisable(): void { + if (!this._shouldBeEnabled()) { + this._overlay.clear(); + } + } + + private _shouldBeEnabled(): boolean { + const capability = this._instance.capabilities.get(TerminalCapability.CommandDetection); + return !!(this._configurationService.getValue(TerminalSettingId.EnableStickyScroll) && capability && this._xterm?.raw?.element); + } +} diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index cfbef437710..ebffd73f28d 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -2,10 +2,9 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - import type { CanvasAddon as CanvasAddonType } from '@xterm/addon-canvas'; import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; -import type { IMarker, ITerminalOptions, Terminal as RawXtermTerminal } from '@xterm/xterm'; +import type { IMarker, ITerminalOptions, Terminal as RawXtermTerminal, Terminal as XTermTerminal } from '@xterm/xterm'; import { importAMDNodeModule } from 'vs/amdX'; import { $, addStandardDisposableListener } from 'vs/base/browser/dom'; import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; @@ -14,19 +13,12 @@ import { Event } from 'vs/base/common/event'; import { Disposable, MutableDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./media/stickyScroll'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ICommandDetectionCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; -import { TerminalLocation } from 'vs/platform/terminal/common/terminal'; -import { editorBackground } from 'vs/platform/theme/common/colorRegistry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; -import { ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; +import { IXtermColorProvider, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; import { TERMINAL_CONFIG_SECTION } from 'vs/workbench/contrib/terminal/common/terminal'; -import { TERMINAL_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; -import { terminalStickyScrollBackground, terminalStickyScrollHoverBackground } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry'; +import { terminalStickyScrollHoverBackground } from 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollColorRegistry'; const enum OverlayState { /** Initial state/disabled by the alt buffer. */ @@ -54,12 +46,11 @@ export class TerminalStickyScrollOverlay extends Disposable { private _state: OverlayState = OverlayState.Off; constructor( - private readonly _instance: ITerminalInstance, private readonly _xterm: IXtermTerminal & { raw: RawXtermTerminal }, + private readonly _xtermColorProvider: IXtermColorProvider, private readonly _commandDetection: ICommandDetectionCapability, - @IContextKeyService private readonly _contextKeyService: IContextKeyService, + xtermCtor: Promise, @IConfigurationService configurationService: IConfigurationService, - @IKeybindingService private readonly _keybindingService: IKeybindingService, @IThemeService private readonly _themeService: IThemeService, ) { super(); @@ -80,7 +71,7 @@ export class TerminalStickyScrollOverlay extends Disposable { })); // Eagerly create the overlay - TerminalInstance.getXtermConstructor(this._keybindingService, this._contextKeyService).then(ctor => { + xtermCtor.then(ctor => { this._stickyScrollOverlay = this._register(new ctor({ rows: 1, cols: this._xterm.raw.cols, @@ -277,9 +268,6 @@ export class TerminalStickyScrollOverlay extends Disposable { private _getOptions(): ITerminalOptions { const o = this._xterm.raw.options; const theme = this._themeService.getColorTheme(); - const terminalBackground = theme.getColor(terminalStickyScrollBackground) || theme.getColor(TERMINAL_BACKGROUND_COLOR) || ( - theme.getColor(this._instance.target === TerminalLocation.Editor ? editorBackground : PANEL_BACKGROUND) - ); return { cursorInactiveStyle: 'none', scrollback: 0, @@ -288,7 +276,7 @@ export class TerminalStickyScrollOverlay extends Disposable { // Selection is used for hover state in the overlay theme: { ...this._xterm.getXtermTheme(), - background: terminalBackground?.toString(), + background: this._xtermColorProvider.getBackgroundColor(theme)?.toString(), selectionBackground: theme.getColor(terminalStickyScrollHoverBackground)?.toString(), selectionInactiveBackground: undefined }, From aafaa65df0160f36d3325dd1b1b82666546164b9 Mon Sep 17 00:00:00 2001 From: Justin Chen <54879025+justschen@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:53:50 -0800 Subject: [PATCH 093/240] Fix Quick Fix Copilot sorting (#197684) added ai sorting --- src/vs/editor/contrib/codeAction/browser/codeActionModel.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts index c9c02e6f298..4f785a850c1 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts @@ -269,6 +269,10 @@ export class CodeActionModel extends Disposable { return -1; } else if (!a.action.isPreferred && b.action.isPreferred) { return 1; + } else if (a.action.isAI && !b.action.isAI) { + return 1; + } else if (!a.action.isAI && b.action.isAI) { + return -1; } else { return 0; } From fff2eae109719f78c4fcd7d5ad480e0ebe1f5285 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 7 Nov 2023 16:45:26 -0700 Subject: [PATCH 094/240] Do a pass on chatAgents2 docs (#197688) #197687 --- .../vscode.proposed.chatAgents2.d.ts | 86 +++++++++++++++++-- 1 file changed, 79 insertions(+), 7 deletions(-) diff --git a/src/vscode-dts/vscode.proposed.chatAgents2.d.ts b/src/vscode-dts/vscode.proposed.chatAgents2.d.ts index d81ebcf66c5..31d7ce0058f 100644 --- a/src/vscode-dts/vscode.proposed.chatAgents2.d.ts +++ b/src/vscode-dts/vscode.proposed.chatAgents2.d.ts @@ -12,23 +12,68 @@ declare module 'vscode' { history: ChatMessage[]; } + /** + * Represents an error result from a chat request. + */ export interface ChatAgentErrorDetails { + /** + * An error message that is shown to the user. + */ message: string; + + /** + * If partial markdown content was sent over the `progress` callback before the response terminated, then this flag + * can be set to true and it will be rendered with incomplete markdown features patched up. + * + * For example, if the response terminated after sending part of a triple-backtick code block, then the editor will + * render it as a complete code block. + */ responseIsIncomplete?: boolean; + + /** + * If set to true, the response will be partly blurred out. + */ responseIsFiltered?: boolean; } + /** + * The result of a chat request. + */ export interface ChatAgentResult2 { + /** + * If the request resulted in an error, this property defines the error details. + */ errorDetails?: ChatAgentErrorDetails; } + /** + * Represents the type of user feedback received. + */ export enum ChatAgentResultFeedbackKind { + /** + * The user marked the result as helpful. + */ Unhelpful = 0, + + /** + * The user marked the result as unhelpful. + */ Helpful = 1, } + /** + * Represents user feedback for a result. + */ export interface ChatAgentResult2Feedback { + /** + * This instance of ChatAgentResult2 is the same instance that was returned from the chat agent, + * and it can be extended with arbitrary properties if needed. + */ readonly result: ChatAgentResult2; + + /** + * The kind of feedback that was received. + */ readonly kind: ChatAgentResultFeedbackKind; } @@ -36,6 +81,8 @@ declare module 'vscode' { /** * A short name by which this command is referred to in the UI, e.g. `fix` or * `explain` for commands that fix an issue or explain code. + * + * **Note**: The name should be unique among the slash commands provided by this agent. */ readonly name: string; @@ -62,7 +109,7 @@ declare module 'vscode' { /** * Returns a list of slash commands that its agent is capable of handling. A slash command - * and be selected by the user and will then be passed to the {@link ChatAgentHandler handler} + * can be selected by the user and will then be passed to the {@link ChatAgentHandler handler} * via the {@link ChatAgentRequest.slashCommand slashCommand} property. * * @@ -73,7 +120,7 @@ declare module 'vscode' { provideSlashCommands(token: CancellationToken): ProviderResult; } - // TODO@API is this just a vscode.Command? + // TODO@API This should become a progress type, and use vscode.Command // TODO@API what's the when-property for? how about not returning it in the first place? export interface ChatAgentCommandFollowup { commandId: string; @@ -82,27 +129,49 @@ declare module 'vscode' { when?: string; } + /** + * A followup question suggested by the model. + */ export interface ChatAgentReplyFollowup { + /** + * The message to send to the chat. + */ message: string; + + /** + * A tooltip to show when hovering over the followup. + */ tooltip?: string; + + /** + * A title to show the user, when it is different than the message. + */ title?: string; } export type ChatAgentFollowup = ChatAgentCommandFollowup | ChatAgentReplyFollowup; + /** + * Will be invoked once after each request to get suggested followup questions to show the user. The user can click the followup to send it to the chat. + */ export interface FollowupProvider { + /** + * + * @param result The same instance of the result object that was returned by the chat agent, and it can be extended with arbitrary properties if needed. + * @param token A cancellation token. + */ provideFollowups(result: ChatAgentResult2, token: CancellationToken): ProviderResult; } export interface ChatAgent2 { /** - * The short name by which this agent is referred to in the UI, e.g `workspace` + * The short name by which this agent is referred to in the UI, e.g `workspace`. */ readonly name: string; /** - * The full name of this agent + * The full name of this agent. */ fullName: string; @@ -125,8 +194,14 @@ declare module 'vscode' { dark: Uri; } | ThemeIcon; + /** + * This provider will be called to retrieve the agent's slash commands. + */ slashCommandProvider?: ChatAgentSlashCommandProvider; + /** + * This provider will be called once after each request to retrieve suggested followup questions. + */ followupProvider?: FollowupProvider; /** @@ -138,9 +213,6 @@ declare module 'vscode' { */ onDidReceiveFeedback: Event; - // TODO@API Something like prepareSession from the interactive chat provider might be needed.Probably nobody needs it right now. - // prepareSession(); - /** * TODO@API explain what happens wrt to history, in-flight requests etc... * Dispose this agent and free resources From 0f8d9033b462c22e23f8884a9fcd44403869fa18 Mon Sep 17 00:00:00 2001 From: Justin Chen <54879025+justschen@users.noreply.github.com> Date: Tue, 7 Nov 2023 16:21:32 -0800 Subject: [PATCH 095/240] fix: no code actions for Nearby Quick Fixes (#197691) * double checks if provider provides code actions * better check for if we need to add new actions --- .../editor/contrib/codeAction/browser/codeActionModel.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts index 4f785a850c1..f785fd21e02 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts @@ -210,7 +210,7 @@ export class CodeActionModel extends Disposable { const actions = createCancelablePromise(async token => { if (this._settingEnabledNearbyQuickfixes() && trigger.trigger.type === CodeActionTriggerType.Invoke && (trigger.trigger.triggerAction === CodeActionTriggerSource.QuickFix || trigger.trigger.filter?.include?.contains(CodeActionKind.QuickFix))) { const codeActionSet = await getCodeActions(this._registry, model, trigger.selection, trigger.trigger, Progress.None, token); - + const allCodeActions = [...codeActionSet.allActions]; if (token.isCancellationRequested) { return emptyCodeActionSet; } @@ -251,6 +251,11 @@ export class CodeActionModel extends Disposable { for (const action of actionsAtMarker.validActions) { action.highlightRange = action.action.isPreferred; } + + if (codeActionSet.allActions.length === 0) { + allCodeActions.push(...actionsAtMarker.allActions); + } + // Already filtered through to only get quickfixes, so no need to filter again. if (Math.abs(currPosition.column - col) < distance) { currentActions.unshift(...actionsAtMarker.validActions); @@ -279,7 +284,7 @@ export class CodeActionModel extends Disposable { }); // Only retriggers if actually found quickfix on the same line as cursor - return { validActions: filteredActions, allActions: codeActionSet.allActions, documentation: codeActionSet.documentation, hasAutoFix: codeActionSet.hasAutoFix, dispose: () => { codeActionSet.dispose(); } }; + return { validActions: filteredActions, allActions: allCodeActions, documentation: codeActionSet.documentation, hasAutoFix: codeActionSet.hasAutoFix, dispose: () => { codeActionSet.dispose(); } }; } } } From 7771124ebd6b7f6e60da14d744961b717b73282f Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 7 Nov 2023 16:23:48 -0800 Subject: [PATCH 096/240] cli: add tcpConnect exec server command, add proposed methods to .d.ts (#197692) --- cli/src/tunnels/control_server.rs | 29 +++++- cli/src/tunnels/protocol.rs | 7 ++ src/vscode-dts/vscode.proposed.resolvers.d.ts | 99 +++++++++++++++++++ 3 files changed, 132 insertions(+), 3 deletions(-) diff --git a/cli/src/tunnels/control_server.rs b/cli/src/tunnels/control_server.rs index a33b59db32a..5f564494b98 100644 --- a/cli/src/tunnels/control_server.rs +++ b/cli/src/tunnels/control_server.rs @@ -32,6 +32,7 @@ use opentelemetry::KeyValue; use std::collections::HashMap; use std::path::PathBuf; use std::process::Stdio; +use tokio::net::TcpStream; use tokio::pin; use tokio::process::{ChildStderr, ChildStdin}; use tokio_util::codec::Decoder; @@ -55,9 +56,9 @@ use super::protocol::{ ChallengeIssueResponse, ChallengeVerifyParams, ClientRequestMethod, EmptyObject, ForwardParams, ForwardResult, FsReadDirEntry, FsReadDirResponse, FsRenameRequest, FsSinglePathRequest, FsStatResponse, GetEnvResponse, GetHostnameResponse, HttpBodyParams, HttpHeadersParams, - ServeParams, ServerLog, ServerMessageParams, SpawnParams, SpawnResult, SysKillRequest, - SysKillResponse, ToClientRequest, UnforwardParams, UpdateParams, UpdateResult, VersionResponse, - METHOD_CHALLENGE_VERIFY, + NetConnectRequest, ServeParams, ServerLog, ServerMessageParams, SpawnParams, SpawnResult, + SysKillRequest, SysKillResponse, ToClientRequest, UnforwardParams, UpdateParams, UpdateResult, + VersionResponse, METHOD_CHALLENGE_VERIFY, }; use super::server_bridge::ServerBridge; use super::server_multiplexer::ServerMultiplexer; @@ -341,6 +342,14 @@ fn make_socket_rpc( handle_fs_connect(streams.remove(0), p.path).await }, ); + rpc.register_duplex( + "net_connect", + 1, + move |mut streams, n: NetConnectRequest, c| async move { + ensure_auth(&c.auth_state)?; + handle_net_connect(streams.remove(0), n).await + }, + ); rpc.register_async("fs_rm", move |p: FsSinglePathRequest, c| async move { ensure_auth(&c.auth_state)?; handle_fs_remove(p.path).await @@ -896,6 +905,20 @@ async fn handle_fs_write(mut input: DuplexStream, path: String) -> Result Result { + let mut s = TcpStream::connect((req.host, req.port)) + .await + .map_err(|e| wrap(e, "could not connect to address"))?; + + tokio::io::copy_bidirectional(&mut stream, &mut s) + .await + .map_err(|e| wrap(e, "error copying stream data"))?; + + Ok(EmptyObject {}) +} async fn handle_fs_connect( mut stream: DuplexStream, path: String, diff --git a/cli/src/tunnels/protocol.rs b/cli/src/tunnels/protocol.rs index 547ffba82a8..6434faadc39 100644 --- a/cli/src/tunnels/protocol.rs +++ b/cli/src/tunnels/protocol.rs @@ -209,6 +209,13 @@ pub struct FsRenameRequest { pub to_path: String, } +/// Method: `net_connect`. Connects to a port. +#[derive(Deserialize)] +pub struct NetConnectRequest { + pub port: u16, + pub host: String, +} + #[derive(Deserialize, Debug)] pub struct CallServerHttpParams { pub path: String, diff --git a/src/vscode-dts/vscode.proposed.resolvers.d.ts b/src/vscode-dts/vscode.proposed.resolvers.d.ts index 783e23fe049..eaef16c501a 100644 --- a/src/vscode-dts/vscode.proposed.resolvers.d.ts +++ b/src/vscode-dts/vscode.proposed.resolvers.d.ts @@ -191,6 +191,26 @@ declare module 'vscode' { */ env(): Thenable; + /** + * Kills a process with the given ID. + * + * @param processId process ID to kill. + */ + kill(processId: number): Thenable; + + /** + * Connects to the given TCP host/port on the remote. + * + * @param host The hostname or IP to connect to + * @param port The port number to connect to + * @returns a duplex stream, and a promise the resolves when both sides + * have closed. + */ + tcpConnect( + host: string, + port: number, + ): Thenable<{ stream: WriteStream & ReadStream; done: Thenable }>; + /** * Access to the file system of the remote. */ @@ -272,6 +292,85 @@ declare module 'vscode' { * @throws an exception when `path` doesn't exist. */ stat(path: string): Thenable; + + /** + * Recursively creates the given directory on the remote. + * + * @param path The path of the folder to create + * @throws an exception when `path` is a file, or other i/o operations happen + */ + mkdirp(path: string): Thenable; + + /** + * Recursively deletes the given path on the remote. + * + * @param path The path of the file or folder to delete. + * @throws if an i/o error happens during removal. It does not throw if + * the path already does not exist. + */ + rm(path: string): Thenable; + + /** + * Reads the given file from the remote. + * + * @param path The path of the file to read. + * @throws if the path doesn't exist or can't be accessed + * @returns a readable stream of the file data + */ + read(path: string): Thenable; + + /** + * Writes the given file on the remote. Truncates the file if it exists. + * + * @param path The path of the file to write. + * @throws if the path can't be accessed + * @returns a writable `stream` that accepts data, and a `done` promise that + * will resolve after `stream.end()` is called once the write is complete. + */ + write(path: string): Thenable<{ stream: WriteStream; done: Thenable }>; + + /** + * Connects to the given unix socket or named pipe on the remote. + * + * @param path The path of the unix socket or named pipe + * @throws if the path can't be accessed + * @returns a duplex stream, and a promise the resolves when both sides + * have closed. + */ + connect(path: string): Thenable<{ stream: WriteStream & ReadStream; done: Thenable }>; + + /** + * Renames the file. + * + * @param fromPath The existing file path. + * @param toPath The new file path. + * @throws if the original path doesn't exist, or the toPath can't be accessed + */ + rename(fromPath: string, toPath: string): Thenable; + + /** + * Reads the contents of a directory. + * + * @param path The path of the folder to read. + * @throws if the folder doesn't exist + * @returns a list of directory entries + */ + readdir(path: string): Thenable; + } + + export interface DirectoryEntry { + /** + * The type of the file, e.g. is a regular file, a directory, or symbolic link + * to a file. + * + * *Note:* This value might be a bitmask, e.g. `FileType.File | FileType.SymbolicLink`. + */ + type: FileType; + + /** + * Non-absolute name of the file in the directory. + */ + name: string; } export interface RemoteAuthorityResolver { From c90951b147164bb427d08f2c251666d5610076d3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 8 Nov 2023 08:39:04 +0100 Subject: [PATCH 097/240] aux window - less global `document` usages (#197701) * aux window - less global `document` usages * aux window - less global `document` usages * aux window - less global `document` usages --- .eslintrc.json | 184 ++++++++++++++---- src/vs/amdX.ts | 3 +- src/vs/base/browser/dom.ts | 20 +- .../browser/formattedTextRenderer.test.ts | 6 +- src/vs/base/test/browser/progressBar.test.ts | 5 +- src/vs/code/browser/workbench/workbench.ts | 6 +- .../issue/issueReporterMain.ts | 7 +- .../issue/issueReporterService.ts | 44 ++--- .../processExplorer/processExplorerMain.ts | 12 +- src/vs/css.ts | 6 +- .../editor/browser/config/charWidthReader.ts | 5 +- .../browser/controller/textAreaHandler.ts | 10 +- .../browser/view/domLineBreaksComputer.ts | 5 +- .../browser/standaloneCodeEditor.ts | 3 +- .../standalone/browser/standaloneEditor.ts | 5 +- .../standalone/browser/standaloneServices.ts | 2 +- .../test/browser/controller/imeRecorder.ts | 7 +- .../test/browser/controller/imeTester.ts | 3 +- .../test/browser/quickinput.test.ts | 5 +- src/vs/workbench/browser/layout.ts | 6 +- .../parts/notifications/notificationsList.ts | 4 +- src/vs/workbench/browser/style.ts | 3 +- src/vs/workbench/browser/window.ts | 4 +- src/vs/workbench/browser/workbench.ts | 4 +- .../electron-sandbox/inputClipboardActions.ts | 3 +- .../electron-sandbox/selectionClipboard.ts | 3 +- .../files/browser/views/explorerViewer.ts | 2 +- .../browser/languageStatus.contribution.ts | 7 +- .../contrib/clipboard/notebookClipboard.ts | 3 +- .../view/renderers/backLayerWebView.ts | 3 +- .../browser/view/renderers/webviewPreloads.ts | 68 +++---- .../preferences/browser/settingsEditor2.ts | 3 +- .../contrib/splash/browser/partsSplash.ts | 6 +- .../terminal/browser/terminalService.ts | 3 +- .../terminal/browser/xterm/xtermTerminal.ts | 6 +- .../test/browser/terminalConfigHelper.test.ts | 3 +- .../webview/browser/webview.contribution.ts | 3 +- .../contrib/webview/browser/webviewElement.ts | 4 +- .../electron-sandbox/webviewCommands.ts | 3 +- .../browser/gettingStarted.ts | 5 +- .../electron-sandbox/desktop.main.ts | 2 +- .../browser/auxiliaryWindowService.ts | 10 +- .../dialogs/browser/simpleFileDialog.ts | 5 +- .../services/driver/browser/driver.ts | 18 +- .../builtinExtensionsScannerService.ts | 3 +- .../storage/browser/storageService.ts | 3 +- .../themes/browser/workbenchThemeService.ts | 3 +- src/vs/workbench/test/browser/part.test.ts | 19 +- 48 files changed, 345 insertions(+), 202 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index c24488ff1d7..13f8b065618 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -699,6 +699,118 @@ { "selector": "BinaryExpression[operator='instanceof'][right.name='DragEvent']", "message": "Use DOM.isDragEvent() to support multi-window scenarios." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='activeElement']", + "message": "Use .document.activeElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='styleSheets']", + "message": "Use .document.styleSheets to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='fullscreenElement']", + "message": "Use .document.fullscreenElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='body']", + "message": "Use .document.body to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='addEventListener']", + "message": "Use .document.addEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='removeEventListener']", + "message": "Use .document.removeEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='hasFocus']", + "message": "Use .document.hasFocus to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='head']", + "message": "Use .document.head to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='exitFullscreen']", + "message": "Use .document.exitFullscreen to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='getElementById']", + "message": "Use .document.getElementById to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='getElementsByClassName']", + "message": "Use .document.getElementsByClassName to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='getElementsByName']", + "message": "Use .document.getElementsByName to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='getElementsByTagName']", + "message": "Use .document.getElementsByTagName to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='getElementsByTagNameNS']", + "message": "Use .document.getElementsByTagNameNS to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='getSelection']", + "message": "Use .document.getSelection to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='open']", + "message": "Use .document.open to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='close']", + "message": "Use .document.close to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='documentElement']", + "message": "Use .document.documentElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='visibilityState']", + "message": "Use .document.visibilityState to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='querySelector']", + "message": "Use .document.querySelector to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='querySelectorAll']", + "message": "Use .document.querySelectorAll to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='elementFromPoint']", + "message": "Use .document.elementFromPoint to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='elementsFromPoint']", + "message": "Use .document.elementsFromPoint to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='onkeydown']", + "message": "Use .document.onkeydown to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='onkeyup']", + "message": "Use .document.onkeyup to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='onmousedown']", + "message": "Use .document.onmousedown to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='onmouseup']", + "message": "Use .document.onmouseup to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." + }, + { + "selector": "MemberExpression[object.name='document'][property.name='execCommand']", + "message": "Use .document.execCommand to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." } ], "no-restricted-globals": [ @@ -714,147 +826,147 @@ "context", { "name": "requestAnimationFrame", - "message": "Use .requestAnimationFrame to support multi-window scenarios." + "message": "Use .requestAnimationFrame to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "cancelAnimationFrame", - "message": "Use .cancelAnimationFrame to support multi-window scenarios." + "message": "Use .cancelAnimationFrame to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "requestIdleCallback", - "message": "Use .requestIdleCallback to support multi-window scenarios." + "message": "Use .requestIdleCallback to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "cancelIdleCallback", - "message": "Use .cancelIdleCallback to support multi-window scenarios." + "message": "Use .cancelIdleCallback to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "window", - "message": "Be aware of multi-window scenarios: Use DOM.getWindow() or DOM.getActiveWindow() to obtain the correct window for the context you are in. Only use window.ts#mainWindow if you target the main window." + "message": "Use to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "addEventListener", - "message": "Use .addEventListener to support multi-window scenarios." + "message": "Use .addEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "removeEventListener", - "message": "Use .removeEventListener to support multi-window scenarios." + "message": "Use .removeEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "getComputedStyle", - "message": "Use .getComputedStyle to support multi-window scenarios." + "message": "Use .getComputedStyle to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "focus", - "message": "Use .focus to support multi-window scenarios." + "message": "Use .focus to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "blur", - "message": "Use .blur to support multi-window scenarios." + "message": "Use .blur to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "close", - "message": "Use .close to support multi-window scenarios." + "message": "Use .close to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "dispatchEvent", - "message": "Use .dispatchEvent to support multi-window scenarios." + "message": "Use .dispatchEvent to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "getSelection", - "message": "Use .getSelection to support multi-window scenarios." + "message": "Use .getSelection to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "matchMedia", - "message": "Use .matchMedia to support multi-window scenarios." + "message": "Use .matchMedia to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "open", - "message": "Use .open to support multi-window scenarios." + "message": "Use .open to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "parent", - "message": "Use .parent to support multi-window scenarios." + "message": "Use .parent to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "postMessage", - "message": "Use .postMessage to support multi-window scenarios." + "message": "Use .postMessage to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "devicePixelRatio", - "message": "Use .devicePixelRatio to support multi-window scenarios." + "message": "Use .devicePixelRatio to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "frames", - "message": "Use .frames to support multi-window scenarios." + "message": "Use .frames to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "frameElement", - "message": "Use .frameElement to support multi-window scenarios." + "message": "Use .frameElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "innerHeight", - "message": "Use .innerHeight to support multi-window scenarios." + "message": "Use .innerHeight to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "innerWidth", - "message": "Use .innerWidth to support multi-window scenarios." + "message": "Use .innerWidth to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "outerHeight", - "message": "Use .outerHeight to support multi-window scenarios." + "message": "Use .outerHeight to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "outerWidth", - "message": "Use .outerWidth to support multi-window scenarios." + "message": "Use .outerWidth to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "length", - "message": "Use .length to support multi-window scenarios." + "message": "Use .length to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "opener", - "message": "Use .opener to support multi-window scenarios." + "message": "Use .opener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "origin", - "message": "Use .origin to support multi-window scenarios." + "message": "Use .origin to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "screen", - "message": "Use .screen to support multi-window scenarios." + "message": "Use .screen to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "screenLeft", - "message": "Use .screenLeft to support multi-window scenarios." + "message": "Use .screenLeft to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "screenTop", - "message": "Use .screenTop to support multi-window scenarios." + "message": "Use .screenTop to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "screenX", - "message": "Use .screenX to support multi-window scenarios." + "message": "Use .screenX to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "screenY", - "message": "Use .screenY to support multi-window scenarios." + "message": "Use .screenY to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "scrollX", - "message": "Use .scrollX to support multi-window scenarios." + "message": "Use .scrollX to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "scrollY", - "message": "Use .scrollY to support multi-window scenarios." + "message": "Use .scrollY to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "top", - "message": "Use .top to support multi-window scenarios." + "message": "Use .top to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." }, { "name": "visualViewport", - "message": "Use .visualViewport to support multi-window scenarios." + "message": "Use .visualViewport to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant." } ] } diff --git a/src/vs/amdX.ts b/src/vs/amdX.ts index 03460284b21..ba164787d2e 100644 --- a/src/vs/amdX.ts +++ b/src/vs/amdX.ts @@ -123,7 +123,8 @@ class AMDModuleImporter { scriptSrc = this._amdPolicy.createScriptURL(scriptSrc) as any as string; } scriptElement.setAttribute('src', scriptSrc); - document.getElementsByTagName('head')[0].appendChild(scriptElement); + // eslint-disable-next-line no-restricted-globals + window.document.getElementsByTagName('head')[0].appendChild(scriptElement); }); } diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 2d0d87a1448..aba7dd5a987 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -794,7 +794,7 @@ export function getActiveDocument(): Document { } const documents = Array.from(getWindows()).map(({ window }) => window.document); - return documents.find(document => document.hasFocus()) ?? document; + return documents.find(doc => doc.hasFocus()) ?? document; } export function getActiveWindow(): CodeWindow { @@ -831,7 +831,7 @@ export function isGlobalStylesheet(node: Node): boolean { return globalStylesheets.has(node as HTMLStyleElement); } -export function createStyleSheet(container: HTMLElement = document.head, beforeAppend?: (style: HTMLStyleElement) => void, disposableStore?: DisposableStore): HTMLStyleElement { +export function createStyleSheet(container: HTMLElement = mainWindow.document.head, beforeAppend?: (style: HTMLStyleElement) => void, disposableStore?: DisposableStore): HTMLStyleElement { const style = document.createElement('style'); style.type = 'text/css'; style.media = 'screen'; @@ -844,7 +844,7 @@ export function createStyleSheet(container: HTMLElement = document.head, beforeA // With as container, the stylesheet becomes global and is tracked // to support auxiliary windows to clone the stylesheet. - if (container === document.head) { + if (container === mainWindow.document.head) { const globalStylesheetClones = new Set(); globalStylesheets.set(style, globalStylesheetClones); @@ -945,7 +945,7 @@ export const sharedMutationObserver = new class { } }; -export function createMetaElement(container: HTMLElement = document.head): HTMLMetaElement { +export function createMetaElement(container: HTMLElement = mainWindow.document.head): HTMLMetaElement { const meta = document.createElement('meta'); container.appendChild(meta); return meta; @@ -1547,14 +1547,15 @@ export function triggerDownload(dataOrUri: Uint8Array | URI, name: string): void // to be creating a element with download attribute that // points to the file to download. // See also https://developers.google.com/web/updates/2011/08/Downloading-resources-in-HTML5-a-download + const activeWindow = getActiveWindow(); const anchor = document.createElement('a'); - document.body.appendChild(anchor); + activeWindow.document.body.appendChild(anchor); anchor.download = name; anchor.href = url; anchor.click(); // Ensure to remove the element from DOM eventually - setTimeout(() => document.body.removeChild(anchor)); + setTimeout(() => activeWindow.document.body.removeChild(anchor)); } export function triggerUpload(): Promise { @@ -1563,8 +1564,9 @@ export function triggerUpload(): Promise { // In order to upload to the browser, create a // input element of type `file` and click it // to gather the selected files + const activeWindow = getActiveWindow(); const input = document.createElement('input'); - document.body.appendChild(input); + activeWindow.document.body.appendChild(input); input.type = 'file'; input.multiple = true; @@ -1576,7 +1578,7 @@ export function triggerUpload(): Promise { input.click(); // Ensure to remove the element from DOM eventually - setTimeout(() => document.body.removeChild(input)); + setTimeout(() => activeWindow.document.body.removeChild(input)); }); } @@ -1612,7 +1614,7 @@ export interface IDetectedFullscreen { export function detectFullscreen(): IDetectedFullscreen | null { // Browser fullscreen: use DOM APIs to detect - if (document.fullscreenElement || (document).webkitFullscreenElement || (document).webkitIsFullScreen) { + if ($window.document.fullscreenElement || ($window.document).webkitFullscreenElement || ($window.document).webkitIsFullScreen) { return { mode: DetectedFullscreenMode.DOCUMENT, guess: false }; } diff --git a/src/vs/base/test/browser/formattedTextRenderer.test.ts b/src/vs/base/test/browser/formattedTextRenderer.test.ts index f12ca3222ee..f5bcc1b2d5d 100644 --- a/src/vs/base/test/browser/formattedTextRenderer.test.ts +++ b/src/vs/base/test/browser/formattedTextRenderer.test.ts @@ -77,7 +77,7 @@ suite('FormattedTextRenderer', () => { }); assert.strictEqual(result.innerHTML, 'action'); - const event: MouseEvent = document.createEvent('MouseEvent'); + const event: MouseEvent = document.createEvent('MouseEvent'); event.initEvent('click', true, true); result.firstChild!.dispatchEvent(event); assert.strictEqual(callbackCalled, true); @@ -96,7 +96,7 @@ suite('FormattedTextRenderer', () => { }); assert.strictEqual(result.innerHTML, 'action'); - const event: MouseEvent = document.createEvent('MouseEvent'); + const event: MouseEvent = document.createEvent('MouseEvent'); event.initEvent('click', true, true); result.firstChild!.firstChild!.firstChild!.dispatchEvent(event); assert.strictEqual(callbackCalled, true); @@ -116,7 +116,7 @@ suite('FormattedTextRenderer', () => { }); assert.strictEqual(result.innerHTML, 'action'); - const event: MouseEvent = document.createEvent('MouseEvent'); + const event: MouseEvent = document.createEvent('MouseEvent'); event.initEvent('click', true, true); result.firstChild!.firstChild!.firstChild!.firstChild!.dispatchEvent(event); assert.strictEqual(callbackCalled, true); diff --git a/src/vs/base/test/browser/progressBar.test.ts b/src/vs/base/test/browser/progressBar.test.ts index eb9790cd6ce..9620ae31948 100644 --- a/src/vs/base/test/browser/progressBar.test.ts +++ b/src/vs/base/test/browser/progressBar.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar'; +import { mainWindow } from 'vs/base/browser/window'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('ProgressBar', () => { @@ -12,11 +13,11 @@ suite('ProgressBar', () => { setup(() => { fixture = document.createElement('div'); - document.body.appendChild(fixture); + mainWindow.document.body.appendChild(fixture); }); teardown(() => { - document.body.removeChild(fixture); + mainWindow.document.body.removeChild(fixture); }); test('Progress Bar', function () { diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts index 0a6b1d6d4e9..dee15a5f132 100644 --- a/src/vs/code/browser/workbench/workbench.ts +++ b/src/vs/code/browser/workbench/workbench.ts @@ -197,7 +197,7 @@ export class LocalStorageSecretStorageProvider implements ISecretStorageProvider private loadAuthSessionFromElement(): Record { let authSessionInfo: (AuthenticationSessionInfo & { scopes: string[][] }) | undefined; - const authSessionElement = document.getElementById('vscode-workbench-auth-session'); + const authSessionElement = mainWindow.document.getElementById('vscode-workbench-auth-session'); const authSessionElementAttribute = authSessionElement ? authSessionElement.getAttribute('data-settings') : undefined; if (authSessionElementAttribute) { try { @@ -565,7 +565,7 @@ function readCookie(name: string): string | undefined { (function () { // Find config by checking for DOM - const configElement = document.getElementById('vscode-workbench-web-configuration'); + const configElement = mainWindow.document.getElementById('vscode-workbench-web-configuration'); const configElementAttribute = configElement ? configElement.getAttribute('data-settings') : undefined; if (!configElement || !configElementAttribute) { throw new Error('Missing web configuration element'); @@ -576,7 +576,7 @@ function readCookie(name: string): string | undefined { ? new ServerKeyedAESCrypto(secretStorageKeyPath) : new TransparentCrypto(); // Create workbench - create(document.body, { + create(mainWindow.document.body, { ...config, windowIndicator: config.windowIndicator ?? { label: '$(remote)', tooltip: `${product.nameShort} Web` }, settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined, diff --git a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts index ebefca402ea..2cbe4b0f8d2 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts @@ -19,18 +19,19 @@ import { IIssueMainService, IssueReporterWindowConfiguration } from 'vs/platform import { INativeHostService } from 'vs/platform/native/common/native'; import { NativeHostService } from 'vs/platform/native/common/nativeHostService'; import { IssueReporter } from './issueReporterService'; +import { mainWindow } from 'vs/base/browser/window'; export function startup(configuration: IssueReporterWindowConfiguration) { const platformClass = isWindows ? 'windows' : isLinux ? 'linux' : 'mac'; - document.body.classList.add(platformClass); // used by our fonts + mainWindow.document.body.classList.add(platformClass); // used by our fonts - safeInnerHtml(document.body, BaseHtml()); + safeInnerHtml(mainWindow.document.body, BaseHtml()); const instantiationService = initServices(configuration.windowId); const issueReporter = instantiationService.createInstance(IssueReporter, configuration); issueReporter.render(); - document.body.style.display = 'block'; + mainWindow.document.body.style.display = 'block'; issueReporter.setInitialFocus(); } diff --git a/src/vs/code/electron-sandbox/issue/issueReporterService.ts b/src/vs/code/electron-sandbox/issue/issueReporterService.ts index 58761964f6a..0f6d705f16a 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterService.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterService.ts @@ -142,10 +142,10 @@ export class IssueReporter extends Disposable { setInitialFocus() { const { fileOnExtension } = this.issueReporterModel.getData(); if (fileOnExtension) { - const issueTitle = document.getElementById('issue-title'); + const issueTitle = mainWindow.document.getElementById('issue-title'); issueTitle?.focus(); } else { - const issueType = document.getElementById('issue-type'); + const issueType = mainWindow.document.getElementById('issue-type'); issueType?.focus(); } } @@ -222,8 +222,8 @@ export class IssueReporter extends Disposable { } styleTag.textContent = content.join('\n'); - document.head.appendChild(styleTag); - document.body.style.color = styles.color || ''; + mainWindow.document.head.appendChild(styleTag); + mainWindow.document.body.style.color = styles.color || ''; } private handleExtensionData(extensions: IssueReporterExtensionData[]) { @@ -299,7 +299,7 @@ export class IssueReporter extends Disposable { }); }); - const showInfoElements = document.getElementsByClassName('showInfo'); + const showInfoElements = mainWindow.document.getElementsByClassName('showInfo'); for (let i = 0; i < showInfoElements.length; i++) { const showInfo = showInfoElements.item(i)!; (showInfo as HTMLAnchorElement).addEventListener('click', (e: MouseEvent) => { @@ -397,7 +397,7 @@ export class IssueReporter extends Disposable { } }); - document.onkeydown = async (e: KeyboardEvent) => { + mainWindow.document.onkeydown = async (e: KeyboardEvent) => { const cmdOrCtrlKey = isMacintosh ? e.metaKey : e.ctrlKey; // Cmd/Ctrl+Enter previews issue and closes window if (cmdOrCtrlKey && e.keyCode === 13) { @@ -739,12 +739,12 @@ export class IssueReporter extends Disposable { // Depending on Issue Type, we render different blocks and text const { issueType, fileOnExtension, fileOnMarketplace, selectedExtension } = this.issueReporterModel.getData(); const blockContainer = this.getElementById('block-container'); - const systemBlock = document.querySelector('.block-system'); - const processBlock = document.querySelector('.block-process'); - const workspaceBlock = document.querySelector('.block-workspace'); - const extensionsBlock = document.querySelector('.block-extensions'); - const experimentsBlock = document.querySelector('.block-experiments'); - const extensionDataBlock = document.querySelector('.block-extension-data'); + const systemBlock = mainWindow.document.querySelector('.block-system'); + const processBlock = mainWindow.document.querySelector('.block-process'); + const workspaceBlock = mainWindow.document.querySelector('.block-workspace'); + const extensionsBlock = mainWindow.document.querySelector('.block-extensions'); + const experimentsBlock = mainWindow.document.querySelector('.block-experiments'); + const extensionDataBlock = mainWindow.document.querySelector('.block-extension-data'); const problemSource = this.getElementById('problem-source')!; const descriptionTitle = this.getElementById('issue-description-label')!; @@ -893,7 +893,7 @@ export class IssueReporter extends Disposable { if (!this.validateInputs()) { // If inputs are invalid, set focus to the first one and add listeners on them // to detect further changes - const invalidInput = document.getElementsByClassName('invalid-input'); + const invalidInput = mainWindow.document.getElementsByClassName('invalid-input'); if (invalidInput.length) { (invalidInput[0]).focus(); } @@ -1002,7 +1002,7 @@ export class IssueReporter extends Disposable { } private updateSystemInfo(state: IssueReporterModelData) { - const target = document.querySelector('.block-system .block-info'); + const target = mainWindow.document.querySelector('.block-system .block-info'); if (target) { const systemInfo = state.systemInfo!; @@ -1143,7 +1143,7 @@ export class IssueReporter extends Disposable { (descriptionTextArea as HTMLTextAreaElement).value = fullTextArea; this.issueReporterModel.update({ issueDescription: fullTextArea }); } - const extensionDataBlock = document.querySelector('.block-extension-data')!; + const extensionDataBlock = mainWindow.document.querySelector('.block-extension-data')!; show(extensionDataBlock); // Start loading for extension data. @@ -1202,7 +1202,7 @@ export class IssueReporter extends Disposable { const extensionDataCaption = this.getElementById('extension-id')!; hide(extensionDataCaption); - const extensionDataCaption2 = Array.from(document.querySelectorAll('.ext-parens')); + const extensionDataCaption2 = Array.from(mainWindow.document.querySelectorAll('.ext-parens')); extensionDataCaption2.forEach(extensionDataCaption2 => hide(extensionDataCaption2)); const showLoading = this.getElementById('ext-loading')!; @@ -1216,7 +1216,7 @@ export class IssueReporter extends Disposable { const extensionDataCaption = this.getElementById('extension-id')!; show(extensionDataCaption); - const extensionDataCaption2 = Array.from(document.querySelectorAll('.ext-parens')); + const extensionDataCaption2 = Array.from(mainWindow.document.querySelectorAll('.ext-parens')); extensionDataCaption2.forEach(extensionDataCaption2 => show(extensionDataCaption2)); const hideLoading = this.getElementById('ext-loading')!; @@ -1247,18 +1247,18 @@ export class IssueReporter extends Disposable { } private updateProcessInfo(state: IssueReporterModelData) { - const target = document.querySelector('.block-process .block-info') as HTMLElement; + const target = mainWindow.document.querySelector('.block-process .block-info') as HTMLElement; if (target) { reset(target, $('code', undefined, state.processInfo ?? '')); } } private updateWorkspaceInfo(state: IssueReporterModelData) { - document.querySelector('.block-workspace .block-info code')!.textContent = '\n' + state.workspaceInfo; + mainWindow.document.querySelector('.block-workspace .block-info code')!.textContent = '\n' + state.workspaceInfo; } private updateExtensionTable(extensions: IssueReporterExtensionData[], numThemeExtensions: number): void { - const target = document.querySelector('.block-extensions .block-info'); + const target = mainWindow.document.querySelector('.block-extensions .block-info'); if (target) { if (this.configuration.disableExtensions) { reset(target, localize('disabledExtensions', "Extensions are disabled")); @@ -1287,7 +1287,7 @@ export class IssueReporter extends Disposable { private updateExperimentsInfo(experimentInfo: string | undefined) { this.issueReporterModel.update({ experimentInfo }); - const target = document.querySelector('.block-experiments .block-info'); + const target = mainWindow.document.querySelector('.block-experiments .block-info'); if (target) { target.textContent = experimentInfo ? experimentInfo : localize('noCurrentExperiments', "No current experiments."); } @@ -1318,7 +1318,7 @@ export class IssueReporter extends Disposable { } private getElementById(elementId: string): T | undefined { - const element = document.getElementById(elementId) as T | undefined; + const element = mainWindow.document.getElementById(elementId) as T | undefined; if (element) { return element; } else { diff --git a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts index 1d5a3567fd8..522c418ffaa 100644 --- a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts @@ -275,7 +275,7 @@ class ProcessExplorer { } private setEventHandlers(data: ProcessExplorerData): void { - document.onkeydown = (e: KeyboardEvent) => { + mainWindow.document.onkeydown = (e: KeyboardEvent) => { const cmdOrCtrlKey = data.platform === 'darwin' ? e.metaKey : e.ctrlKey; // Cmd/Ctrl + w closes issue window @@ -299,7 +299,7 @@ class ProcessExplorer { } private async createProcessTree(processRoots: MachineProcessInformation[]): Promise { - const container = document.getElementById('process-list'); + const container = mainWindow.document.getElementById('process-list'); if (!container) { return; } @@ -477,7 +477,7 @@ class ProcessExplorer { styleElement.textContent = content.join('\n'); if (styles.color) { - document.body.style.color = styles.color; + mainWindow.document.body.style.color = styles.color; } } @@ -517,7 +517,7 @@ class ProcessExplorer { selectionPids.length = 0; selectionPids.push(pid); } - const rows = selectionPids?.map(e => document.getElementById(`pid-${e}`)).filter(e => !!e) as HTMLElement[]; + const rows = selectionPids?.map(e => mainWindow.document.getElementById(`pid-${e}`)).filter(e => !!e) as HTMLElement[]; if (rows) { const text = rows.map(e => e.innerText).filter(e => !!e) as string[]; this.nativeHostService.writeClipboardText(text.join('\n')); @@ -528,7 +528,7 @@ class ProcessExplorer { items.push({ label: localize('copyAll', "Copy All"), click: () => { - const processList = document.getElementById('process-list'); + const processList = mainWindow.document.getElementById('process-list'); if (processList) { this.nativeHostService.writeClipboardText(processList.innerText); } @@ -593,7 +593,7 @@ function createCodiconStyleSheet() { export function startup(configuration: ProcessExplorerWindowConfiguration): void { const platformClass = configuration.data.platform === 'win32' ? 'windows' : configuration.data.platform === 'linux' ? 'linux' : 'mac'; - document.body.classList.add(platformClass); // used by our fonts + mainWindow.document.body.classList.add(platformClass); // used by our fonts createCodiconStyleSheet(); applyZoom(configuration.data.zoomLevel); diff --git a/src/vs/css.ts b/src/vs/css.ts index 5337b4f2136..e142f8dc8b5 100644 --- a/src/vs/css.ts +++ b/src/vs/css.ts @@ -41,7 +41,8 @@ function loadCSS(name: string, cssUrl: string, callback: () => void, errorback: } function linkTagExists(name: string, cssUrl: string): boolean { - const links = document.getElementsByTagName('link'); + // eslint-disable-next-line no-restricted-globals + const links = window.document.getElementsByTagName('link'); for (let i = 0, len = links.length; i < len; i++) { const nameAttr = links[i].getAttribute('data-name'); const hrefAttr = links[i].getAttribute('href'); @@ -61,7 +62,8 @@ function createLinkTag(name: string, cssUrl: string, callback: () => void, error attachListeners(name, linkNode, callback, errorback); linkNode.setAttribute('href', cssUrl); - const head = document.head || document.getElementsByTagName('head')[0]; + // eslint-disable-next-line no-restricted-globals + const head = window.document.head || window.document.getElementsByTagName('head')[0]; head.appendChild(linkNode); } diff --git a/src/vs/editor/browser/config/charWidthReader.ts b/src/vs/editor/browser/config/charWidthReader.ts index 16b6d7d1c48..c2097a6074a 100644 --- a/src/vs/editor/browser/config/charWidthReader.ts +++ b/src/vs/editor/browser/config/charWidthReader.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { $window } from 'vs/base/browser/window'; import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; import { BareFontInfo } from 'vs/editor/common/config/fontInfo'; @@ -50,13 +51,13 @@ class DomCharWidthReader { this._createDomElements(); // Add the container to the DOM - document.body.appendChild(this._container!); + $window.document.body.appendChild(this._container!); // Read character widths this._readFromDomElements(); // Remove the container from the DOM - document.body.removeChild(this._container!); + $window.document.body.removeChild(this._container!); this._container = null; this._testElements = null; diff --git a/src/vs/editor/browser/controller/textAreaHandler.ts b/src/vs/editor/browser/controller/textAreaHandler.ts index 76a007a4cad..e7f16198870 100644 --- a/src/vs/editor/browser/controller/textAreaHandler.ts +++ b/src/vs/editor/browser/controller/textAreaHandler.ts @@ -927,28 +927,28 @@ interface IRenderData { strikethrough?: boolean; } -function measureText(document: Document, text: string, fontInfo: FontInfo, tabSize: number): number { +function measureText(targetDocument: Document, text: string, fontInfo: FontInfo, tabSize: number): number { if (text.length === 0) { return 0; } - const container = document.createElement('div'); + const container = targetDocument.createElement('div'); container.style.position = 'absolute'; container.style.top = '-50000px'; container.style.width = '50000px'; - const regularDomNode = document.createElement('span'); + const regularDomNode = targetDocument.createElement('span'); applyFontInfo(regularDomNode, fontInfo); regularDomNode.style.whiteSpace = 'pre'; // just like the textarea regularDomNode.style.tabSize = `${tabSize * fontInfo.spaceWidth}px`; // just like the textarea regularDomNode.append(text); container.appendChild(regularDomNode); - document.body.appendChild(container); + targetDocument.body.appendChild(container); const res = regularDomNode.offsetWidth; - document.body.removeChild(container); + targetDocument.body.removeChild(container); return res; } diff --git a/src/vs/editor/browser/view/domLineBreaksComputer.ts b/src/vs/editor/browser/view/domLineBreaksComputer.ts index 9aba078cf67..54a0c9be997 100644 --- a/src/vs/editor/browser/view/domLineBreaksComputer.ts +++ b/src/vs/editor/browser/view/domLineBreaksComputer.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { createTrustedTypesPolicy } from 'vs/base/browser/trustedTypes'; +import { $window } from 'vs/base/browser/window'; import { CharCode } from 'vs/base/common/charCode'; import * as strings from 'vs/base/common/strings'; import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; @@ -139,7 +140,7 @@ function createLineBreaks(requests: string[], fontInfo: FontInfo, tabSize: numbe containerDomNode.style.wordBreak = 'inherit'; containerDomNode.style.overflowWrap = 'break-word'; } - document.body.appendChild(containerDomNode); + $window.document.body.appendChild(containerDomNode); const range = document.createRange(); const lineDomNodes = Array.prototype.slice.call(containerDomNode.children, 0); @@ -183,7 +184,7 @@ function createLineBreaks(requests: string[], fontInfo: FontInfo, tabSize: numbe result[i] = new ModelLineProjectionData(injectionOffsets, injectionOptions, breakOffsets, breakOffsetsVisibleColumn, wrappedTextIndentLength); } - document.body.removeChild(containerDomNode); + $window.document.body.removeChild(containerDomNode); return result; } diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts index 4ed5acd6a1d..7ad3d3c44d4 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts @@ -38,6 +38,7 @@ import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfi import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditor/diffEditorWidget'; import { IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; +import { mainWindow } from 'vs/base/browser/window'; /** * Description of an action contribution @@ -252,7 +253,7 @@ function createAriaDomNode(parent: HTMLElement | undefined) { } ariaDomNodeCreated = true; } - aria.setARIAContainer(parent || document.body); + aria.setARIAContainer(parent || mainWindow.document.body); } /** diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index 92cf32cf2d5..c61977fd234 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { mainWindow } from 'vs/base/browser/window'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { splitLines } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; @@ -346,7 +347,7 @@ export function colorizeElement(domNode: HTMLElement, options: IColorizerElement export function colorize(text: string, languageId: string, options: IColorizerOptions): Promise { const languageService = StandaloneServices.get(ILanguageService); const themeService = StandaloneServices.get(IStandaloneThemeService); - themeService.registerEditorContainer(document.body); + themeService.registerEditorContainer(mainWindow.document.body); return Colorizer.colorize(languageService, text, languageId, options); } @@ -355,7 +356,7 @@ export function colorize(text: string, languageId: string, options: IColorizerOp */ export function colorizeModelLine(model: ITextModel, lineNumber: number, tabSize: number = 4): string { const themeService = StandaloneServices.get(IStandaloneThemeService); - themeService.registerEditorContainer(document.body); + themeService.registerEditorContainer(mainWindow.document.body); return Colorizer.colorizeModelLine(model, lineNumber, tabSize); } diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index 1b01cd7d6af..353447e0f34 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -528,7 +528,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService { } protected _documentHasFocus(): boolean { - return document.hasFocus(); + return mainWindow.document.hasFocus(); } private _toNormalizedKeybindingItems(items: IKeybindingItem[], isDefault: boolean): ResolvedKeybindingItem[] { diff --git a/src/vs/editor/test/browser/controller/imeRecorder.ts b/src/vs/editor/test/browser/controller/imeRecorder.ts index e8c6ee7b40e..36290eb2e98 100644 --- a/src/vs/editor/test/browser/controller/imeRecorder.ts +++ b/src/vs/editor/test/browser/controller/imeRecorder.ts @@ -8,11 +8,12 @@ import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { IRecorded, IRecordedCompositionEvent, IRecordedEvent, IRecordedInputEvent, IRecordedKeyboardEvent, IRecordedTextareaState } from 'vs/editor/test/browser/controller/imeRecordedTypes'; import * as browser from 'vs/base/browser/browser'; import * as platform from 'vs/base/common/platform'; +import { mainWindow } from 'vs/base/browser/window'; (() => { - const startButton = document.getElementById('startRecording')!; - const endButton = document.getElementById('endRecording')!; + const startButton = mainWindow.document.getElementById('startRecording')!; + const endButton = mainWindow.document.getElementById('endRecording')!; let inputarea: HTMLTextAreaElement; const disposables = new DisposableStore(); @@ -90,7 +91,7 @@ import * as platform from 'vs/base/common/platform'; function startTest() { inputarea = document.createElement('textarea'); - document.body.appendChild(inputarea); + mainWindow.document.body.appendChild(inputarea); inputarea.focus(); disposables.add(toDisposable(() => { inputarea.remove(); diff --git a/src/vs/editor/test/browser/controller/imeTester.ts b/src/vs/editor/test/browser/controller/imeTester.ts index b44da204b52..25cdbd57c75 100644 --- a/src/vs/editor/test/browser/controller/imeTester.ts +++ b/src/vs/editor/test/browser/controller/imeTester.ts @@ -11,6 +11,7 @@ import { EndOfLinePreference } from 'vs/editor/common/model'; import * as dom from 'vs/base/browser/dom'; import * as browser from 'vs/base/browser/browser'; import * as platform from 'vs/base/common/platform'; +import { mainWindow } from 'vs/base/browser/window'; // To run this test, open imeTester.html @@ -198,5 +199,5 @@ const TESTS = [ ]; TESTS.forEach((t) => { - document.body.appendChild(doCreateTest(t.description, t.in, t.out)); + mainWindow.document.body.appendChild(doCreateTest(t.description, t.in, t.out)); }); diff --git a/src/vs/platform/quickinput/test/browser/quickinput.test.ts b/src/vs/platform/quickinput/test/browser/quickinput.test.ts index 8d54f3cd5af..fdfdc1ffcf4 100644 --- a/src/vs/platform/quickinput/test/browser/quickinput.test.ts +++ b/src/vs/platform/quickinput/test/browser/quickinput.test.ts @@ -17,6 +17,7 @@ import { QuickInputController } from 'vs/platform/quickinput/browser/quickInputC import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { toDisposable } from 'vs/base/common/lifecycle'; +import { mainWindow } from 'vs/base/browser/window'; // Sets up an `onShow` listener to allow us to wait until the quick pick is shown (useful when triggering an `accept()` right after launching a quick pick) // kick this off before you launch the picker and then await the promise returned after you launch the picker. @@ -39,8 +40,8 @@ suite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 setup(() => { const fixture = document.createElement('div'); - document.body.appendChild(fixture); - store.add(toDisposable(() => document.body.removeChild(fixture))); + mainWindow.document.body.appendChild(fixture); + store.add(toDisposable(() => mainWindow.document.body.removeChild(fixture))); controller = store.add(new QuickInputController({ container: fixture, diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 0836557e40a..a74c41bba1b 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -177,13 +177,13 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi return containers; } - private getContainerFromDocument(document: Document): HTMLElement { - if (document === this.container.ownerDocument) { + private getContainerFromDocument(targetDocument: Document): HTMLElement { + if (targetDocument === this.container.ownerDocument) { // main window return this.container; } else { // auxiliary window - return document.body.getElementsByClassName('monaco-workbench')[0] as HTMLElement; + return targetDocument.body.getElementsByClassName('monaco-workbench')[0] as HTMLElement; } } diff --git a/src/vs/workbench/browser/parts/notifications/notificationsList.ts b/src/vs/workbench/browser/parts/notifications/notificationsList.ts index 5ac8c173685..4dad9770b06 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsList.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsList.ts @@ -5,7 +5,7 @@ import 'vs/css!./media/notificationsList'; import { localize } from 'vs/nls'; -import { isAncestorOfActiveElement, trackFocus } from 'vs/base/browser/dom'; +import { getWindow, isAncestorOfActiveElement, trackFocus } from 'vs/base/browser/dom'; import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IListAccessibilityProvider, IListOptions } from 'vs/base/browser/ui/list/listWidget'; @@ -111,7 +111,7 @@ export class NotificationsList extends Disposable { // This ensures that when the focus comes back, the notification is still focused const listFocusTracker = this._register(trackFocus(list.getHTMLElement())); this._register(listFocusTracker.onDidBlur(() => { - if (document.hasFocus()) { + if (getWindow(this.listContainer).document.hasFocus()) { list.setFocus([]); } })); diff --git a/src/vs/workbench/browser/style.ts b/src/vs/workbench/browser/style.ts index d70a5c0e797..23f2e2bac99 100644 --- a/src/vs/workbench/browser/style.ts +++ b/src/vs/workbench/browser/style.ts @@ -10,6 +10,7 @@ import { isWeb, isIOS, isMacintosh, isWindows } from 'vs/base/common/platform'; import { createMetaElement } from 'vs/base/browser/dom'; import { isSafari, isStandalone } from 'vs/base/browser/browser'; import { selectionBackground } from 'vs/platform/theme/common/colorRegistry'; +import { mainWindow } from 'vs/base/browser/window'; registerThemingParticipant((theme, collector) => { @@ -28,7 +29,7 @@ registerThemingParticipant((theme, collector) => { const titleBackground = theme.getColor(TITLE_BAR_ACTIVE_BACKGROUND); if (titleBackground) { const metaElementId = 'monaco-workbench-meta-theme-color'; - let metaElement = document.getElementById(metaElementId) as HTMLMetaElement | null; + let metaElement = mainWindow.document.getElementById(metaElementId) as HTMLMetaElement | null; if (!metaElement) { metaElement = createMetaElement(); metaElement.name = 'theme-color'; diff --git a/src/vs/workbench/browser/window.ts b/src/vs/workbench/browser/window.ts index eb0305eb86a..0293a819b2f 100644 --- a/src/vs/workbench/browser/window.ts +++ b/src/vs/workbench/browser/window.ts @@ -90,8 +90,8 @@ export class BrowserWindow extends Disposable { // when shutdown has happened to not show the dialog e.g. // when navigation takes a longer time. Event.toPromise(Event.any( - Event.once(new DomEmitter(document.body, EventType.KEY_DOWN, true).event), - Event.once(new DomEmitter(document.body, EventType.MOUSE_DOWN, true).event) + Event.once(new DomEmitter(mainWindow.document.body, EventType.KEY_DOWN, true).event), + Event.once(new DomEmitter(mainWindow.document.body, EventType.MOUSE_DOWN, true).event) )).then(async () => { // Delay the dialog in case the user interacted diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 56225a3e363..ef64702af52 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -330,10 +330,10 @@ export class Workbench extends Layout { ]); this.container.classList.add(...workbenchClasses); - document.body.classList.add(platformClass); // used by our fonts + mainWindow.document.body.classList.add(platformClass); // used by our fonts if (isWeb) { - document.body.classList.add('web'); + mainWindow.document.body.classList.add('web'); } // Apply font aliasing diff --git a/src/vs/workbench/contrib/codeEditor/electron-sandbox/inputClipboardActions.ts b/src/vs/workbench/contrib/codeEditor/electron-sandbox/inputClipboardActions.ts index 5eec3dce8a7..1877ea58966 100644 --- a/src/vs/workbench/contrib/codeEditor/electron-sandbox/inputClipboardActions.ts +++ b/src/vs/workbench/contrib/codeEditor/electron-sandbox/inputClipboardActions.ts @@ -6,6 +6,7 @@ import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import * as platform from 'vs/base/common/platform'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import { $window } from 'vs/base/browser/window'; if (platform.isMacintosh) { @@ -37,7 +38,7 @@ if (platform.isMacintosh) { function bindExecuteCommand(command: 'cut' | 'copy' | 'paste') { return () => { - document.execCommand(command); + $window.document.execCommand(command); }; } } diff --git a/src/vs/workbench/contrib/codeEditor/electron-sandbox/selectionClipboard.ts b/src/vs/workbench/contrib/codeEditor/electron-sandbox/selectionClipboard.ts index eadd523ded5..ba50a21294c 100644 --- a/src/vs/workbench/contrib/codeEditor/electron-sandbox/selectionClipboard.ts +++ b/src/vs/workbench/contrib/codeEditor/electron-sandbox/selectionClipboard.ts @@ -21,6 +21,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; +import { $window } from 'vs/base/browser/window'; export class SelectionClipboard extends Disposable implements IEditorContribution { private static readonly SELECTION_LENGTH_LIMIT = 65536; @@ -94,7 +95,7 @@ class SelectionClipboardPastePreventer implements IWorkbenchContribution { @IConfigurationService configurationService: IConfigurationService ) { if (platform.isLinux) { - document.addEventListener('mouseup', (e) => { + $window.document.addEventListener('mouseup', (e) => { if (e.button === 1) { // middle button const config = configurationService.getValue<{ selectionClipboard: boolean }>('editor'); diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 486cf8cbdc2..d42faed523e 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -1465,7 +1465,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { } private static getCompressedStatFromDragEvent(stat: ExplorerItem, dragEvent: DragEvent): ExplorerItem { - const target = document.elementFromPoint(dragEvent.clientX, dragEvent.clientY); + const target = DOM.getWindow(dragEvent).document.elementFromPoint(dragEvent.clientX, dragEvent.clientY); const iconLabelName = getIconLabelNameFromHTMLElement(target); if (iconLabelName) { diff --git a/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts b/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts index b2af996d57e..1160e6249a8 100644 --- a/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts +++ b/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts @@ -31,6 +31,7 @@ import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { Categories } from 'vs/platform/action/common/actionCommonCategories'; import { IAccessibilityInformation } from 'vs/platform/accessibility/common/accessibility'; +import { $window } from 'vs/base/browser/window'; class LanguageStatusViewModel { @@ -202,8 +203,8 @@ class EditorStatusContribution implements IWorkbenchContribution { // animate the status bar icon whenever language status changes, repeat animation // when severity is warning or error, don't show animation when showing progress/busy const userHasInteractedWithStatus = this._interactionCounter.value >= 3; - const node = document.querySelector('.monaco-workbench .statusbar DIV#status\\.languageStatus A>SPAN.codicon'); - const container = document.querySelector('.monaco-workbench .statusbar DIV#status\\.languageStatus'); + const node = $window.document.querySelector('.monaco-workbench .statusbar DIV#status\\.languageStatus A>SPAN.codicon'); + const container = $window.document.querySelector('.monaco-workbench .statusbar DIV#status\\.languageStatus'); if (node instanceof HTMLElement && container) { const _wiggle = 'wiggle'; const _flash = 'flash'; @@ -223,7 +224,7 @@ class EditorStatusContribution implements IWorkbenchContribution { // track when the hover shows (this is automagic and DOM mutation spying is needed...) // use that as signal that the user has interacted/learned language status items work if (!userHasInteractedWithStatus) { - const hoverTarget = document.querySelector('.monaco-workbench .context-view'); + const hoverTarget = $window.document.querySelector('.monaco-workbench .context-view'); if (hoverTarget instanceof HTMLElement) { const observer = new MutationObserver(() => { if (document.contains(element)) { diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/notebookClipboard.ts b/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/notebookClipboard.ts index a6ede9416aa..d112e828555 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/notebookClipboard.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/notebookClipboard.ts @@ -31,6 +31,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { showWindowLogActionId } from 'vs/workbench/services/log/common/logConstants'; import { getActiveElement, getWindow } from 'vs/base/browser/dom'; +import { $window } from 'vs/base/browser/window'; let _logging: boolean = false; function toggleLogging() { @@ -161,7 +162,7 @@ export function runCopyCells(accessor: ServicesAccessor, editor: INotebookEditor } if (editor.hasOutputTextSelection()) { - document.execCommand('copy'); + $window.document.execCommand('copy'); return true; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index fe504529b07..b4b0972c7f2 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -55,6 +55,7 @@ import { INotebookLoggingService } from 'vs/workbench/contrib/notebook/common/no import { IDisposable } from 'vs/base/common/lifecycle'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { WorkbenchActionExecutedClassification, WorkbenchActionExecutedEvent } from 'vs/base/common/actions'; +import { getWindow } from 'vs/base/browser/dom'; const LINE_COLUMN_REGEX = /:([\d]+)(?::([\d]+))?$/; const LineQueryRegex = /line=(\d+)$/; @@ -547,7 +548,7 @@ export class BackLayerWebView extends Themable { } private _initialize(content: string): Promise { - if (!document.body.contains(this.element)) { + if (!getWindow(this.element).document.body.contains(this.element)) { throw new Error('Element is already detached from the DOM tree'); } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index acdf0c25e45..802a46145f8 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -146,7 +146,7 @@ async function webviewPreloads(ctx: PreloadContext) { // check if an input element is focused within the output element const checkOutputInputFocus = () => { - const activeElement = document.activeElement; + const activeElement = $window.document.activeElement; if (!activeElement) { return; } @@ -258,8 +258,8 @@ async function webviewPreloads(ctx: PreloadContext) { } }; - document.body.addEventListener('click', handleInnerClick); - document.body.addEventListener('focusin', checkOutputInputFocus); + $window.document.body.addEventListener('click', handleInnerClick); + $window.document.body.addEventListener('focusin', checkOutputInputFocus); interface RendererContext extends rendererApi.RendererContext { readonly onDidChangeSettings: Event; @@ -360,7 +360,7 @@ async function webviewPreloads(ctx: PreloadContext) { constructor() { this._observer = new ResizeObserver(entries => { for (const entry of entries) { - if (!document.body.contains(entry.target)) { + if (!$window.document.body.contains(entry.target)) { continue; } @@ -492,10 +492,10 @@ async function webviewPreloads(ctx: PreloadContext) { }; function focusFirstFocusableOrContainerInOutput(cellOrOutputId: string, alternateId?: string) { - const cellOutputContainer = document.getElementById(cellOrOutputId) ?? - (alternateId ? document.getElementById(alternateId!) : undefined); + const cellOutputContainer = $window.document.getElementById(cellOrOutputId) ?? + (alternateId ? $window.document.getElementById(alternateId!) : undefined); if (cellOutputContainer) { - if (cellOutputContainer.contains(document.activeElement)) { + if (cellOutputContainer.contains($window.document.activeElement)) { return; } @@ -723,7 +723,7 @@ async function webviewPreloads(ctx: PreloadContext) { selectRange(_range); try { document.designMode = 'On'; - document.execCommand('removeFormat', false, undefined); + $window.document.execCommand('removeFormat', false, undefined); document.designMode = 'Off'; $window.getSelection()?.removeAllRanges(); } catch (e) { @@ -734,7 +734,7 @@ async function webviewPreloads(ctx: PreloadContext) { selectRange(_range); try { document.designMode = 'On'; - document.execCommand('removeFormat', false, undefined); + $window.document.execCommand('removeFormat', false, undefined); $window.document.execCommand('hiliteColor', false, color); document.designMode = 'Off'; $window.getSelection()?.removeAllRanges(); @@ -948,8 +948,8 @@ async function webviewPreloads(ctx: PreloadContext) { currentMatchIndex: number; } - const matchColor = $window.getComputedStyle(document.getElementById('_defaultColorPalatte')!).color; - const currentMatchColor = $window.getComputedStyle(document.getElementById('_defaultColorPalatte')!).backgroundColor; + const matchColor = $window.getComputedStyle($window.document.getElementById('_defaultColorPalatte')!).color; + const currentMatchColor = $window.getComputedStyle($window.document.getElementById('_defaultColorPalatte')!).backgroundColor; class JSHighlighter implements IHighlighter { private _activeHighlightInfo: Map; @@ -999,7 +999,7 @@ async function webviewPreloads(ctx: PreloadContext) { if (!!match && !!sel && match.highlightResult) { let offset = 0; try { - const outputOffset = document.getElementById(match.id)!.getBoundingClientRect().top; + const outputOffset = $window.document.getElementById(match.id)!.getBoundingClientRect().top; const tempRange = document.createRange(); tempRange.selectNode(match.highlightResult.range.startContainer); @@ -1015,7 +1015,7 @@ async function webviewPreloads(ctx: PreloadContext) { match.highlightResult?.update(currentMatchColor, match.isShadow ? undefined : 'current-find-match'); - document.getSelection()?.removeAllRanges(); + $window.document.getSelection()?.removeAllRanges(); postNotebookMessage('didFindHighlightCurrent', { offset }); @@ -1034,7 +1034,7 @@ async function webviewPreloads(ctx: PreloadContext) { } dispose() { - document.getSelection()?.removeAllRanges(); + $window.document.getSelection()?.removeAllRanges(); this._activeHighlightInfo.forEach(highlightInfo => { highlightInfo.matches.forEach(match => { match.highlightResult?.dispose(); @@ -1109,7 +1109,7 @@ async function webviewPreloads(ctx: PreloadContext) { if (match) { let offset = 0; try { - const outputOffset = document.getElementById(match.id)!.getBoundingClientRect().top; + const outputOffset = $window.document.getElementById(match.id)!.getBoundingClientRect().top; match.originalRange.startContainer.parentElement?.scrollIntoView({ behavior: 'auto', block: 'end', inline: 'nearest' }); const rangeOffset = match.originalRange.getBoundingClientRect().top; offset = rangeOffset - outputOffset; @@ -1138,7 +1138,7 @@ async function webviewPreloads(ctx: PreloadContext) { } dispose(): void { - document.getSelection()?.removeAllRanges(); + $window.document.getSelection()?.removeAllRanges(); this._currentMatchesHighlight.clear(); this._matchesHighlight.clear(); } @@ -1239,7 +1239,7 @@ async function webviewPreloads(ctx: PreloadContext) { const matches: IFindMatch[] = []; const range = document.createRange(); - range.selectNodeContents(document.getElementById('findStart')!); + range.selectNodeContents($window.document.getElementById('findStart')!); const sel = $window.getSelection(); sel?.removeAllRanges(); sel?.addRange(range); @@ -1347,7 +1347,7 @@ async function webviewPreloads(ctx: PreloadContext) { break; } - if (node.id === 'container' || node === document.body) { + if (node.id === 'container' || node === $window.document.body) { break; } } @@ -1363,7 +1363,7 @@ async function webviewPreloads(ctx: PreloadContext) { } _highlighter.addHighlights(matches, options.ownerID); - document.getSelection()?.removeAllRanges(); + $window.document.getSelection()?.removeAllRanges(); viewModel.toggleDragDropEnabled(currentOptions.dragAndDropEnabled); @@ -1381,7 +1381,7 @@ async function webviewPreloads(ctx: PreloadContext) { }; const copyOutputImage = async (outputId: string, altOutputId: string, retries = 5) => { - if (!document.hasFocus() && retries > 0) { + if (!$window.document.hasFocus() && retries > 0) { // copyImage can be called from outside of the webview, which means this function may be running whilst the webview is gaining focus. // Since navigator.clipboard.write requires the document to be focused, we need to wait for focus. // We cannot use a listener, as there is a high chance the focus is gained during the setup of the listener resulting in us missing it. @@ -1390,8 +1390,8 @@ async function webviewPreloads(ctx: PreloadContext) { } try { - const image = document.getElementById(outputId)?.querySelector('img') - ?? document.getElementById(altOutputId)?.querySelector('img'); + const image = $window.document.getElementById(outputId)?.querySelector('img') + ?? $window.document.getElementById(altOutputId)?.querySelector('img'); if (image) { await navigator.clipboard.write([new ClipboardItem({ 'image/png': new Promise((resolve) => { @@ -1492,7 +1492,7 @@ async function webviewPreloads(ctx: PreloadContext) { case 'clear': renderers.clearAll(); viewModel.clearAll(); - document.getElementById('container')!.innerText = ''; + $window.document.getElementById('container')!.innerText = ''; break; case 'clearOutput': { @@ -1544,10 +1544,10 @@ async function webviewPreloads(ctx: PreloadContext) { focusFirstFocusableOrContainerInOutput(event.data.cellOrOutputId, event.data.alternateId); break; case 'decorations': { - let outputContainer = document.getElementById(event.data.cellId); + let outputContainer = $window.document.getElementById(event.data.cellId); if (!outputContainer) { viewModel.ensureOutputCell(event.data.cellId, -100000, true); - outputContainer = document.getElementById(event.data.cellId); + outputContainer = $window.document.getElementById(event.data.cellId); } outputContainer?.classList.add(...event.data.addedClassNames); outputContainer?.classList.remove(...event.data.removedClassNames); @@ -1560,7 +1560,7 @@ async function webviewPreloads(ctx: PreloadContext) { renderers.getRenderer(event.data.rendererId)?.receiveMessage(event.data.message); break; case 'notebookStyles': { - const documentStyle = document.documentElement.style; + const documentStyle = $window.document.documentElement.style; for (let i = documentStyle.length - 1; i >= 0; i--) { const property = documentStyle[i]; @@ -1940,7 +1940,7 @@ async function webviewPreloads(ctx: PreloadContext) { public async render(item: ExtendedOutputItem, preferredRendererId: string | undefined, element: HTMLElement, signal: AbortSignal): Promise { const primaryRenderer = this.findRenderer(preferredRendererId, item); if (!primaryRenderer) { - const errorMessage = (document.documentElement.style.getPropertyValue('--notebook-cell-renderer-not-found-error') || '').replace('$0', () => item.mime); + const errorMessage = ($window.document.documentElement.style.getPropertyValue('--notebook-cell-renderer-not-found-error') || '').replace('$0', () => item.mime); this.showRenderError(item, element, errorMessage); return; } @@ -1972,7 +1972,7 @@ async function webviewPreloads(ctx: PreloadContext) { } // All renderers have failed and there is nothing left to fallback to - const errorMessage = (document.documentElement.style.getPropertyValue('--notebook-cell-renderer-fallbacks-exhausted') || '').replace('$0', () => item.mime); + const errorMessage = ($window.document.documentElement.style.getPropertyValue('--notebook-cell-renderer-fallbacks-exhausted') || '').replace('$0', () => item.mime); this.showRenderError(item, element, errorMessage); } @@ -2293,7 +2293,7 @@ async function webviewPreloads(ctx: PreloadContext) { }] }); - const root = document.getElementById('container')!; + const root = $window.document.getElementById('container')!; const markupCell = document.createElement('div'); markupCell.className = 'markup'; markupCell.style.position = 'absolute'; @@ -2461,7 +2461,7 @@ async function webviewPreloads(ctx: PreloadContext) { private readonly outputElements = new Map(); constructor(cellId: string) { - const container = document.getElementById('container')!; + const container = $window.document.getElementById('container')!; const upperWrapperElement = createFocusSink(cellId); container.appendChild(upperWrapperElement); @@ -2754,12 +2754,12 @@ async function webviewPreloads(ctx: PreloadContext) { private dragOverlay?: HTMLElement; constructor() { - document.addEventListener('dragover', e => { + $window.document.addEventListener('dragover', e => { // Allow dropping dragged markup cells e.preventDefault(); }); - document.addEventListener('drop', e => { + $window.document.addEventListener('drop', e => { e.preventDefault(); const drag = this.currentDrag; @@ -2798,7 +2798,7 @@ async function webviewPreloads(ctx: PreloadContext) { this.dragOverlay.style.width = '100%'; this.dragOverlay.style.height = '100%'; this.dragOverlay.style.background = 'transparent'; - document.body.appendChild(this.dragOverlay); + $window.document.body.appendChild(this.dragOverlay); } (e.target as HTMLElement).style.zIndex = `${overlayZIndex + 1}`; (e.target as HTMLElement).classList.add('dragging'); @@ -2840,7 +2840,7 @@ async function webviewPreloads(ctx: PreloadContext) { }); if (this.dragOverlay) { - document.body.removeChild(this.dragOverlay); + $window.document.body.removeChild(this.dragOverlay); this.dragOverlay = undefined; } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 9bcd33dd4a2..2962c8e38a5 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -65,6 +65,7 @@ import { defaultButtonStyles } from 'vs/platform/theme/browser/defaultStyles'; import { IProductService } from 'vs/platform/product/common/productService'; import { registerNavigableContainer } from 'vs/workbench/browser/actions/widgetNavigationCommands'; import { IEditorProgressService } from 'vs/platform/progress/common/progress'; +import { $window } from 'vs/base/browser/window'; export const enum SettingsFocusContext { @@ -1411,7 +1412,7 @@ export class SettingsEditor2 extends EditorPane { // If the context view is focused, delay rendering settings if (this.contextViewFocused()) { - const element = document.querySelector('.context-view'); + const element = $window.document.querySelector('.context-view'); if (element) { this.scheduleRefresh(element as HTMLElement, key); } diff --git a/src/vs/workbench/contrib/splash/browser/partsSplash.ts b/src/vs/workbench/contrib/splash/browser/partsSplash.ts index 1683602cde2..1dee95f26ec 100644 --- a/src/vs/workbench/contrib/splash/browser/partsSplash.ts +++ b/src/vs/workbench/contrib/splash/browser/partsSplash.ts @@ -96,15 +96,15 @@ export class PartsSplash { } private _removePartsSplash(): void { - const element = document.getElementById(PartsSplash._splashElementId); + const element = mainWindow.document.getElementById(PartsSplash._splashElementId); if (element) { element.style.display = 'none'; } // remove initial colors - const defaultStyles = document.head.getElementsByClassName('initialShellColors'); + const defaultStyles = mainWindow.document.head.getElementsByClassName('initialShellColors'); if (defaultStyles.length) { - document.head.removeChild(defaultStyles[0]); + mainWindow.document.head.removeChild(defaultStyles[0]); } } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index f5ea4fd4228..4686df0178b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -55,6 +55,7 @@ import { mark } from 'vs/base/common/performance'; import { DeatachedTerminal } from 'vs/workbench/contrib/terminal/browser/detachedTerminal'; import { ITerminalCapabilityImplMap, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { createInstanceCapabilityEventMultiplexer } from 'vs/workbench/contrib/terminal/browser/terminalEvents'; +import { mainWindow } from 'vs/base/browser/window'; export class TerminalService extends Disposable implements ITerminalService { declare _serviceBrand: undefined; @@ -228,7 +229,7 @@ export class TerminalService extends Disposable implements ITerminalService { this.initializePrimaryBackend(); // Create async as the class depends on `this` - timeout(0).then(() => this._register(this._instantiationService.createInstance(TerminalEditorStyle, document.head))); + timeout(0).then(() => this._register(this._instantiationService.createInstance(TerminalEditorStyle, mainWindow.document.head))); } async showProfileQuickPick(type: 'setDefault' | 'createInstance', cwd?: string | URI): Promise { diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index fb7572a512a..34bc9a58488 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -646,9 +646,9 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach e.clipboardData.setData('text/html', textAsHtml); e.preventDefault(); } - document.addEventListener('copy', listener); - document.execCommand('copy'); - document.removeEventListener('copy', listener); + $window.document.addEventListener('copy', listener); + $window.document.execCommand('copy'); + $window.document.removeEventListener('copy', listener); } else { await this._clipboardService.writeText(this.raw.getSelection()); } diff --git a/src/vs/workbench/contrib/terminal/test/browser/terminalConfigHelper.test.ts b/src/vs/workbench/contrib/terminal/test/browser/terminalConfigHelper.test.ts index 8764db8e257..7df51a71941 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/terminalConfigHelper.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/terminalConfigHelper.test.ts @@ -10,6 +10,7 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import { LinuxDistro } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { DisposableStore } from 'vs/base/common/lifecycle'; +import { mainWindow } from 'vs/base/browser/window'; class TestTerminalConfigHelper extends TerminalConfigHelper { set linuxDistro(distro: LinuxDistro) { @@ -28,7 +29,7 @@ suite('Workbench - TerminalConfigHelper', function () { setup(() => { store = new DisposableStore(); - fixture = document.body; + fixture = mainWindow.document.body; }); teardown(() => store.dispose()); diff --git a/src/vs/workbench/contrib/webview/browser/webview.contribution.ts b/src/vs/workbench/contrib/webview/browser/webview.contribution.ts index 0f13a054471..95db9a4365a 100644 --- a/src/vs/workbench/contrib/webview/browser/webview.contribution.ts +++ b/src/vs/workbench/contrib/webview/browser/webview.contribution.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { $window } from 'vs/base/browser/window'; import { MultiCommand, RedoCommand, SelectAllCommand, UndoCommand } from 'vs/editor/browser/editorExtensions'; import { CopyAction, CutAction, PasteAction } from 'vs/editor/contrib/clipboard/browser/clipboard'; import * as nls from 'vs/nls'; @@ -26,7 +27,7 @@ function overrideCommandForWebview(command: MultiCommand | undefined, f: (webvie // When focused in a custom menu try to fallback to the active webview // This is needed for context menu actions and the menubar - if (document.activeElement?.classList.contains('action-menu-item')) { + if ($window.document.activeElement?.classList.contains('action-menu-item')) { const editorService = accessor.get(IEditorService); if (editorService.activeEditor instanceof WebviewInput) { f(editorService.activeEditor.webview); diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index bd319b67288..b442277e920 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -103,7 +103,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD if (!this._focused) { return false; } - if (document.activeElement && document.activeElement !== this.element) { + if ($window.document.activeElement && $window.document.activeElement !== this.element) { // looks like https://github.com/microsoft/vscode/issues/132641 // where the focus is actually not in the `